diff --git a/src/app/core/configurable-enum/basic-autocomplete/basic-autocomplete.component.html b/src/app/core/configurable-enum/basic-autocomplete/basic-autocomplete.component.html index a3ca639273..95d1138694 100644 --- a/src/app/core/configurable-enum/basic-autocomplete/basic-autocomplete.component.html +++ b/src/app/core/configurable-enum/basic-autocomplete/basic-autocomplete.component.html @@ -1,7 +1,6 @@ implements OnChanges { @ContentChild(TemplateRef) templateRef: TemplateRef; - @ViewChild("inputElement") inputElement: ElementRef; + // `_elementRef` is protected in `MapInput` + @ViewChild(MatInput, { static: true }) inputElement: MatInput & { + _elementRef: ElementRef; + }; @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; @Input() valueMapper = (option: O) => option as unknown as V; @@ -280,7 +283,7 @@ export class BasicAutocompleteComponent onContainerClick(event: MouseEvent) { if ((event.target as Element).tagName.toLowerCase() != "input") { - this.inputElement.nativeElement.focus(); + this.inputElement.focus(); } } diff --git a/src/app/core/configurable-enum/basic-autocomplete/custom-form-control.directive.ts b/src/app/core/configurable-enum/basic-autocomplete/custom-form-control.directive.ts index c986873d5d..d51de1104a 100644 --- a/src/app/core/configurable-enum/basic-autocomplete/custom-form-control.directive.ts +++ b/src/app/core/configurable-enum/basic-autocomplete/custom-form-control.directive.ts @@ -30,6 +30,7 @@ export abstract class CustomFormControlDirective @Input() placeholder: string; @Input() required = false; + abstract inputElement: { _elementRef: ElementRef }; stateChanges = new Subject(); focused = false; touched = false; @@ -98,10 +99,10 @@ export abstract class CustomFormControlDirective } setDescribedByIds(ids: string[]) { - const controlElement = this.elementRef.nativeElement.querySelector( - ".autocomplete-input" - )!; - controlElement.setAttribute("aria-describedby", ids.join(" ")); + this.inputElement._elementRef.nativeElement.setAttribute( + "aria-describedby", + ids.join(" ") + ); } abstract onContainerClick(event: MouseEvent); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.html b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.html new file mode 100644 index 0000000000..7efa691323 --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.html @@ -0,0 +1,5 @@ +{{ placeholder }} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.scss b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.scss new file mode 100644 index 0000000000..c77000384e --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.scss @@ -0,0 +1,3 @@ +app-boolean-input label { + font-size: initial +} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.spec.ts new file mode 100644 index 0000000000..55b616e6a3 --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BooleanInputComponent } from './boolean-input.component'; + +describe('BooleanInputComponent', () => { + let component: BooleanInputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ BooleanInputComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BooleanInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.ts new file mode 100644 index 0000000000..8cb9c02344 --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/boolean-input/boolean-input.component.ts @@ -0,0 +1,55 @@ +import { + Component, + ElementRef, + Optional, + Self, + ViewChild, + ViewEncapsulation, +} from "@angular/core"; +import { CustomFormControlDirective } from "../../../../../configurable-enum/basic-autocomplete/custom-form-control.directive"; +import { MatCheckbox, MatCheckboxModule } from "@angular/material/checkbox"; +import { + FormGroupDirective, + FormsModule, + NgControl, + NgForm, +} from "@angular/forms"; +import { MatFormFieldControl } from "@angular/material/form-field"; +import { ErrorStateMatcher } from "@angular/material/core"; + +@Component({ + selector: "app-boolean-input", + standalone: true, + imports: [MatCheckboxModule, FormsModule], + providers: [ + { provide: MatFormFieldControl, useExisting: BooleanInputComponent }, + ], + templateUrl: "./boolean-input.component.html", + styleUrls: ["./boolean-input.component.scss"], + encapsulation: ViewEncapsulation.None, +}) +export class BooleanInputComponent extends CustomFormControlDirective { + @ViewChild(MatCheckbox, { static: true }) inputElement: MatCheckbox; + + constructor( + elementRef: ElementRef, + errorStateMatcher: ErrorStateMatcher, + @Optional() @Self() ngControl: NgControl, + @Optional() parentForm: NgForm, + @Optional() parentFormGroup: FormGroupDirective + ) { + super( + elementRef, + errorStateMatcher, + ngControl, + parentForm, + parentFormGroup + ); + } + + onContainerClick(event: MouseEvent) { + if ((event.target as Element).tagName.toLowerCase() != "mat-checkbox") { + this.inputElement.focus(); + } + } +} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.html b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.html index 2daaf9764c..cc73548ecf 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.html +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.html @@ -1,3 +1,3 @@ -
- {{ label }} -
+ + + diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.scss b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.scss new file mode 100644 index 0000000000..832502a736 --- /dev/null +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.scss @@ -0,0 +1,4 @@ +app-edit-boolean .mat-mdc-form-field-infix { + padding-top: 12px !important; + padding-bottom: 0 !important; +} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.ts index fd035d3639..6e7104f2e2 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-boolean/edit-boolean.component.ts @@ -1,14 +1,17 @@ -import { Component } from "@angular/core"; +import { Component, ViewEncapsulation } from "@angular/core"; import { EditComponent } from "../edit-component"; import { DynamicComponent } from "../../../../view/dynamic-components/dynamic-component.decorator"; import { ReactiveFormsModule } from "@angular/forms"; -import { MatCheckboxModule } from "@angular/material/checkbox"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { BooleanInputComponent } from "./boolean-input/boolean-input.component"; @DynamicComponent("EditBoolean") @Component({ selector: "app-edit-boolean", templateUrl: "./edit-boolean.component.html", - imports: [ReactiveFormsModule, MatCheckboxModule], + styleUrls: ["./edit-boolean.component.scss"], + imports: [ReactiveFormsModule, MatFormFieldModule, BooleanInputComponent], standalone: true, + encapsulation: ViewEncapsulation.None, }) export class EditBooleanComponent extends EditComponent {} diff --git a/src/app/core/ui/search/search.service.spec.ts b/src/app/core/ui/search/search.service.spec.ts index a41dc1f81a..a07e8143bd 100644 --- a/src/app/core/ui/search/search.service.spec.ts +++ b/src/app/core/ui/search/search.service.spec.ts @@ -9,12 +9,18 @@ import { Database } from "../../database/database"; describe("SearchService", () => { let service: SearchService; + const childToStringBefore = Child.toStringAttributes; + const csrToStringBefore = ChildSchoolRelation.toStringAttributes; beforeEach(() => { TestBed.configureTestingModule({ imports: [DatabaseTestingModule] }); }); - afterEach(() => TestBed.inject(Database).destroy()); + afterEach(() => { + Child.toStringAttributes = childToStringBefore; + ChildSchoolRelation.toStringAttributes = csrToStringBefore; + return TestBed.inject(Database).destroy(); + }); it("should allow to search for toStringAttributes that are not the entityId", async () => { ChildSchoolRelation.toStringAttributes = ["entityId"]; diff --git a/src/styles/resets/_mat-input.scss b/src/styles/resets/_mat-input.scss index dc44571d60..137bc3b14b 100644 --- a/src/styles/resets/_mat-input.scss +++ b/src/styles/resets/_mat-input.scss @@ -1,11 +1,7 @@ @use "@angular/material" as mat; /* display disabled form values in black for better readability as we disable forms by default */ -.mat-mdc-input-element:disabled { - color: mat.get-color-from-palette(mat.$light-theme-foreground-palette, text) !important; -} - -.mat-mdc-select-disabled .mat-mdc-select-value { +.mat-mdc-input-element:disabled, .mat-mdc-select-disabled .mat-mdc-select-value, .mat-mdc-checkbox-disabled label { color: mat.get-color-from-palette(mat.$light-theme-foreground-palette, text) !important; }