Skip to content

Commit

Permalink
feat: merged location form with the case detail edit form (#2808)
Browse files Browse the repository at this point in the history
combined two forms into a single one

Solves PZ-4900
  • Loading branch information
xiduzo authored Mar 3, 2025
1 parent c92a138 commit b849b05
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 265 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ export class FormComponent {
}
}

@Output() formSubmit: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
@Output() formPartial: EventEmitter<FormGroup> =
new EventEmitter<FormGroup>();
@Output() formSubmit = new EventEmitter<FormGroup>();
@Output() formPartial = new EventEmitter<FormGroup>();

data: Array<AbstractFormField[]>;
formGroup: FormGroup;
Expand All @@ -45,8 +44,6 @@ export class FormComponent {

private _config: FormConfig;

constructor() {}

refreshFormfields(formFields: Array<AbstractFormField[]>): void {
this.data = formFields;

Expand Down
13 changes: 0 additions & 13 deletions src/main/app/src/app/zaken/model/zaak-edit-met-reden-gegevens.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,40 @@ <h3>
<mat-icon>edit</mat-icon>
{{ "actie.zaak.wijzigen" | translate }}
</h3>
<button mat-icon-button (click)="sideNav.close()">
<button mat-icon-button (click)="exit()">
<mat-icon>close</mat-icon>
</button>
</div>

<div>
<mat-tab-group mat-stretch-tabs="false">
<mat-tab label="Tab 1">
<mat-tab label="{{ 'gegevens.algemeen' | translate }}">
<ng-template mat-tab-label>
<mat-icon>topic</mat-icon>
{{ "gegevens.algemeen" | translate }}</ng-template
>
<div class="form">
<mfb-form
#mfbForm
*ngIf="formFields"
[formFields]="formFields"
[config]="formConfig"
(formSubmit)="onFormSubmit($event)"
(formSubmit)="saveFromFormView($event)"
(formPartial)="saveFromFormView($event)"
></mfb-form>
</div>
</mat-tab>
<mat-tab label="Tab 2" *ngIf="false">
<mat-tab label="{{ 'locatie' | translate }}">
<ng-template mat-tab-label>
<mat-icon>place</mat-icon>
{{ "locatie" | translate }}
</ng-template>
<div>Location Content - Todo</div>
<zac-locatie-zoek
[huidigeLocatie]="zaak.zaakgeometrie"
[readonly]="!zaak.isOpen || !zaak.rechten.wijzigen"
[reasonControl]="reasonField.formControl"
(locatie)="saveFromMapView()"
(locationChanged)="locationChanged($event)"
></zac-locatie-zoek>
</mat-tab>
</mat-tab-group>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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<void>();
private initialZaakGeometry: Geometry;

constructor(
private zakenService: ZakenService,
private referentieTabelService: ReferentieTabelService,
private utilService: UtilService,
) {}

ngOnInit() {
) {
this.formConfig = new FormConfigBuilder()
.saveText("actie.opslaan")
.cancelText("actie.annuleren")
Expand All @@ -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,
Expand All @@ -99,7 +115,6 @@ export class CaseDetailsEditComponent implements OnDestroy, OnInit {
.validators(Validators.required)
.build();

//
this.startDatumField = this.createDateFormField(
"startdatum",
this.zaak.startdatum,
Expand Down Expand Up @@ -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],
[
Expand Down Expand Up @@ -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<string, any>) {
const { assignment, reason, ...updates } = update;

return {
...updates,
groep: assignment.groep,
behandelaar: assignment.medewerker,
} satisfies Partial<Zaak>;
}

private async updateZaak(zaak: Partial<Zaak>) {
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<Zaak>, 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(
Expand Down
30 changes: 5 additions & 25 deletions src/main/app/src/app/zaken/zaak-view/zaak-view.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,6 @@
[sideNav]="actionsSidenav"
(bagObject)="adresGeselecteerd($event)"
></zac-bag-zoek>
<zac-locatie-zoek
*ngSwitchCase="'actie.locatie.toevoegen'"
[sideNav]="actionsSidenav"
[huidigeLocatie]="zaak.zaakgeometrie"
[readonly]="!zaak.isOpen || !zaak.rechten.wijzigen"
(locatie)="locatieGeselecteerd($event)"
></zac-locatie-zoek>
<zac-case-details-edit
*ngSwitchCase="'actie.zaak.wijzigen'"
[zaak]="zaak"
Expand Down Expand Up @@ -295,24 +288,11 @@
"
class="flex-item"
></zac-static-text>
<div
class="location-text flex-item"
[class.readonly]="!zaak.isOpen || !zaak.rechten.wijzigen"
(click)="showOrEditZaakLocatie()"
>
<label class="static-text-label" translate="locatie">
<mat-icon>edit</mat-icon>
</label>
<div
class="static-text-content"
[ngClass]="{ nopanel: zaak.zaakgeometrie == null }"
>
{{ zaak.zaakgeometrie | location | empty }}
<div class="edit-icon">
<mat-icon>place</mat-icon>
</div>
</div>
</div>
<zac-static-text
[label]="'locatie' | translate"
[value]="zaak.zaakgeometrie | location | empty"
class="flex-item"
></zac-static-text>
</div>

<div class="flex flex-col gap-10">
Expand Down
Loading

0 comments on commit b849b05

Please sign in to comment.