From b849b05088161d7a6ca807c8d5b60da1f15dda5c Mon Sep 17 00:00:00 2001 From: sander boer Date: Mon, 3 Mar 2025 17:24:53 +0100 Subject: [PATCH] feat: merged location form with the case detail edit form (#2808) combined two forms into a single one Solves PZ-4900 --- .../form/form/form.component.ts | 7 +- .../model/zaak-edit-met-reden-gegevens.ts | 13 -- .../zaak-details-wijzigen.component.html | 18 +- .../zaak-details-wijzigen.component.ts | 192 +++++++++++------- .../zaken/zaak-view/zaak-view.component.html | 30 +-- .../zaken/zaak-view/zaak-view.component.less | 66 ------ .../zaken/zaak-view/zaak-view.component.ts | 21 -- src/main/app/src/app/zaken/zaken.service.ts | 37 ++-- .../locatie-zoek/locatie-zoek.component.html | 20 +- .../locatie-zoek/locatie-zoek.component.less | 6 +- .../locatie-zoek/locatie-zoek.component.ts | 46 +++-- 11 files changed, 191 insertions(+), 265 deletions(-) delete mode 100644 src/main/app/src/app/zaken/model/zaak-edit-met-reden-gegevens.ts diff --git a/src/main/app/src/app/shared/material-form-builder/form/form/form.component.ts b/src/main/app/src/app/shared/material-form-builder/form/form/form.component.ts index 97265894db..6087af494a 100644 --- a/src/main/app/src/app/shared/material-form-builder/form/form/form.component.ts +++ b/src/main/app/src/app/shared/material-form-builder/form/form/form.component.ts @@ -33,9 +33,8 @@ export class FormComponent { } } - @Output() formSubmit: EventEmitter = new EventEmitter(); - @Output() formPartial: EventEmitter = - new EventEmitter(); + @Output() formSubmit = new EventEmitter(); + @Output() formPartial = new EventEmitter(); data: Array; formGroup: FormGroup; @@ -45,8 +44,6 @@ export class FormComponent { private _config: FormConfig; - constructor() {} - refreshFormfields(formFields: Array): void { this.data = formFields; diff --git a/src/main/app/src/app/zaken/model/zaak-edit-met-reden-gegevens.ts b/src/main/app/src/app/zaken/model/zaak-edit-met-reden-gegevens.ts deleted file mode 100644 index 4929b448e8..0000000000 --- a/src/main/app/src/app/zaken/model/zaak-edit-met-reden-gegevens.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Atos - * SPDX-License-Identifier: EUPL-1.2+ - */ - -import { Zaak } from "./zaak"; - -export class ZaakEditMetRedenGegevens { - constructor( - public zaak: Zaak, - public reden: string, - ) {} -} diff --git a/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.html b/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.html index 2204ac63ad..e5e8c24789 100644 --- a/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.html +++ b/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.html @@ -8,34 +8,40 @@

edit {{ "actie.zaak.wijzigen" | translate }}

-
- + topic {{ "gegevens.algemeen" | translate }}
- + place {{ "locatie" | translate }} -
Location Content - Todo
+
diff --git a/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.ts b/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.ts index 5fbd2f9bc1..367e211caf 100644 --- a/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.ts +++ b/src/main/app/src/app/zaken/zaak-details-wijzigen/zaak-details-wijzigen.component.ts @@ -32,6 +32,7 @@ import { FormConfig } from "src/app/shared/material-form-builder/model/form-conf import { FormConfigBuilder } from "src/app/shared/material-form-builder/model/form-config-builder"; import { OrderUtil } from "src/app/shared/order/order-util"; import { GeneratedType } from "src/app/shared/utils/generated-types"; +import { Geometry } from "../model/geometry"; import { Zaak } from "../model/zaak"; import { ZakenService } from "../zaken.service"; @@ -58,16 +59,15 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit { private vertrouwelijkheidaanduidingenList: { label: string; value: string }[]; private omschrijving: TextareaFormField; private toelichtingField: TextareaFormField; - private reasonField: TextareaFormField; + reasonField: TextareaFormField; private ngDestroy = new Subject(); + private initialZaakGeometry: Geometry; constructor( private zakenService: ZakenService, private referentieTabelService: ReferentieTabelService, private utilService: UtilService, - ) {} - - ngOnInit() { + ) { this.formConfig = new FormConfigBuilder() .saveText("actie.opslaan") .cancelText("actie.annuleren") @@ -83,6 +83,22 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit { Vertrouwelijkheidaanduiding, ); + this.reasonField = new InputFormFieldBuilder() + .id("reason") + .label("reden") + .maxlength(80) + .validators(Validators.required) + .build(); + + // Forcing the set value to sync tabs + this.reasonField.formControl.valueChanges.subscribe((value) => { + this.reasonField.formControl.setValue(value, { emitEvent: false }); + }); + } + + ngOnInit() { + this.initialZaakGeometry = this.zaak.zaakgeometrie; + this.medewerkerGroepFormField = this.getMedewerkerGroupFormField( !this.zaak.isOpen || !this.zaak.rechten.toekennen, this.zaak?.groep.id, @@ -99,7 +115,6 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit { .validators(Validators.required) .build(); - // this.startDatumField = this.createDateFormField( "startdatum", this.zaak.startdatum, @@ -159,14 +174,6 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit { .disabled(!this.zaak.rechten.wijzigen) .build(); - this.reasonField = new InputFormFieldBuilder() - .id("reason") - .label("reden") - .maxlength(80) - .disabled() - .validators(Validators.required) - .build(); - this.formFields = [ [this.medewerkerGroepFormField, this.communicatiekanaalField], [ @@ -306,78 +313,117 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit { return null; } - onFormSubmit(formGroup: FormGroup): void { - const changedValues: Partial< - GeneratedType<"RestZaak"> & { - assignment: { - groep: GeneratedType<"RestGroup">; - medewerker: GeneratedType<"RestUser">; - }; - reason: string; - } - > = {}; - for (const [key, control] of Object.entries(formGroup.controls)) { - if (control.dirty) { - changedValues[key] = control.value; - } - } - const { reason, assignment, ...patchFields } = changedValues; - const subscriptions: Subscription[] = []; + saveFromFormView(formGroup: FormGroup): void { + const updates = Object.entries(formGroup.controls).reduce( + (acc, [key, control]) => { + const value = control.value; + acc[key] = key === "vertrouwelijkheidaanduiding" ? value.value : value; + return acc; + }, + {}, + ); - if (assignment) { - this.zaak = { - ...this.zaak, - groep: assignment.groep, - behandelaar: assignment.medewerker, - }; + void this.updateZaak(this.createZaakPatch(updates)); + } - if (this.zaak.behandelaar?.id === this.loggedInUser.id) { - subscriptions.push( - this.zakenService - .toekennenAanIngelogdeMedewerker(this.zaak, reason) - .subscribe((zaak) => { - this.utilService.openSnackbar("msg.zaak.toegekend", { - behandelaar: zaak.behandelaar?.naam, - }); - }), - ); - } else { - subscriptions.push( - this.zakenService.toekennen(this.zaak, reason).subscribe((zaak) => { - if (zaak?.behandelaar?.id) { - this.utilService.openSnackbar("msg.zaak.toegekend", { - behandelaar: zaak.behandelaar.naam, - }); - } else { - this.utilService.openSnackbar("msg.vrijgegeven.zaak"); - } - }), - ); - } - } + saveFromMapView() { + const updates = this.formFields.reduce((acc, fields) => { + fields.forEach((field) => { + const value = field.formControl.value; + acc[field.id] = + field.id === "vertrouwelijkheidaanduiding" ? value.value : value; + }); + return acc; + }, {}); - if (patchFields) { - const zaak = new Zaak(); + void this.updateZaak(this.createZaakPatch(updates)); + } - Object.keys(patchFields).forEach((key) => { - // circumvent the TypeScript type check (pattern copied from zaak-view.component.ts) - zaak[key] = patchFields[key].value; - patchFields[key].value; - patchFields[key]; - }); + locationChanged(update: Geometry) { + this.zaak.zaakgeometrie = update; + } + + private createZaakPatch(update: Record) { + const { assignment, reason, ...updates } = update; + + return { + ...updates, + groep: assignment.groep, + behandelaar: assignment.medewerker, + } satisfies Partial; + } + private async updateZaak(zaak: Partial) { + const reason = this.reasonField.formControl.value; + const subscriptions: Subscription[] = []; + + subscriptions.push(this.patchBehandelaar(zaak, reason)); + + this.patchLocation(reason).subscribe(() => { + // To prevent a race condition we need to first update the `zaakgeometrie` and then the other fields subscriptions.push( this.zakenService - .updateZaak(this.zaak.uuid, zaak, reason) + .updateZaak(this.zaak.uuid, { zaak, reden: reason }) .subscribe(() => {}), ); - } - if (subscriptions.length > 0) { - forkJoin([subscriptions]).subscribe(async () => { - await this.sideNav.close(); + forkJoin([subscriptions]).subscribe(() => this.sideNav.close()); + }); + } + + private patchLocation(reason?: string) { + if ( + JSON.stringify(this.zaak.zaakgeometrie) === + JSON.stringify(this.initialZaakGeometry) + ) { + return new Observable((observer) => { + observer.next(null); + observer.complete(); }); } + + return this.zakenService.updateZaakLocatie( + this.zaak.uuid, + this.zaak.zaakgeometrie, + reason, + ); + } + + private patchBehandelaar(zaak: Partial, reason?: string) { + if (zaak.behandelaar?.id === this.zaak.behandelaar?.id) { + return; + } + + if (zaak.behandelaar?.id === this.loggedInUser.id) { + return this.zakenService + .toekennenAanIngelogdeMedewerker(this.zaak.uuid, reason) + .subscribe((updatedZaak) => { + this.utilService.openSnackbar("msg.zaak.toegekend", { + behandelaar: updatedZaak.behandelaar?.naam, + }); + }); + } + + return this.zakenService + .toekennen(this.zaak.uuid, { + reason, + groupId: zaak.groep?.id, + behandelaarId: zaak?.behandelaar?.id, + }) + .subscribe((updatedZaak) => { + if (updatedZaak.behandelaar?.id) { + this.utilService.openSnackbar("msg.zaak.toegekend", { + behandelaar: updatedZaak.behandelaar?.naam, + }); + } else { + this.utilService.openSnackbar("msg.vrijgegeven.zaak"); + } + }); + } + + exit() { + this.zaak.zaakgeometrie = this.initialZaakGeometry; + void this.sideNav.close(); } private getMedewerkerGroupFormField( diff --git a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.html b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.html index e3c035ce63..afc98f0d16 100644 --- a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.html +++ b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.html @@ -53,13 +53,6 @@ [sideNav]="actionsSidenav" (bagObject)="adresGeselecteerd($event)" > - -
- -
- {{ zaak.zaakgeometrie | location | empty }} -
- place -
-
-
+
diff --git a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.less b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.less index d74ea15fa1..2d698595d5 100644 --- a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.less +++ b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.less @@ -65,72 +65,6 @@ mat-slide-toggle { left: 12px; } -.location-text { - margin: 5px; - - .static-text-label { - font-size: small; - font-weight: 500; - - .mat-icon { - font-size: 14px; - height: 14px; - width: 14px; - margin-left: 10px; - vertical-align: text-bottom; - } - } - - .static-text-content { - min-height: 20px; - font-size: 14px; - margin-top: 5px; - display: flex; - justify-content: space-between; - - .edit-icon { - display: none; - background-color: @box-shadow-color-light; - - .mat-icon { - font-size: 20px; - width: 20px; - height: 20px; - } - } - } - - &:hover { - .static-text-content { - cursor: pointer; - box-shadow: 0 0 0 1px @box-shadow-color-light; - - .edit-icon { - display: flex; - } - } - } - - &.readonly { - .static-text-label { - .mat-icon { - display: none; - } - } - - .static-text-content { - &.nopanel { - cursor: default; - box-shadow: none; - - .edit-icon { - display: none; - } - } - } - } -} - .flex-item { flex: 0 1 calc(33% - 5px); box-sizing: border-box; diff --git a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.ts b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.ts index bbcb787778..5f4e8b6aaf 100644 --- a/src/main/app/src/app/zaken/zaak-view/zaak-view.component.ts +++ b/src/main/app/src/app/zaken/zaak-view/zaak-view.component.ts @@ -63,7 +63,6 @@ import { Taak } from "../../taken/model/taak"; import { TaakStatus } from "../../taken/model/taak-status.enum"; import { TakenService } from "../../taken/taken.service"; import { IntakeAfrondenDialogComponent } from "../intake-afronden-dialog/intake-afronden-dialog.component"; -import { GeometryGegevens } from "../model/geometry-gegevens"; import { Zaak } from "../model/zaak"; import { ZaakBetrokkene } from "../model/zaak-betrokkene"; import { ZaakAfhandelenDialogComponent } from "../zaak-afhandelen-dialog/zaak-afhandelen-dialog.component"; @@ -954,16 +953,6 @@ export class ZaakViewComponent }); } - showOrEditZaakLocatie(): void { - if ( - (this.zaak.isOpen && this.zaak.rechten.wijzigen) || - this.zaak.zaakgeometrie != null - ) { - this.activeSideAction = "actie.locatie.toevoegen"; - this.actionsSidenav.open(); - } - } - editCaseDetails(): void { if (this.zaak.rechten.wijzigen || this.zaak.rechten.toekennen) { this.activeSideAction = "actie.zaak.wijzigen"; @@ -1030,16 +1019,6 @@ export class ZaakViewComponent ); } - locatieGeselecteerd(locatie: GeometryGegevens): void { - this.actionsSidenav.close(); - this.websocketService.suspendListener(this.zaakListener); - this.zakenService - .updateZaakLocatie(this.zaak.uuid, locatie.geometry, locatie.reden) - .subscribe((updatedZaak) => { - this.init(updatedZaak); - }); - } - initiatorGeselecteerd(initiator: Klant): void { this.websocketService.suspendListener(this.zaakRollenListener); this.actionsSidenav.close(); diff --git a/src/main/app/src/app/zaken/zaken.service.ts b/src/main/app/src/app/zaken/zaken.service.ts index 40f9a9ead7..9a89c6717c 100644 --- a/src/main/app/src/app/zaken/zaken.service.ts +++ b/src/main/app/src/app/zaken/zaken.service.ts @@ -23,7 +23,6 @@ import { ZaakAfbrekenGegevens } from "./model/zaak-afbreken-gegevens"; import { ZaakAfsluitenGegevens } from "./model/zaak-afsluiten-gegevens"; import { ZaakBetrokkene } from "./model/zaak-betrokkene"; import { ZaakBetrokkeneGegevens } from "./model/zaak-betrokkene-gegevens"; -import { ZaakEditMetRedenGegevens } from "./model/zaak-edit-met-reden-gegevens"; import { ZaakHeropenenGegevens } from "./model/zaak-heropenen-gegevens"; import { ZaakLocatieGegevens } from "./model/zaak-locatie-gegevens"; import { ZaakToekennenGegevens } from "./model/zaak-toekennen-gegevens"; @@ -69,12 +68,15 @@ export class ZakenService { ); } - updateZaak(uuid: string, zaak: Zaak, reden?: string): Observable { + updateZaak( + uuid: string, + update: { + zaak: Omit, "zaakgeometrie" | "behandelaar">; + reden?: string; + }, + ) { return this.http - .patch( - `${this.basepath}/zaak/${uuid}`, - new ZaakEditMetRedenGegevens(zaak, reden), - ) + .patch(`${this.basepath}/zaak/${uuid}`, update) .pipe( catchError((err) => this.foutAfhandelingService.foutAfhandelen(err)), ); @@ -146,13 +148,15 @@ export class ZakenService { ); } - toekennen(zaak: Zaak, reden?: string): Observable { - const toekennenGegevens: ZaakToekennenGegevens = - new ZaakToekennenGegevens(); - toekennenGegevens.zaakUUID = zaak.uuid; - toekennenGegevens.behandelaarGebruikersnaam = zaak.behandelaar?.id; - toekennenGegevens.groepId = zaak.groep?.id; - toekennenGegevens.reden = reden; + toekennen( + zaakUuid: string, + options?: { behandelaarId?: string; groupId?: string; reason?: string }, + ) { + const toekennenGegevens = new ZaakToekennenGegevens(); + toekennenGegevens.zaakUUID = zaakUuid; + toekennenGegevens.behandelaarGebruikersnaam = options?.behandelaarId; + toekennenGegevens.groepId = options?.groupId; + toekennenGegevens.reden = options?.reason; return this.http .patch(`${this.basepath}/toekennen`, toekennenGegevens) @@ -194,13 +198,10 @@ export class ZakenService { ); } - toekennenAanIngelogdeMedewerker( - zaak: Zaak, - reden?: string, - ): Observable { + toekennenAanIngelogdeMedewerker(zaakUuid: string, reden?: string) { const toekennenGegevens: ZaakToekennenGegevens = new ZaakToekennenGegevens(); - toekennenGegevens.zaakUUID = zaak.uuid; + toekennenGegevens.zaakUUID = zaakUuid; toekennenGegevens.reden = reden; return this.http diff --git a/src/main/app/src/app/zaken/zoek/locatie-zoek/locatie-zoek.component.html b/src/main/app/src/app/zaken/zoek/locatie-zoek/locatie-zoek.component.html index 9d96196e57..20d3a1ba9a 100644 --- a/src/main/app/src/app/zaken/zoek/locatie-zoek/locatie-zoek.component.html +++ b/src/main/app/src/app/zaken/zoek/locatie-zoek/locatie-zoek.component.html @@ -2,15 +2,6 @@ ~ SPDX-FileCopyrightText: 2022 Atos, 2024 Lifely ~ SPDX-License-Identifier: EUPL-1.2+ --> -
-

- location_on - {{ "actie.locatie." + (readonly ? "bekijken" : "toevoegen") | translate }} -

- -
@@ -57,17 +48,18 @@

matInput type="text" id="reden" - [formControl]="redenControl" + [formControl]="reasonControl" required="true" - maxlength="80" /> - {{ redenControl.value.length }}/80 + {{ reasonControl.value?.length }}/80