refactor: split dashboard.page.ts into per-concern sections

Each dashboard section (Mijn aanvragen, Wat moet ik regelen, Mijn
registratie, Specialismen, Wat wilt u doen, Beheer) now owns its own
store access, async state, and template. DashboardPage becomes pure
composition.

Extract the repeated RemoteData Success-narrowing pattern into
successOf() and the dashboard sort/split logic into
sortForDashboard/concepten/ingediend, both with tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
eho
2026-09-04 15:17:02 +02:00
co-authored by Claude Sonnet 5
parent 42e7a1e927
commit 5977efe044
17 changed files with 725 additions and 334 deletions
@@ -0,0 +1,84 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { applicationConfig } from '@storybook/angular';
import { provideRouter } from '@angular/router';
import { MijnAanvragenSection } from './mijn-aanvragen.section';
import { AanvragenStore } from '@registratie/application/aanvragen.store';
import { Aanvraag } from '@registratie/domain/aanvraag';
import { RemoteData } from '@shared/application/remote-data';
import { loading, success, failure } from '@shared/testing/remote-data';
const base = {
id: 'a1',
type: 'herregistratie',
documentIds: [],
createdAt: '2026-06-28T10:00:00Z',
updatedAt: '2026-06-28T10:05:00Z',
submittedAt: '2026-06-28T10:05:00Z',
} satisfies Omit<Aanvraag, 'status'>;
const concept: Aanvraag = { ...base, status: { tag: 'Concept', stepIndex: 1, stepCount: 3 } };
const ingediend: Aanvraag = {
...base,
id: 'a2',
status: { tag: 'InBehandeling', referentie: 'BIG-2026-456789', manual: false },
};
/** Minimal store stand-in — only the members the section's template reads. */
function storeStub(aanvragen: RemoteData<Error | undefined, Aanvraag[]>, lastError = '') {
return {
aanvragen: () => aanvragen,
reload: () => {},
cancel: async () => {},
lastError: () => lastError,
};
}
const meta: Meta<MijnAanvragenSection> = {
title: 'Domein/Registratie/Dashboard/Mijn Aanvragen',
component: MijnAanvragenSection,
decorators: [applicationConfig({ providers: [provideRouter([])] })],
};
export default meta;
type Story = StoryObj<MijnAanvragenSection>;
export const Loading: Story = {
decorators: [
applicationConfig({ providers: [{ provide: AanvragenStore, useValue: storeStub(loading()) }] }),
],
};
export const WithConceptAndSubmitted: Story = {
decorators: [
applicationConfig({
providers: [{ provide: AanvragenStore, useValue: storeStub(success([concept, ingediend])) }],
}),
],
};
export const Empty: Story = {
decorators: [
applicationConfig({
providers: [{ provide: AanvragenStore, useValue: storeStub(success([])) }],
}),
],
};
export const CancelFailed: Story = {
decorators: [
applicationConfig({
providers: [
{
provide: AanvragenStore,
useValue: storeStub(
success([concept]),
$localize`:@@dashboard.cancel.failed:Verwijderen is niet gelukt.`,
),
},
],
}),
],
};
export const Failed: Story = {
decorators: [
applicationConfig({
providers: [{ provide: AanvragenStore, useValue: storeStub(failure(new Error('offline'))) }],
}),
],
};