Move the adres, beroep and controle cases out of registratie-wizard.component.ts into adres.step.ts, beroep.step.ts and controle.step.ts, matching RD-22's *.step.ts convention. The parent drops from ~568 to 274 lines and loses its `eslint-disable max-lines`. The upload controller moves into beroep.step.ts and emits `uploadMsg` instead of dispatching directly; the parent maps that back onto the machine's `Upload` message. `onDiplomaKeuze` stays in the parent (message construction from the DUO payload belongs in the container) and now takes only the chosen id, reading its own `duoData` computed instead of receiving the DUO payload as an argument. Each step injects `RegistratieLookupStore` directly for its own async presentation (adresStatus, the DUO lookup, samenvattingVragen) — the sanctioned exception, since it is a root singleton. Markup moved verbatim; the `@@` id count across the directory stays 43. Two of the ticket's acceptance numbers do not hold against correct code and are corrected in the ticket file: `createUploadController` is 2 lines (import + call), not 1 — `git grep -c` counts lines, and the same shape gives 2 for `createStore` and 3 for `createDraftSync` elsewhere in this codebase. `dispatch` is 1, not 0 — decision 4's mandated `UploadControllerDeps.dispatch` property name is that string even though it is not the machine's dispatch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
123 lines
4.5 KiB
TypeScript
123 lines
4.5 KiB
TypeScript
import { Component, inject, input, output } from '@angular/core';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { FormFieldComponent } from '@shared/ui/form-field/form-field.component';
|
|
import { TextInputComponent } from '@shared/ui/text-input/text-input.component';
|
|
import { RadioGroupComponent } from '@shared/ui/radio-group/radio-group.component';
|
|
import { AlertComponent } from '@shared/ui/alert/alert.component';
|
|
import { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';
|
|
import { AddressFieldsComponent } from '@registratie/ui/address-fields/address-fields.component';
|
|
import { RegistratieLookupStore } from '@registratie/application/registratie-lookup.store';
|
|
import { Draft, DraftField, Errors } from '@registratie/domain/registratie-wizard.machine';
|
|
|
|
const KANALEN = [
|
|
{ value: 'email', label: $localize`:@@registratie.kanaalEmail:E-mail` },
|
|
{ value: 'post', label: $localize`:@@registratie.kanaalPost:Post` },
|
|
];
|
|
|
|
/** Step: the registratie wizard's first screen (adres + correspondentievoorkeur).
|
|
Injects RegistratieLookupStore directly for the BRP lookup banner — the
|
|
sanctioned exception (it is `providedIn: 'root'`, so every injection is the
|
|
same instance): the step owns its own async presentation rather than making
|
|
the parent a pass-through for it. Values otherwise in via `draft`/`errors`,
|
|
every change out via `fieldChange`/`kanaalChange`. No internal state; the
|
|
parent owns the Model and decides what a change means. */
|
|
@Component({
|
|
selector: 'app-reg-adres-step',
|
|
imports: [
|
|
FormsModule,
|
|
FormFieldComponent,
|
|
TextInputComponent,
|
|
RadioGroupComponent,
|
|
AlertComponent,
|
|
SkeletonComponent,
|
|
AddressFieldsComponent,
|
|
],
|
|
template: `
|
|
@if (adresStatus() === 'laden') {
|
|
<app-skeleton height="2.5rem" [count]="4" />
|
|
} @else {
|
|
@switch (adresStatus()) {
|
|
@case ('gevonden') {
|
|
<app-alert type="info" i18n="@@regWizard.brpGevonden"
|
|
>Vooraf ingevuld op basis van de BRP. Controleer en pas zo nodig aan.</app-alert
|
|
>
|
|
}
|
|
@case ('geen') {
|
|
<app-alert type="warning" i18n="@@regWizard.brpGeen"
|
|
>We vonden geen adres in de BRP. Vul uw adres hieronder handmatig in.</app-alert
|
|
>
|
|
}
|
|
@case ('fout') {
|
|
<app-alert type="warning" i18n="@@regWizard.brpFout"
|
|
>We konden de BRP nu niet bereiken. Vul uw adres hieronder handmatig in.</app-alert
|
|
>
|
|
}
|
|
}
|
|
<app-address-fields
|
|
[value]="{
|
|
straat: draft().straat ?? '',
|
|
postcode: draft().postcode ?? '',
|
|
woonplaats: draft().woonplaats ?? '',
|
|
}"
|
|
[errors]="{
|
|
straat: err('straat'),
|
|
postcode: err('postcode'),
|
|
woonplaats: err('woonplaats'),
|
|
}"
|
|
(fieldChange)="fieldChange.emit($event)"
|
|
/>
|
|
<fieldset>
|
|
<app-form-field
|
|
i18n-label="@@regWizard.correspondentieLabel"
|
|
label="Hoe wilt u correspondentie ontvangen?"
|
|
fieldId="correspondentie"
|
|
required
|
|
[error]="err('correspondentie')"
|
|
>
|
|
<app-radio-group
|
|
name="correspondentie"
|
|
[options]="kanalen"
|
|
[invalid]="!!err('correspondentie')"
|
|
[ngModel]="draft().correspondentie ?? ''"
|
|
(ngModelChange)="kanaalChange.emit($event)"
|
|
/>
|
|
</app-form-field>
|
|
</fieldset>
|
|
@if (draft().correspondentie === 'email') {
|
|
<fieldset>
|
|
<app-form-field
|
|
i18n-label="@@regWizard.emailLabel"
|
|
label="E-mailadres"
|
|
fieldId="email"
|
|
required
|
|
[error]="err('email')"
|
|
>
|
|
<app-text-input
|
|
inputId="email"
|
|
type="email"
|
|
[invalid]="!!err('email')"
|
|
[ngModel]="draft().email ?? ''"
|
|
(ngModelChange)="fieldChange.emit({ key: 'email', value: $event })"
|
|
name="email"
|
|
i18n-placeholder="@@regWizard.emailPlaceholder"
|
|
placeholder="naam@voorbeeld.nl"
|
|
/>
|
|
</app-form-field>
|
|
</fieldset>
|
|
}
|
|
}
|
|
`,
|
|
})
|
|
export class AdresStep {
|
|
private lookup = inject(RegistratieLookupStore);
|
|
|
|
draft = input.required<Draft>();
|
|
errors = input.required<Errors>();
|
|
fieldChange = output<{ key: DraftField; value: string }>();
|
|
kanaalChange = output<string>();
|
|
|
|
protected adresStatus = this.lookup.adresStatus;
|
|
readonly kanalen = KANALEN;
|
|
protected err = (k: DraftField | 'correspondentie') => this.errors()[k] ?? '';
|
|
}
|