diff --git a/src/app/child-dev-project/schools/model/school.ts b/src/app/child-dev-project/schools/model/school.ts index 14c985f6b8..c17961f7ed 100644 --- a/src/app/child-dev-project/schools/model/school.ts +++ b/src/app/child-dev-project/schools/model/school.ts @@ -8,6 +8,12 @@ export class School extends Entity { return "SchoolBlock"; } + static create(params: Partial): School { + const school = new School(); + Object.assign(school, params); + return school; + } + @DatabaseField({ label: $localize`:Label for the name of a school:Name`, required: true, diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html index e18b7d83e7..d8bff1c611 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.html @@ -1,19 +1,22 @@ - + {{ label }} - + + +
+ + +
diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.scss b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.scss index e69de29bb2..6b61d442d7 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.scss +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.scss @@ -0,0 +1,5 @@ +.block-wrapper { + padding: 12px; + border-radius: 5px; + border: 1px solid lightgray; +} diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts index a1ccfdcae5..bb4134a4b5 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.spec.ts @@ -70,10 +70,8 @@ describe("EditSingleEntityComponent", () => { })); it("should show name of the selected entity", fakeAsync(() => { - const child1 = new Child(); - child1.name = "First Child"; - const child2 = new Child(); - child2.name = "Second Child"; + const child1 = Child.create("First Child"); + const child2 = Child.create("Second Child"); component.formControl.setValue(child1.getId()); mockEntityMapper.loadType.and.resolveTo([child1, child2]); @@ -86,4 +84,31 @@ describe("EditSingleEntityComponent", () => { expect(component.entityNameFormControl.value).toEqual("First Child"); })); + + it("Should have the correct entity selected when it's name is entered", () => { + const child1 = Child.create("First Child"); + const child2 = Child.create("Second Child"); + component.entities = [child1, child2]; + component.select("First Child"); + expect(component.selectedEntity).toBe(child1); + expect(component.formControl.value).toEqual(child1.getId()); + expect(component.editingSelectedEntity).toBeFalse(); + }); + + it("Should edit the selected entity", fakeAsync(() => { + const input: HTMLInputElement = fixture.elementRef.nativeElement.querySelector( + "input" + ); + const inputSpy = spyOn(input, "focus"); + component.entities = [School.create({ name: "High School" })]; + component.select("High School"); + expect(inputSpy).not.toHaveBeenCalled(); + component.editSelectedEntity(); + tick(); + expect(component.selectedEntity).toBeUndefined(); + expect(component.editingSelectedEntity).toBeTrue(); + expect(component.formControl.value).toBeNull(); + + expect(inputSpy).toHaveBeenCalled(); + })); }); diff --git a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts index 8fe64288b1..51643e0e4e 100644 --- a/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts +++ b/src/app/core/entity-components/entity-utils/dynamic-form-components/edit-single-entity/edit-single-entity.component.ts @@ -1,42 +1,52 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, ElementRef, ViewChild } from "@angular/core"; import { EditComponent, EditPropertyConfig } from "../edit-component"; import { ENTITY_MAP } from "../../../entity-details/entity-details.component"; import { EntityMapperService } from "../../../../entity/entity-mapper.service"; import { Entity } from "../../../../entity/model/entity"; import { Observable } from "rxjs"; -import { map } from "rxjs/operators"; +import { filter, map } from "rxjs/operators"; +import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { FormControl } from "@angular/forms"; +@UntilDestroy() @Component({ selector: "app-edit-single-entity", templateUrl: "./edit-single-entity.component.html", styleUrls: ["./edit-single-entity.component.scss"], }) -export class EditSingleEntityComponent - extends EditComponent - implements OnInit { +export class EditSingleEntityComponent extends EditComponent { entities: Entity[] = []; placeholder: string; filteredEntities: Observable; - entityNameFormControl: FormControl; + selectedEntity?: Entity; + editingSelectedEntity: boolean = false; + entityNameFormControl = new FormControl(); + + @ViewChild("inputElement") input: ElementRef; constructor(private entityMapper: EntityMapperService) { super(); - this.entityNameFormControl = new FormControl(); - } - filter(searchText: string): Entity[] { - return this.entities.filter((entity) => - entity.toString().toLowerCase().includes(searchText) - ); - } - ngOnInit() { this.filteredEntities = this.entityNameFormControl.valueChanges.pipe( + untilDestroyed(this), + filter((s) => s !== null), map((searchText?: string) => this.filter(searchText)) ); } + + private filter(searchText?: string): Entity[] { + if (!searchText) { + return this.entities; + } else { + const filterValue = searchText.toLowerCase(); + return this.entities.filter((entity) => + entity.toString().toLowerCase().includes(filterValue) + ); + } + } + async onInitFromDynamicConfig(config: EditPropertyConfig) { super.onInitFromDynamicConfig(config); - this.placeholder = $localize`:Placeholder for input to add entities|context Add User(s):Add ${this.label}`; + this.placeholder = $localize`:Placeholder for input to set an entity|context Select User:Select ${this.label}`; const entityType: string = config.formFieldConfig.additional || config.propertySchema.additional; const entityConstructor = ENTITY_MAP.get(entityType); @@ -52,7 +62,31 @@ export class EditSingleEntityComponent (entity) => entity.getId() === this.formControl.value ); if (selectedEntity) { + this.selectedEntity = selectedEntity; + this.editingSelectedEntity = false; this.entityNameFormControl.setValue(selectedEntity.toString()); + } else { + this.entityNameFormControl.setValue(""); } } + + select(entityName: string) { + const entity = this.entities.find( + (e) => e.toString().toLowerCase() === entityName.toLowerCase() + ); + if (entity) { + this.selectedEntity = entity; + this.editingSelectedEntity = false; + this.formControl.setValue(entity.getId()); + } + } + + editSelectedEntity() { + this.editingSelectedEntity = true; + this.selectedEntity = undefined; + this.formControl.setValue(null); + setTimeout(() => { + this.input.nativeElement.focus(); + }); + } } diff --git a/src/app/core/entity-components/entity-utils/entity-utils.module.ts b/src/app/core/entity-components/entity-utils/entity-utils.module.ts index b4a0a9c4b9..2797efa561 100644 --- a/src/app/core/entity-components/entity-utils/entity-utils.module.ts +++ b/src/app/core/entity-components/entity-utils/entity-utils.module.ts @@ -33,6 +33,7 @@ import { MatChipsModule } from "@angular/material/chips"; import { EditNumberComponent } from "./dynamic-form-components/edit-number/edit-number.component"; import { EntityFunctionPipe } from "./view-components/readonly-function/entity-function.pipe"; import { FlexLayoutModule } from "@angular/flex-layout"; +import { MatButtonModule } from "@angular/material/button"; @NgModule({ declarations: [ @@ -72,6 +73,7 @@ import { FlexLayoutModule } from "@angular/flex-layout"; MatAutocompleteModule, MatChipsModule, FlexLayoutModule, + MatButtonModule, ], entryComponents: [ EditTextComponent,