diff --git a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts b/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts index 34203d73e2..2a096c5f8f 100644 --- a/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts +++ b/src/app/core/common-components/entity-subrecord/entity-subrecord/entity-subrecord.component.ts @@ -55,6 +55,7 @@ import { MatCheckboxModule, } from "@angular/material/checkbox"; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; +import { applyUpdate } from "../../../entity/model/entity-update"; export interface TableRow { record: T; @@ -349,19 +350,12 @@ export class EntitySubrecordComponent implements OnChanges { this.updateSubscription = this.entityMapper .receiveUpdates(this.getEntityConstructor()) .pipe(untilDestroyed(this)) - .subscribe(({ entity, type }) => { - if (type === "new") { - this.addToTable(entity); - } else if (type === "remove") { - this.removeFromDataTable(entity); - } else if ( - type === "update" && - !this.records.find((rec) => rec.getId() === entity.getId()) - ) { - this.addToTable(entity); - } + .subscribe((next) => { + this.records = applyUpdate(this.records, next, true); - if (!this.predicate(entity)) { + if (this.predicate(next.entity)) { + this.initDataSource(); + } else { // hide after a short delay to give a signal in the UI why records disappear by showing the changed values first setTimeout(() => this.initDataSource(), 5000); } @@ -410,20 +404,6 @@ export class EntitySubrecordComponent implements OnChanges { row.formGroup = null; } - private removeFromDataTable(deleted: T) { - // use setter so datasource is also updated - this.records = this.records.filter( - (rec) => rec.getId() !== deleted.getId(), - ); - this.initDataSource(); - } - - private addToTable(record: T) { - // use setter so datasource is also updated - this.records = [record].concat(this.records); - this.initDataSource(); - } - /** * Create a new entity. * The entity is only written to the database when the user saves this record which is newly added in edit mode. diff --git a/src/app/core/entity/model/entity-update.ts b/src/app/core/entity/model/entity-update.ts index a3f9ec6c97..551548f666 100644 --- a/src/app/core/entity/model/entity-update.ts +++ b/src/app/core/entity/model/entity-update.ts @@ -28,23 +28,34 @@ export interface UpdatedEntity { * @param next An entity that should be updated as well as the type of update. This, as well as the entity * may be undefined or null. In this event, the entities-array is returned as is. * @param entities The entities to update, must be defined + * @param addIfMissing (Optional) whether to add an entity that comes through an update event but is not part of the array yet (default is to ignore) * @return An array of the given entities with the update applied */ export function applyUpdate( entities: T[], next: UpdatedEntity, + addIfMissing: boolean = false, ): T[] { if (!next || !next.entity || !entities) { return entities; } - switch (next.type) { - case "new": - return [next.entity].concat(entities); - case "update": - return entities.map((e) => - e.getId() === next.entity.getId() ? next.entity : e, - ); - case "remove": - return entities.filter((e) => e.getId() !== next.entity.getId()); + + if ( + next.type === "new" || + (addIfMissing && + next.type === "update" && + !entities.find((e) => e.getId() === next.entity.getId())) + ) { + return [next.entity].concat(entities); + } + + if (next.type === "update") { + return entities.map((e) => + e.getId() === next.entity.getId() ? next.entity : e, + ); + } + + if (next.type === "remove") { + return entities.filter((e) => e.getId() !== next.entity.getId()); } }