refactor: extract toWizardErrors, adopted by all 3 wizards (RD-20)
Each wizard flattened its per-field error record into the shell's WizardError[] summary with its own copy of the same loop. Extract one pure helper, wizard-errors.ts, next to naarStapLabel. Add a spec that covers a flat record, an empty record, skipped undefined/empty-string values, the idPrefix, and a skipped nested object. registratie-wizard.machine.ts changes Errors from an interface to a type alias, because only a type alias gets an implicit index signature and is assignable to the helper's Record<string, unknown> parameter. The other two machines already declare their error maps as type aliases, so this also makes the three consistent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+2
-6
@@ -9,6 +9,7 @@ import {
|
||||
WizardPhase,
|
||||
naarStapLabel,
|
||||
} from '@shared/layout/wizard-shell/wizard-shell.component';
|
||||
import { toWizardErrors } from '@shared/layout/wizard-shell/wizard-errors';
|
||||
import { ConfirmationComponent } from '@shared/ui/confirmation/confirmation.component';
|
||||
import { createStore } from '@shared/application/store';
|
||||
import { whenTag } from '@shared/kernel/fp';
|
||||
@@ -251,12 +252,7 @@ export class HerregistratieWizardComponent {
|
||||
}
|
||||
});
|
||||
/** Current step's field errors, flattened for the shell's error summary. */
|
||||
protected errorList = computed<WizardError[]>(() => {
|
||||
const e = this.editing()?.errors ?? {};
|
||||
return (Object.keys(e) as (keyof typeof e)[])
|
||||
.filter((k) => e[k])
|
||||
.map((k) => ({ id: k, message: e[k]! }));
|
||||
});
|
||||
protected errorList = computed<WizardError[]>(() => toWizardErrors(this.editing()?.errors ?? {}));
|
||||
|
||||
constructor() {
|
||||
// An explicit seed (stories/tests) wins; otherwise resume the backend draft
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
WizardPhase,
|
||||
naarStapLabel,
|
||||
} from '@shared/layout/wizard-shell/wizard-shell.component';
|
||||
import { toWizardErrors } from '@shared/layout/wizard-shell/wizard-errors';
|
||||
import { createStore } from '@shared/application/store';
|
||||
import { whenTag } from '@shared/kernel/fp';
|
||||
import { BigProfileStore } from '@registratie/application/big-profile.store';
|
||||
@@ -360,12 +361,9 @@ export class IntakeWizardComponent {
|
||||
});
|
||||
/** Current step's field errors, flattened for the shell's error summary. The
|
||||
field ids match the answer keys, so the summary anchors jump to the field. */
|
||||
protected errorList = computed<WizardError[]>(() => {
|
||||
const e = this.answering()?.errors ?? {};
|
||||
return (Object.keys(e) as (keyof Answers)[])
|
||||
.filter((k) => e[k])
|
||||
.map((k) => ({ id: k, message: e[k]! }));
|
||||
});
|
||||
protected errorList = computed<WizardError[]>(() =>
|
||||
toWizardErrors(this.answering()?.errors ?? {}),
|
||||
);
|
||||
|
||||
protected err = (k: keyof Answers) => this.answering()?.errors[k] ?? '';
|
||||
protected set = (key: keyof Answers, value: string) =>
|
||||
|
||||
@@ -66,7 +66,7 @@ export type DraftField = 'straat' | 'postcode' | 'woonplaats' | 'email';
|
||||
|
||||
/** Per-field error map. `antwoorden` holds per-policy-question errors, keyed by
|
||||
question id (a step can show several questions). */
|
||||
export interface Errors {
|
||||
export type Errors = {
|
||||
straat?: string;
|
||||
postcode?: string;
|
||||
woonplaats?: string;
|
||||
@@ -75,7 +75,7 @@ export interface Errors {
|
||||
diploma?: string;
|
||||
documenten?: string;
|
||||
antwoorden?: Record<string, string>;
|
||||
}
|
||||
};
|
||||
|
||||
export type RegistratieState =
|
||||
| { tag: 'Invullen'; draft: Draft; cursor: number; errors: Errors; upload: UploadState }
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
WizardPhase,
|
||||
naarStapLabel,
|
||||
} from '@shared/layout/wizard-shell/wizard-shell.component';
|
||||
import { toWizardErrors } from '@shared/layout/wizard-shell/wizard-errors';
|
||||
import { ASYNC } from '@shared/ui/async/async.component';
|
||||
import { AddressFieldsComponent } from '@registratie/ui/address-fields/address-fields.component';
|
||||
import { createStore } from '@shared/application/store';
|
||||
@@ -468,14 +469,7 @@ export class RegistratieWizardComponent {
|
||||
/** Current step's errors (incl. per-question), flattened for the error summary. */
|
||||
protected errorList = computed<WizardError[]>(() => {
|
||||
const e = this.invullen()?.errors ?? {};
|
||||
const out: WizardError[] = [];
|
||||
for (const [k, v] of Object.entries(e)) {
|
||||
if (k !== 'antwoorden' && typeof v === 'string' && v) out.push({ id: k, message: v });
|
||||
}
|
||||
for (const [qid, msg] of Object.entries(e.antwoorden ?? {})) {
|
||||
if (msg) out.push({ id: 'vraag-' + qid, message: msg });
|
||||
}
|
||||
return out;
|
||||
return [...toWizardErrors(e), ...toWizardErrors(e.antwoorden ?? {}, 'vraag-')];
|
||||
});
|
||||
protected adresSamenvatting = computed(() => {
|
||||
const d = this.draft();
|
||||
|
||||
Reference in New Issue
Block a user