{ "pipes": [], "interfaces": [ { "name": "Aantekening", "id": "interface-Aantekening-2ecca36e413e22c1c5967d07b811fa4171ff578eb6b47a7275723bcca44e93a2db27d77a765b82e5f6182492464cc8b9268c9724e13b400718d30da7bc4ba50c", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export type RegistrationStatus =\n | { tag: 'Geregistreerd'; herregistratieDatum: string } // ISO date\n | { tag: 'Geschorst'; geschorstTot: string; reden: string }\n | { tag: 'Doorgehaald'; doorgehaaldOp: string; reden: string };\n\n/** Just the discriminant — for atoms that only need the label/color. */\nexport type StatusTag = RegistrationStatus['tag'];\n\nexport interface Registration {\n bigNummer: string;\n naam: string;\n beroep: string; // arts, verpleegkundige, apotheker, ...\n registratiedatum: string; // ISO date\n geboortedatum: string;\n status: RegistrationStatus;\n}\n\nexport interface Aantekening {\n type: string; // specialisme of aantekening\n omschrijving: string;\n datum: string;\n}\n", "properties": [ { "name": "datum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 28 }, { "name": "omschrijving", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 27 }, { "name": "type", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 26 } ], "indexSignatures": [], "kind": 172, "methods": [], "extends": [] }, { "name": "Adres", "id": "interface-Adres-07cec46d80a41919e40d0bcb002981627d1a30edb363d64a0a140a8af2c38ad85be5603d88030d0704870800694c5bed9c709ae6891fe83e646e90c1a67cf548", "file": "src/app/registratie/domain/person.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export interface Adres {\n straat: string;\n postcode: string;\n woonplaats: string;\n}\n\nexport interface Person {\n naam: string;\n geboortedatum: string; // ISO date\n adres: Adres;\n}\n", "properties": [ { "name": "postcode", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 4 }, { "name": "straat", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 3 }, { "name": "woonplaats", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 5 } ], "indexSignatures": [], "kind": 172, "description": "

Person identity as supplied by the BRP (Basisregistratie Personen).

\n", "rawdescription": "\nPerson identity as supplied by the BRP (Basisregistratie Personen).", "methods": [], "extends": [] }, { "name": "BigProfile", "id": "interface-BigProfile-c363e317899ff3cd424b0033c2f57ea14e9617f52401171543b5a82d67046a894a2806afc198812808d0080b3093471e081f7e79b12f2c8c37eef68785e47a43", "file": "src/app/registratie/domain/big-profile.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Registration } from './registration';\nimport { Person } from './person';\n\n/**\n * The view the dashboard/detail render: a registration (from the BIG-register)\n * enriched with person data (from the BRP). It only exists when BOTH sources\n * have loaded — see BigProfileStore, which builds it with map2.\n */\nexport interface BigProfile {\n registration: Registration;\n person: Person;\n}\n", "properties": [ { "name": "person", "deprecated": false, "deprecationMessage": "", "type": "Person", "indexKey": "", "optional": false, "description": "", "line": 11 }, { "name": "registration", "deprecated": false, "deprecationMessage": "", "type": "Registration", "indexKey": "", "optional": false, "description": "", "line": 10 } ], "indexSignatures": [], "kind": 172, "description": "

The view the dashboard/detail render: a registration (from the BIG-register)\nenriched with person data (from the BRP). It only exists when BOTH sources\nhave loaded — see BigProfileStore, which builds it with map2.

\n", "rawdescription": "\n\nThe view the dashboard/detail render: a registration (from the BIG-register)\nenriched with person data (from the BRP). It only exists when BOTH sources\nhave loaded — see BigProfileStore, which builds it with map2.\n", "methods": [], "extends": [] }, { "name": "ChangeRequest", "id": "interface-ChangeRequest-8d79b6a9ce75f62f4e04f9d3ed0867e00d005c9c05cf267503536c4eec9813372aff51a3c8686927fd07f46503b60ddb4107edcc5f57fdfa1b6b52fe2a98026c", "file": "src/app/registratie/ui/change-request-form/change-request-form.component.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Component, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { Postcode, parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** A submitted change request carries a *parsed* postcode (branded Postcode),\n not a raw string — downstream code can't receive an unvalidated one. */\nexport interface ChangeRequest {\n street: string;\n zip: Postcode;\n city: string;\n}\n\n/** Organism: change-request (adreswijziging) form. Reuses the same form-field\n molecule + text-input/button atoms as the login form. Field errors come\n straight from the parser's Result — no parallel \"is it valid\" flag to drift. */\n@Component({\n selector: 'app-change-request-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent, HeadingComponent],\n template: `\n Adreswijziging doorgeven\n
\n \n \n \n \n \n \n \n \n \n
\n Wijziging indienen\n
\n
\n `,\n})\nexport class ChangeRequestFormComponent {\n street = '';\n zip = '';\n city = '';\n streetError = signal('');\n zipError = signal('');\n submitted = output();\n\n onSubmit() {\n const street = this.street.trim();\n this.streetError.set(street ? '' : 'Vul straat en huisnummer in.');\n\n const postcode = parsePostcode(this.zip);\n this.zipError.set(postcode.ok ? '' : postcode.error);\n\n if (!street || !postcode.ok) return;\n this.submitted.emit({ street, zip: postcode.value, city: this.city.trim() });\n }\n}\n", "properties": [ { "name": "city", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 14 }, { "name": "street", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 12 }, { "name": "zip", "deprecated": false, "deprecationMessage": "", "type": "Postcode", "indexKey": "", "optional": false, "description": "", "line": 13 } ], "indexSignatures": [], "kind": 172, "description": "

A submitted change request carries a parsed postcode (branded Postcode),\nnot a raw string — downstream code can't receive an unvalidated one.

\n", "rawdescription": "\nA submitted change request carries a *parsed* postcode (branded Postcode),\nnot a raw string — downstream code can't receive an unvalidated one.", "methods": [], "extends": [] }, { "name": "Draft", "id": "interface-Draft-6d0ec48dfedad1e9d3dc32caaf0639d35f1430f1e8081a0a719ad0675d06912a90de0d8159326e13c9cc3c8f82521e3fded8d06a5feb1480be4c084a967e6aad", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/** What the user is typing (raw, possibly invalid). */\nexport interface Draft {\n uren: string;\n punten: string;\n}\n\n/** What we have AFTER parsing — branded/typed, guaranteed valid. */\nexport interface Valid {\n uren: Uren;\n punten: number;\n}\n\n/**\n * The whole wizard as one tagged union. `step` and `errors` exist ONLY while\n * Editing; Submitting/Submitted/Failed carry a `Valid` payload and nothing else.\n * So \"submitting while a field is invalid\" or \"showing the success screen with\n * errors set\" are unrepresentable — the bug class is gone by construction.\n */\nexport type WizardState =\n | { tag: 'Editing'; step: 1 | 2; draft: Draft; errors: Partial> }\n | { tag: 'Submitting'; data: Valid }\n | { tag: 'Submitted'; data: Valid }\n | { tag: 'Failed'; data: Valid; error: string };\n\nexport const initial: WizardState = { tag: 'Editing', step: 1, draft: { uren: '', punten: '' }, errors: {} };\n\n/** Parse every field; on success hand back a Valid, else the per-field errors. */\nfunction validate(draft: Draft): Result>, Valid> {\n const uren = parseUren(draft.uren);\n const punten = parseUren(draft.punten);\n const errors: Partial> = {};\n if (!uren.ok) errors.uren = uren.error;\n if (!punten.ok) errors.punten = punten.error;\n if (uren.ok && punten.ok) return { ok: true, value: { uren: uren.value, punten: punten.value } };\n return { ok: false, error: errors };\n}\n\n/** Step 1 → 2: only advance if the uren field parses. Illegal elsewhere = no-op. */\nexport function next(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 1) return s;\n const uren = parseUren(s.draft.uren);\n return uren.ok\n ? { ...s, step: 2, errors: {} }\n : { ...s, errors: { uren: uren.error } };\n}\n\nexport function back(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 2) return s;\n return { ...s, step: 1, errors: {} };\n}\n\n/** Step 2 submit: parse everything; move to Submitting only with Valid data. */\nexport function submit(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 2) return s;\n const result = validate(s.draft);\n return result.ok ? { tag: 'Submitting', data: result.value } : { ...s, errors: result.error };\n}\n\n/** Resolve the async submit. Only meaningful while Submitting. */\nexport function resolve(s: WizardState, r: Result): WizardState {\n if (s.tag !== 'Submitting') return s;\n return r.ok ? { tag: 'Submitted', data: s.data } : { tag: 'Failed', data: s.data, error: r.error };\n}\n\n/** Update one draft field while editing; ignored in any other state. */\nexport function setField(s: WizardState, key: keyof Draft, value: string): WizardState {\n if (s.tag !== 'Editing') return s;\n return { ...s, draft: { ...s.draft, [key]: value } };\n}\n\n/**\n * Every event that can happen to the wizard, as one message type. The component\n * sends a WizardMsg; `reduce` decides the next state. This is the Elm\n * Model+Msg+update pattern: ONE pure function describes all state changes.\n */\nexport type WizardMsg =\n | { tag: 'SetField'; key: keyof Draft; value: string }\n | { tag: 'Next' }\n | { tag: 'Back' }\n | { tag: 'Submit' }\n | { tag: 'Retry' }\n | { tag: 'SubmitConfirmed' }\n | { tag: 'SubmitFailed'; error: string }\n | { tag: 'Seed'; state: WizardState }; // mount a specific state (stories/showcase)\n\nexport function reduce(s: WizardState, m: WizardMsg): WizardState {\n switch (m.tag) {\n case 'SetField':\n return setField(s, m.key, m.value);\n case 'Next':\n return next(s);\n case 'Back':\n return back(s);\n case 'Submit':\n return submit(s);\n case 'Retry':\n return s.tag === 'Failed' ? { tag: 'Submitting', data: s.data } : s;\n case 'SubmitConfirmed':\n return s.tag === 'Submitting' ? { tag: 'Submitted', data: s.data } : s;\n case 'SubmitFailed':\n return s.tag === 'Submitting' ? { tag: 'Failed', data: s.data, error: m.error } : s;\n case 'Seed':\n return m.state;\n default:\n return assertNever(m);\n }\n}\n", "properties": [ { "name": "punten", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 7 }, { "name": "uren", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 6 } ], "indexSignatures": [], "kind": 172, "description": "

What the user is typing (raw, possibly invalid).

\n", "rawdescription": "\nWhat the user is typing (raw, possibly invalid).", "methods": [], "extends": [] }, { "name": "Person", "id": "interface-Person-07cec46d80a41919e40d0bcb002981627d1a30edb363d64a0a140a8af2c38ad85be5603d88030d0704870800694c5bed9c709ae6891fe83e646e90c1a67cf548", "file": "src/app/registratie/domain/person.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export interface Adres {\n straat: string;\n postcode: string;\n woonplaats: string;\n}\n\nexport interface Person {\n naam: string;\n geboortedatum: string; // ISO date\n adres: Adres;\n}\n", "properties": [ { "name": "adres", "deprecated": false, "deprecationMessage": "", "type": "Adres", "indexKey": "", "optional": false, "description": "", "line": 11 }, { "name": "geboortedatum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 10 }, { "name": "naam", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 9 } ], "indexSignatures": [], "kind": 172, "methods": [], "extends": [] }, { "name": "Registration", "id": "interface-Registration-2ecca36e413e22c1c5967d07b811fa4171ff578eb6b47a7275723bcca44e93a2db27d77a765b82e5f6182492464cc8b9268c9724e13b400718d30da7bc4ba50c", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export type RegistrationStatus =\n | { tag: 'Geregistreerd'; herregistratieDatum: string } // ISO date\n | { tag: 'Geschorst'; geschorstTot: string; reden: string }\n | { tag: 'Doorgehaald'; doorgehaaldOp: string; reden: string };\n\n/** Just the discriminant — for atoms that only need the label/color. */\nexport type StatusTag = RegistrationStatus['tag'];\n\nexport interface Registration {\n bigNummer: string;\n naam: string;\n beroep: string; // arts, verpleegkundige, apotheker, ...\n registratiedatum: string; // ISO date\n geboortedatum: string;\n status: RegistrationStatus;\n}\n\nexport interface Aantekening {\n type: string; // specialisme of aantekening\n omschrijving: string;\n datum: string;\n}\n", "properties": [ { "name": "beroep", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 19 }, { "name": "bigNummer", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 17 }, { "name": "geboortedatum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 21 }, { "name": "naam", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 18 }, { "name": "registratiedatum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 20 }, { "name": "status", "deprecated": false, "deprecationMessage": "", "type": "RegistrationStatus", "indexKey": "", "optional": false, "description": "", "line": 22 } ], "indexSignatures": [], "kind": 172, "methods": [], "extends": [] }, { "name": "Session", "id": "interface-Session-4f483129ecb1f3747a600d06904b954a4950b10c4da782d9635896d2c39feaa7777d0e9ed018efa5d4252fd44a29035a431e7dcc15ec19c903f710b163e162f2", "file": "src/app/auth/domain/session.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export interface Session {\n readonly bsn: string;\n readonly naam: string;\n}\n\nexport function isAuthenticated(s: Session | null): s is Session {\n return s !== null;\n}\n", "properties": [ { "name": "bsn", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 3, "modifierKind": [ 148 ] }, { "name": "naam", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 4, "modifierKind": [ 148 ] } ], "indexSignatures": [], "kind": 172, "description": "

Who is logged in. Framework-free domain type.

\n", "rawdescription": "\nWho is logged in. Framework-free domain type.", "methods": [], "extends": [] }, { "name": "Store", "id": "interface-Store-de6d0ec7e0704c5d9490e9a33e624477e924daff53384c527eb4aaa76178bd1716ada071d7e46af3e0a859a7cbec63cdc114f61db5d36b61e49effcd5ac744f9", "file": "src/app/shared/application/store.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Signal, signal } from '@angular/core';\n\n/**\n * A tiny \"Elm-style\" store. The whole idea: all state lives in ONE value\n * (the Model). The only way to change it is to send a message (Msg) to a PURE\n * function `update(model, msg)` that returns the next Model. Nothing else\n * mutates state, so to understand the app you only read the update function.\n *\n * Side effects (HTTP, timers) do NOT go in `update` — that stays pure and easy\n * to test. Instead, effectful \"command\" functions call the network and then\n * `dispatch` a message describing what happened (e.g. Loaded / Failed).\n */\nexport interface Store {\n /** The current state, as a read-only Angular signal. */\n readonly model: Signal;\n /** Send a message; the model becomes update(model, msg). */\n dispatch(msg: Msg): void;\n}\n\nexport function createStore(\n init: Model,\n update: (model: Model, msg: Msg) => Model,\n): Store {\n const model = signal(init);\n return {\n model: model.asReadonly(),\n dispatch: (msg) => model.set(update(model(), msg)),\n };\n}\n", "properties": [ { "name": "model", "deprecated": false, "deprecationMessage": "", "type": "Signal", "indexKey": "", "optional": false, "description": "

The current state, as a read-only Angular signal.

\n", "line": 15, "rawdescription": "\nThe current state, as a read-only Angular signal.", "modifierKind": [ 148 ] } ], "indexSignatures": [], "kind": 174, "description": "

A tiny "Elm-style" store. The whole idea: all state lives in ONE value\n(the Model). The only way to change it is to send a message (Msg) to a PURE\nfunction update(model, msg) that returns the next Model. Nothing else\nmutates state, so to understand the app you only read the update function.

\n

Side effects (HTTP, timers) do NOT go in update — that stays pure and easy\nto test. Instead, effectful "command" functions call the network and then\ndispatch a message describing what happened (e.g. Loaded / Failed).

\n", "rawdescription": "\n\nA tiny \"Elm-style\" store. The whole idea: all state lives in ONE value\n(the Model). The only way to change it is to send a message (Msg) to a PURE\nfunction `update(model, msg)` that returns the next Model. Nothing else\nmutates state, so to understand the app you only read the update function.\n\nSide effects (HTTP, timers) do NOT go in `update` — that stays pure and easy\nto test. Instead, effectful \"command\" functions call the network and then\n`dispatch` a message describing what happened (e.g. Loaded / Failed).\n", "methods": [ { "name": "dispatch", "args": [ { "name": "msg", "type": "Msg", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 17, "deprecated": false, "deprecationMessage": "", "rawdescription": "\nSend a message; the model becomes update(model, msg).", "description": "

Send a message; the model becomes update(model, msg).

\n", "jsdoctags": [ { "name": "msg", "type": "Msg", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "extends": [] }, { "name": "Valid", "id": "interface-Valid-6d0ec48dfedad1e9d3dc32caaf0639d35f1430f1e8081a0a719ad0675d06912a90de0d8159326e13c9cc3c8f82521e3fded8d06a5feb1480be4c084a967e6aad", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/** What the user is typing (raw, possibly invalid). */\nexport interface Draft {\n uren: string;\n punten: string;\n}\n\n/** What we have AFTER parsing — branded/typed, guaranteed valid. */\nexport interface Valid {\n uren: Uren;\n punten: number;\n}\n\n/**\n * The whole wizard as one tagged union. `step` and `errors` exist ONLY while\n * Editing; Submitting/Submitted/Failed carry a `Valid` payload and nothing else.\n * So \"submitting while a field is invalid\" or \"showing the success screen with\n * errors set\" are unrepresentable — the bug class is gone by construction.\n */\nexport type WizardState =\n | { tag: 'Editing'; step: 1 | 2; draft: Draft; errors: Partial> }\n | { tag: 'Submitting'; data: Valid }\n | { tag: 'Submitted'; data: Valid }\n | { tag: 'Failed'; data: Valid; error: string };\n\nexport const initial: WizardState = { tag: 'Editing', step: 1, draft: { uren: '', punten: '' }, errors: {} };\n\n/** Parse every field; on success hand back a Valid, else the per-field errors. */\nfunction validate(draft: Draft): Result>, Valid> {\n const uren = parseUren(draft.uren);\n const punten = parseUren(draft.punten);\n const errors: Partial> = {};\n if (!uren.ok) errors.uren = uren.error;\n if (!punten.ok) errors.punten = punten.error;\n if (uren.ok && punten.ok) return { ok: true, value: { uren: uren.value, punten: punten.value } };\n return { ok: false, error: errors };\n}\n\n/** Step 1 → 2: only advance if the uren field parses. Illegal elsewhere = no-op. */\nexport function next(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 1) return s;\n const uren = parseUren(s.draft.uren);\n return uren.ok\n ? { ...s, step: 2, errors: {} }\n : { ...s, errors: { uren: uren.error } };\n}\n\nexport function back(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 2) return s;\n return { ...s, step: 1, errors: {} };\n}\n\n/** Step 2 submit: parse everything; move to Submitting only with Valid data. */\nexport function submit(s: WizardState): WizardState {\n if (s.tag !== 'Editing' || s.step !== 2) return s;\n const result = validate(s.draft);\n return result.ok ? { tag: 'Submitting', data: result.value } : { ...s, errors: result.error };\n}\n\n/** Resolve the async submit. Only meaningful while Submitting. */\nexport function resolve(s: WizardState, r: Result): WizardState {\n if (s.tag !== 'Submitting') return s;\n return r.ok ? { tag: 'Submitted', data: s.data } : { tag: 'Failed', data: s.data, error: r.error };\n}\n\n/** Update one draft field while editing; ignored in any other state. */\nexport function setField(s: WizardState, key: keyof Draft, value: string): WizardState {\n if (s.tag !== 'Editing') return s;\n return { ...s, draft: { ...s.draft, [key]: value } };\n}\n\n/**\n * Every event that can happen to the wizard, as one message type. The component\n * sends a WizardMsg; `reduce` decides the next state. This is the Elm\n * Model+Msg+update pattern: ONE pure function describes all state changes.\n */\nexport type WizardMsg =\n | { tag: 'SetField'; key: keyof Draft; value: string }\n | { tag: 'Next' }\n | { tag: 'Back' }\n | { tag: 'Submit' }\n | { tag: 'Retry' }\n | { tag: 'SubmitConfirmed' }\n | { tag: 'SubmitFailed'; error: string }\n | { tag: 'Seed'; state: WizardState }; // mount a specific state (stories/showcase)\n\nexport function reduce(s: WizardState, m: WizardMsg): WizardState {\n switch (m.tag) {\n case 'SetField':\n return setField(s, m.key, m.value);\n case 'Next':\n return next(s);\n case 'Back':\n return back(s);\n case 'Submit':\n return submit(s);\n case 'Retry':\n return s.tag === 'Failed' ? { tag: 'Submitting', data: s.data } : s;\n case 'SubmitConfirmed':\n return s.tag === 'Submitting' ? { tag: 'Submitted', data: s.data } : s;\n case 'SubmitFailed':\n return s.tag === 'Submitting' ? { tag: 'Failed', data: s.data, error: m.error } : s;\n case 'Seed':\n return m.state;\n default:\n return assertNever(m);\n }\n}\n", "properties": [ { "name": "punten", "deprecated": false, "deprecationMessage": "", "type": "number", "indexKey": "", "optional": false, "description": "", "line": 13 }, { "name": "uren", "deprecated": false, "deprecationMessage": "", "type": "Uren", "indexKey": "", "optional": false, "description": "", "line": 12 } ], "indexSignatures": [], "kind": 172, "description": "

What we have AFTER parsing — branded/typed, guaranteed valid.

\n", "rawdescription": "\nWhat we have AFTER parsing — branded/typed, guaranteed valid.", "methods": [], "extends": [] } ], "injectables": [ { "name": "BigProfileStore", "id": "injectable-BigProfileStore-d0fd61e9f3ea54ee7ebca6eb9a097da261a7447f337e972e7bbb2a8c238f15a8f175b1fddac6c031fc95f77ab8d2778748a149f358ef5f5ec22ecaa23971ef9a", "file": "src/app/registratie/application/big-profile.store.ts", "properties": [ { "name": "aantekeningen", "defaultValue": "computed>(() =>\n fromResource(this.aantekeningenRes, (v) => v.length === 0),\n )", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "

Specialisms/notes stay a separate stream (they have their own empty state).

\n", "line": 41, "rawdescription": "\nSpecialisms/notes stay a separate stream (they have their own empty state).", "modifierKind": [ 148 ] }, { "name": "aantekeningenRes", "defaultValue": "this.big.aantekeningenResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 26, "modifierKind": [ 123 ] }, { "name": "big", "defaultValue": "inject(BigRegisterAdapter)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 22, "modifierKind": [ 123 ] }, { "name": "brp", "defaultValue": "inject(BrpAdapter)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 23, "modifierKind": [ 123 ] }, { "name": "pending", "defaultValue": "signal(false)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 46, "modifierKind": [ 123 ] }, { "name": "pendingHerregistratie", "defaultValue": "this.pending.asReadonly()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "

True while a herregistratie submission is in flight or just submitted.

\n", "line": 48, "rawdescription": "\nTrue while a herregistratie submission is in flight or just submitted.", "modifierKind": [ 148 ] }, { "name": "personRes", "defaultValue": "this.brp.personResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 27, "modifierKind": [ 123 ] }, { "name": "profile", "defaultValue": "computed>(() =>\n map2(\n fromResource(this.registrationRes),\n fromResource(this.personRes),\n // httpResource types value as T | undefined; in the Success branch it is\n // always present, so narrowing here is safe.\n (registration, person) => ({ registration: registration!, person: person! }),\n ),\n )", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "

BIG-register + BRP folded into one state.

\n", "line": 30, "rawdescription": "\nBIG-register + BRP folded into one state.", "modifierKind": [ 148 ] }, { "name": "registrationRes", "defaultValue": "this.big.registrationResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 25, "modifierKind": [ 123 ] } ], "methods": [ { "name": "beginHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 50, "deprecated": false, "deprecationMessage": "" }, { "name": "confirmHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 53, "deprecated": false, "deprecationMessage": "" }, { "name": "rollbackHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 57, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "

The single source of truth for the logged-in professional's profile, shared\nacross pages (providedIn:'root' = one instance). It owns the httpResources\n(created here, in the required injection context) and exposes them as\nRemoteData signals.

\n

The headline trick: profile combines TWO independent services — the\nBIG-register and the BRP — into ONE RemoteData via map2. A page renders a\nsingle state (loading / error / loaded), never juggling three.

\n", "rawdescription": "\n\nThe single source of truth for the logged-in professional's profile, shared\nacross pages (providedIn:'root' = one instance). It owns the httpResources\n(created here, in the required injection context) and exposes them as\nRemoteData signals.\n\nThe headline trick: `profile` combines TWO independent services — the\nBIG-register and the BRP — into ONE RemoteData via map2. A page renders a\nsingle state (loading / error / loaded), never juggling three.\n", "sourceCode": "import { Injectable, computed, inject, signal } from '@angular/core';\nimport { RemoteData, fromResource, map2 } from '@shared/application/remote-data';\nimport { Aantekening } from '../domain/registration';\nimport { BigProfile } from '../domain/big-profile';\nimport { BigRegisterAdapter } from '../infrastructure/big-register.adapter';\nimport { BrpAdapter } from '../infrastructure/brp.adapter';\n\ntype Err = Error | undefined;\n\n/**\n * The single source of truth for the logged-in professional's profile, shared\n * across pages (providedIn:'root' = one instance). It owns the httpResources\n * (created here, in the required injection context) and exposes them as\n * RemoteData signals.\n *\n * The headline trick: `profile` combines TWO independent services — the\n * BIG-register and the BRP — into ONE RemoteData via map2. A page renders a\n * single state (loading / error / loaded), never juggling three.\n */\n@Injectable({ providedIn: 'root' })\nexport class BigProfileStore {\n private big = inject(BigRegisterAdapter);\n private brp = inject(BrpAdapter);\n\n private registrationRes = this.big.registrationResource();\n private aantekeningenRes = this.big.aantekeningenResource();\n private personRes = this.brp.personResource();\n\n /** BIG-register + BRP folded into one state. */\n readonly profile = computed>(() =>\n map2(\n fromResource(this.registrationRes),\n fromResource(this.personRes),\n // httpResource types value as T | undefined; in the Success branch it is\n // always present, so narrowing here is safe.\n (registration, person) => ({ registration: registration!, person: person! }),\n ),\n );\n\n /** Specialisms/notes stay a separate stream (they have their own empty state). */\n readonly aantekeningen = computed>(() =>\n fromResource(this.aantekeningenRes, (v) => v.length === 0),\n );\n\n // --- Optimistic herregistratie state, shared with the dashboard -----------\n private pending = signal(false);\n /** True while a herregistratie submission is in flight or just submitted. */\n readonly pendingHerregistratie = this.pending.asReadonly();\n\n beginHerregistratie() {\n this.pending.set(true); // optimistic: show it immediately on the dashboard\n }\n confirmHerregistratie() {\n this.pending.set(false);\n this.registrationRes.reload(); // invalidate: re-fetch the now-updated registration\n }\n rollbackHerregistratie() {\n this.pending.set(false); // submission failed — undo the optimistic flag\n }\n}\n", "extends": [], "type": "injectable" }, { "name": "BigRegisterAdapter", "id": "injectable-BigRegisterAdapter-b658d9915e8f09eed460d1f75d5dc229398186277cfa4d35fd143799842c80174c41daf2f30936090fda88e72f3bbfc3e9422cbfa7b1d1342eb004cc2d80e3ae", "file": "src/app/registratie/infrastructure/big-register.adapter.ts", "properties": [], "methods": [ { "name": "aantekeningenResource", "args": [], "optional": false, "returnType": "any", "typeParameters": [], "line": 17, "deprecated": false, "deprecationMessage": "" }, { "name": "registrationResource", "args": [], "optional": false, "returnType": "any", "typeParameters": [], "line": 13, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "

Infrastructure adapter for the BIG-register source. Exposes signal-based\nresources (Angular's httpResource); each returns a Resource with\nstatus()/value()/error()/reload(). Call from an injection context\n(a field initializer in the store).

\n", "rawdescription": "\n\nInfrastructure adapter for the BIG-register source. Exposes signal-based\nresources (Angular's httpResource); each returns a Resource with\nstatus()/value()/error()/reload(). Call from an injection context\n(a field initializer in the store).\n", "sourceCode": "import { Injectable } from '@angular/core';\nimport { httpResource } from '@angular/common/http';\nimport { Registration, Aantekening } from '../domain/registration';\n\n/**\n * Infrastructure adapter for the BIG-register source. Exposes signal-based\n * resources (Angular's httpResource); each returns a Resource with\n * status()/value()/error()/reload(). Call from an injection context\n * (a field initializer in the store).\n */\n@Injectable({ providedIn: 'root' })\nexport class BigRegisterAdapter {\n registrationResource() {\n return httpResource(() => 'mock/registration.json');\n }\n\n aantekeningenResource() {\n return httpResource(() => 'mock/notes.json', { defaultValue: [] });\n }\n}\n", "extends": [], "type": "injectable" }, { "name": "BrpAdapter", "id": "injectable-BrpAdapter-66b7fdb8331dd6cebe24a4713e26a6b025c4c97b239a8de8a81f9b72167dc376459e44aca001b24a7c44bdba6b97fa82d248762bbd1fca3a476993f709834b89", "file": "src/app/registratie/infrastructure/brp.adapter.ts", "properties": [], "methods": [ { "name": "personResource", "args": [], "optional": false, "returnType": "any", "typeParameters": [], "line": 8, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "

Infrastructure adapter for the BRP (Basisregistratie Personen) source.

\n", "rawdescription": "\nInfrastructure adapter for the BRP (Basisregistratie Personen) source.", "sourceCode": "import { Injectable } from '@angular/core';\nimport { httpResource } from '@angular/common/http';\nimport { Person } from '../domain/person';\n\n/** Infrastructure adapter for the BRP (Basisregistratie Personen) source. */\n@Injectable({ providedIn: 'root' })\nexport class BrpAdapter {\n personResource() {\n return httpResource(() => 'mock/brp.json');\n }\n}\n", "extends": [], "type": "injectable" }, { "name": "DigidAdapter", "id": "injectable-DigidAdapter-6b0a6d77a6f7411602d1c257ac45d4d45631556b1a468f7f38abfbbe375a3ac5e566fa6024ba56cb59f8418174ed2dbc6ea937b7b7999e58655acf01c7d7ecc9", "file": "src/app/auth/infrastructure/digid.adapter.ts", "properties": [], "methods": [ { "name": "authenticate", "args": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "Promise>", "typeParameters": [], "line": 10, "deprecated": false, "deprecationMessage": "", "modifierKind": [ 134 ], "jsdoctags": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "deprecated": false, "deprecationMessage": "", "description": "

Infrastructure: talks to the (mock) DigiD identity provider.

\n", "rawdescription": "\nInfrastructure: talks to the (mock) DigiD identity provider.", "sourceCode": "import { Injectable } from '@angular/core';\nimport { Result, ok, err } from '@shared/kernel/fp';\nimport { Session } from '../domain/session';\n\n/** Infrastructure: talks to the (mock) DigiD identity provider. */\n@Injectable({ providedIn: 'root' })\nexport class DigidAdapter {\n // ponytail: fake DigiD — any 9-digit BSN authenticates to a fixed identity.\n // Swap for a real OIDC redirect flow when there's a backend.\n async authenticate(bsn: string): Promise> {\n const t = bsn.trim();\n if (!/^\\d{9}$/.test(t)) return err('Voer een geldig BSN van 9 cijfers in.');\n return ok({ bsn: t, naam: 'Dr. A. (Anna) de Vries' });\n }\n}\n", "extends": [], "type": "injectable" }, { "name": "SessionStore", "id": "injectable-SessionStore-73a990a2a5a1c0f7177443b4e29c7af3da44fcbabcc4e6637486764225143283202ac5da0ee355ed30f829eab6f88a25f05dac7fce22d60cbf2dda7e0956b949", "file": "src/app/auth/application/session.store.ts", "properties": [ { "name": "_session", "defaultValue": "signal(null)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 15, "modifierKind": [ 123 ] }, { "name": "digid", "defaultValue": "inject(DigidAdapter)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 14, "modifierKind": [ 123 ] }, { "name": "isAuthenticated", "defaultValue": "computed(() => this._session() !== null)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 18, "modifierKind": [ 148 ] }, { "name": "session", "defaultValue": "this._session.asReadonly()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 17, "modifierKind": [ 148 ] } ], "methods": [ { "name": "login", "args": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "Promise>", "typeParameters": [], "line": 21, "deprecated": false, "deprecationMessage": "", "rawdescription": "\nEffectful command: authenticate, then store the session on success.", "description": "

Effectful command: authenticate, then store the session on success.

\n", "modifierKind": [ 134 ], "jsdoctags": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "logout", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 27, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "

Holds the current session for the whole app. Because it is providedIn:'root'\nthere is exactly one instance — every component that injects it sees the same\nsession signal, so logging in is instantly visible everywhere (the guard, the\nheader, etc.). ponytail: in-memory only; a refresh logs you out.

\n", "rawdescription": "\n\nHolds the current session for the whole app. Because it is providedIn:'root'\nthere is exactly one instance — every component that injects it sees the same\nsession signal, so logging in is instantly visible everywhere (the guard, the\nheader, etc.). ponytail: in-memory only; a refresh logs you out.\n", "sourceCode": "import { Injectable, computed, inject, signal } from '@angular/core';\nimport { Result } from '@shared/kernel/fp';\nimport { Session } from '../domain/session';\nimport { DigidAdapter } from '../infrastructure/digid.adapter';\n\n/**\n * Holds the current session for the whole app. Because it is providedIn:'root'\n * there is exactly one instance — every component that injects it sees the same\n * session signal, so logging in is instantly visible everywhere (the guard, the\n * header, etc.). ponytail: in-memory only; a refresh logs you out.\n */\n@Injectable({ providedIn: 'root' })\nexport class SessionStore {\n private digid = inject(DigidAdapter);\n private _session = signal(null);\n\n readonly session = this._session.asReadonly();\n readonly isAuthenticated = computed(() => this._session() !== null);\n\n /** Effectful command: authenticate, then store the session on success. */\n async login(bsn: string): Promise> {\n const r = await this.digid.authenticate(bsn);\n if (r.ok) this._session.set(r.value);\n return r;\n }\n\n logout() {\n this._session.set(null);\n }\n}\n", "extends": [], "type": "injectable" } ], "guards": [], "interceptors": [], "classes": [], "directives": [ { "name": "AsyncEmptyDirective", "id": "directive-AsyncEmptyDirective-b3cfb3c4a98444c42ba42c11d432aca9cf324dba35b23ccb8af26360530e37b4edcc64b110afd78fb4d7e4eef1b24c72be872007aaa92127f22e76e1ae7c0964", "file": "src/app/shared/ui/async/async.component.ts", "type": "directive", "description": "", "rawdescription": "\n", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put on children of . */\n@Directive({ selector: '[appAsyncLoaded]' })\nexport class AsyncLoadedDirective {\n constructor(public tpl: TemplateRef<{ $implicit: unknown }>) {}\n}\n@Directive({ selector: '[appAsyncLoading]' })\nexport class AsyncLoadingDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncEmpty]' })\nexport class AsyncEmptyDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncError]' })\nexport class AsyncErrorDirective {\n constructor(public tpl: TemplateRef<{ $implicit: Error | undefined; retry: () => void }>) {}\n}\n\n/**\n * Renders exactly ONE of loading / empty / error / loaded for a signal-based\n * resource (e.g. httpResource). Built on a RemoteData tagged union (see\n * core/remote-data.ts), so the states are mutually exclusive by construction —\n * the UI can never show two at once (\"impossible states\"). Unprovided slots\n * fall back to sensible defaults.\n */\n@Component({\n selector: 'app-async',\n imports: [NgTemplateOutlet, SpinnerComponent, AlertComponent, ButtonComponent],\n template: `\n @switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n }\n `,\n})\nexport class AsyncComponent {\n // Two ways to feed this component:\n // [resource] — a raw httpResource (the common case), or\n // [data] — an already-combined RemoteData (e.g. from a store via map2).\n resource = input>();\n data = input>();\n isEmpty = input<(v: T) => boolean>(() => false);\n\n loadedTpl = contentChild.required(AsyncLoadedDirective);\n loadingTpl = contentChild(AsyncLoadingDirective);\n emptyTpl = contentChild(AsyncEmptyDirective);\n errorTpl = contentChild(AsyncErrorDirective);\n\n // Single source of truth: the supplied RemoteData, or the resource projected into one.\n protected rd = computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n });\n\n // value/error are pulled out via the exhaustive fold — only Success carries a\n // value, only Failure carries an error, so these can't lie.\n protected value = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n );\n protected error = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n );\n\n retry = () => {\n const r = this.resource();\n if (r && 'reload' in r && typeof (r as { reload?: unknown }).reload === 'function') {\n (r as { reload: () => void }).reload();\n }\n };\n}\n\n/** Convenience: import this array to get the wrapper + all slot directives. */\nexport const ASYNC = [\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const;\n", "selector": "[appAsyncEmpty]", "providers": [], "hostDirectives": [], "standalone": false, "inputsClass": [], "outputsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "propertiesClass": [ { "name": "tpl", "deprecated": false, "deprecationMessage": "", "type": "TemplateRef", "indexKey": "", "optional": false, "description": "", "line": 20, "modifierKind": [ 125 ] } ], "methodsClass": [], "extends": [], "constructorObj": { "name": "constructor", "description": "", "deprecated": false, "deprecationMessage": "", "args": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "line": 19, "jsdoctags": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } }, { "name": "AsyncErrorDirective", "id": "directive-AsyncErrorDirective-b3cfb3c4a98444c42ba42c11d432aca9cf324dba35b23ccb8af26360530e37b4edcc64b110afd78fb4d7e4eef1b24c72be872007aaa92127f22e76e1ae7c0964", "file": "src/app/shared/ui/async/async.component.ts", "type": "directive", "description": "", "rawdescription": "\n", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put on children of . */\n@Directive({ selector: '[appAsyncLoaded]' })\nexport class AsyncLoadedDirective {\n constructor(public tpl: TemplateRef<{ $implicit: unknown }>) {}\n}\n@Directive({ selector: '[appAsyncLoading]' })\nexport class AsyncLoadingDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncEmpty]' })\nexport class AsyncEmptyDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncError]' })\nexport class AsyncErrorDirective {\n constructor(public tpl: TemplateRef<{ $implicit: Error | undefined; retry: () => void }>) {}\n}\n\n/**\n * Renders exactly ONE of loading / empty / error / loaded for a signal-based\n * resource (e.g. httpResource). Built on a RemoteData tagged union (see\n * core/remote-data.ts), so the states are mutually exclusive by construction —\n * the UI can never show two at once (\"impossible states\"). Unprovided slots\n * fall back to sensible defaults.\n */\n@Component({\n selector: 'app-async',\n imports: [NgTemplateOutlet, SpinnerComponent, AlertComponent, ButtonComponent],\n template: `\n @switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n }\n `,\n})\nexport class AsyncComponent {\n // Two ways to feed this component:\n // [resource] — a raw httpResource (the common case), or\n // [data] — an already-combined RemoteData (e.g. from a store via map2).\n resource = input>();\n data = input>();\n isEmpty = input<(v: T) => boolean>(() => false);\n\n loadedTpl = contentChild.required(AsyncLoadedDirective);\n loadingTpl = contentChild(AsyncLoadingDirective);\n emptyTpl = contentChild(AsyncEmptyDirective);\n errorTpl = contentChild(AsyncErrorDirective);\n\n // Single source of truth: the supplied RemoteData, or the resource projected into one.\n protected rd = computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n });\n\n // value/error are pulled out via the exhaustive fold — only Success carries a\n // value, only Failure carries an error, so these can't lie.\n protected value = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n );\n protected error = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n );\n\n retry = () => {\n const r = this.resource();\n if (r && 'reload' in r && typeof (r as { reload?: unknown }).reload === 'function') {\n (r as { reload: () => void }).reload();\n }\n };\n}\n\n/** Convenience: import this array to get the wrapper + all slot directives. */\nexport const ASYNC = [\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const;\n", "selector": "[appAsyncError]", "providers": [], "hostDirectives": [], "standalone": false, "inputsClass": [], "outputsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "propertiesClass": [ { "name": "tpl", "deprecated": false, "deprecationMessage": "", "type": "TemplateRef", "indexKey": "", "optional": false, "description": "", "line": 24, "modifierKind": [ 125 ] } ], "methodsClass": [], "extends": [], "constructorObj": { "name": "constructor", "description": "", "deprecated": false, "deprecationMessage": "", "args": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "line": 23, "jsdoctags": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } }, { "name": "AsyncLoadedDirective", "id": "directive-AsyncLoadedDirective-b3cfb3c4a98444c42ba42c11d432aca9cf324dba35b23ccb8af26360530e37b4edcc64b110afd78fb4d7e4eef1b24c72be872007aaa92127f22e76e1ae7c0964", "file": "src/app/shared/ui/async/async.component.ts", "type": "directive", "description": "", "rawdescription": "\n", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put on children of . */\n@Directive({ selector: '[appAsyncLoaded]' })\nexport class AsyncLoadedDirective {\n constructor(public tpl: TemplateRef<{ $implicit: unknown }>) {}\n}\n@Directive({ selector: '[appAsyncLoading]' })\nexport class AsyncLoadingDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncEmpty]' })\nexport class AsyncEmptyDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncError]' })\nexport class AsyncErrorDirective {\n constructor(public tpl: TemplateRef<{ $implicit: Error | undefined; retry: () => void }>) {}\n}\n\n/**\n * Renders exactly ONE of loading / empty / error / loaded for a signal-based\n * resource (e.g. httpResource). Built on a RemoteData tagged union (see\n * core/remote-data.ts), so the states are mutually exclusive by construction —\n * the UI can never show two at once (\"impossible states\"). Unprovided slots\n * fall back to sensible defaults.\n */\n@Component({\n selector: 'app-async',\n imports: [NgTemplateOutlet, SpinnerComponent, AlertComponent, ButtonComponent],\n template: `\n @switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n }\n `,\n})\nexport class AsyncComponent {\n // Two ways to feed this component:\n // [resource] — a raw httpResource (the common case), or\n // [data] — an already-combined RemoteData (e.g. from a store via map2).\n resource = input>();\n data = input>();\n isEmpty = input<(v: T) => boolean>(() => false);\n\n loadedTpl = contentChild.required(AsyncLoadedDirective);\n loadingTpl = contentChild(AsyncLoadingDirective);\n emptyTpl = contentChild(AsyncEmptyDirective);\n errorTpl = contentChild(AsyncErrorDirective);\n\n // Single source of truth: the supplied RemoteData, or the resource projected into one.\n protected rd = computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n });\n\n // value/error are pulled out via the exhaustive fold — only Success carries a\n // value, only Failure carries an error, so these can't lie.\n protected value = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n );\n protected error = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n );\n\n retry = () => {\n const r = this.resource();\n if (r && 'reload' in r && typeof (r as { reload?: unknown }).reload === 'function') {\n (r as { reload: () => void }).reload();\n }\n };\n}\n\n/** Convenience: import this array to get the wrapper + all slot directives. */\nexport const ASYNC = [\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const;\n", "selector": "[appAsyncLoaded]", "providers": [], "hostDirectives": [], "standalone": false, "inputsClass": [], "outputsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "propertiesClass": [ { "name": "tpl", "deprecated": false, "deprecationMessage": "", "type": "TemplateRef", "indexKey": "", "optional": false, "description": "", "line": 12, "modifierKind": [ 125 ] } ], "methodsClass": [], "extends": [], "constructorObj": { "name": "constructor", "description": "", "deprecated": false, "deprecationMessage": "", "args": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "line": 11, "jsdoctags": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } }, { "name": "AsyncLoadingDirective", "id": "directive-AsyncLoadingDirective-b3cfb3c4a98444c42ba42c11d432aca9cf324dba35b23ccb8af26360530e37b4edcc64b110afd78fb4d7e4eef1b24c72be872007aaa92127f22e76e1ae7c0964", "file": "src/app/shared/ui/async/async.component.ts", "type": "directive", "description": "", "rawdescription": "\n", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put on children of . */\n@Directive({ selector: '[appAsyncLoaded]' })\nexport class AsyncLoadedDirective {\n constructor(public tpl: TemplateRef<{ $implicit: unknown }>) {}\n}\n@Directive({ selector: '[appAsyncLoading]' })\nexport class AsyncLoadingDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncEmpty]' })\nexport class AsyncEmptyDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncError]' })\nexport class AsyncErrorDirective {\n constructor(public tpl: TemplateRef<{ $implicit: Error | undefined; retry: () => void }>) {}\n}\n\n/**\n * Renders exactly ONE of loading / empty / error / loaded for a signal-based\n * resource (e.g. httpResource). Built on a RemoteData tagged union (see\n * core/remote-data.ts), so the states are mutually exclusive by construction —\n * the UI can never show two at once (\"impossible states\"). Unprovided slots\n * fall back to sensible defaults.\n */\n@Component({\n selector: 'app-async',\n imports: [NgTemplateOutlet, SpinnerComponent, AlertComponent, ButtonComponent],\n template: `\n @switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n }\n `,\n})\nexport class AsyncComponent {\n // Two ways to feed this component:\n // [resource] — a raw httpResource (the common case), or\n // [data] — an already-combined RemoteData (e.g. from a store via map2).\n resource = input>();\n data = input>();\n isEmpty = input<(v: T) => boolean>(() => false);\n\n loadedTpl = contentChild.required(AsyncLoadedDirective);\n loadingTpl = contentChild(AsyncLoadingDirective);\n emptyTpl = contentChild(AsyncEmptyDirective);\n errorTpl = contentChild(AsyncErrorDirective);\n\n // Single source of truth: the supplied RemoteData, or the resource projected into one.\n protected rd = computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n });\n\n // value/error are pulled out via the exhaustive fold — only Success carries a\n // value, only Failure carries an error, so these can't lie.\n protected value = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n );\n protected error = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n );\n\n retry = () => {\n const r = this.resource();\n if (r && 'reload' in r && typeof (r as { reload?: unknown }).reload === 'function') {\n (r as { reload: () => void }).reload();\n }\n };\n}\n\n/** Convenience: import this array to get the wrapper + all slot directives. */\nexport const ASYNC = [\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const;\n", "selector": "[appAsyncLoading]", "providers": [], "hostDirectives": [], "standalone": false, "inputsClass": [], "outputsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "propertiesClass": [ { "name": "tpl", "deprecated": false, "deprecationMessage": "", "type": "TemplateRef", "indexKey": "", "optional": false, "description": "", "line": 16, "modifierKind": [ 125 ] } ], "methodsClass": [], "extends": [], "constructorObj": { "name": "constructor", "description": "", "deprecated": false, "deprecationMessage": "", "args": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "line": 15, "jsdoctags": [ { "name": "tpl", "type": "TemplateRef", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } } ], "components": [ { "name": "AlertComponent", "id": "component-AlertComponent-7d03ee2c0179c2f8d44795112c823951406810027571b5471bc765873f1aeaee550dcb89c6ebd8514ee36f2d96c8c6ba118293bf44a4a1316f61e91fa3c06f4e", "file": "src/app/shared/ui/alert/alert.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-alert", "styleUrls": [], "styles": [], "template": "\n \n\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "type", "defaultValue": "'info'", "deprecated": false, "deprecationMessage": "", "type": "AlertType", "indexKey": "", "optional": false, "description": "", "line": 21, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: alert/message banner.

\n", "rawdescription": "\nAtom: alert/message banner.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\ntype AlertType = 'info' | 'ok' | 'warning' | 'error';\n\n/** Atom: alert/message banner. */\n@Component({\n selector: 'app-alert',\n template: `\n \n \n \n `,\n})\nexport class AlertComponent {\n type = input('info');\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "App", "id": "component-App-a5889755e6aaa6ebd2f471f1253c27e411d38a42361e18619621ef0e6c5a91de3cf6ba4ace13bbe1756691f1f5e80728717fd18aab2cef50180bd579fa218a6d", "file": "src/app/app.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-root", "styleUrls": [], "styles": [], "template": "", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "RouterOutlet" } ], "description": "", "rawdescription": "\n", "type": "component", "sourceCode": "import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n imports: [RouterOutlet],\n template: '',\n})\nexport class App {}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "AsyncComponent", "id": "component-AsyncComponent-b3cfb3c4a98444c42ba42c11d432aca9cf324dba35b23ccb8af26360530e37b4edcc64b110afd78fb4d7e4eef1b24c72be872007aaa92127f22e76e1ae7c0964", "file": "src/app/shared/ui/async/async.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-async", "styleUrls": [], "styles": [], "template": "@switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n}\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "data", "deprecated": false, "deprecationMessage": "", "type": "RemoteData", "indexKey": "", "optional": false, "description": "", "line": 70, "required": false }, { "name": "isEmpty", "defaultValue": "() => false", "deprecated": false, "deprecationMessage": "", "type": "(v: T) => boolean", "indexKey": "", "optional": false, "description": "", "line": 71, "required": false }, { "name": "resource", "deprecated": false, "deprecationMessage": "", "type": "Resource", "indexKey": "", "optional": false, "description": "", "line": 69, "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "emptyTpl", "defaultValue": "contentChild(AsyncEmptyDirective)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 75 }, { "name": "error", "defaultValue": "computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n )", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 91, "modifierKind": [ 124 ] }, { "name": "errorTpl", "defaultValue": "contentChild(AsyncErrorDirective)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 76 }, { "name": "loadedTpl", "defaultValue": "contentChild.required(AsyncLoadedDirective)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 73 }, { "name": "loadingTpl", "defaultValue": "contentChild(AsyncLoadingDirective)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 74 }, { "name": "rd", "defaultValue": "computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n })", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 79, "modifierKind": [ 124 ] }, { "name": "retry", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 95 }, { "name": "value", "defaultValue": "computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n )", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 88, "modifierKind": [ 124 ] } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "NgTemplateOutlet" }, { "name": "SpinnerComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" } ], "description": "

Renders exactly ONE of loading / empty / error / loaded for a signal-based\nresource (e.g. httpResource). Built on a RemoteData tagged union (see\ncore/remote-data.ts), so the states are mutually exclusive by construction —\nthe UI can never show two at once ("impossible states"). Unprovided slots\nfall back to sensible defaults.

\n", "rawdescription": "\n\nRenders exactly ONE of loading / empty / error / loaded for a signal-based\nresource (e.g. httpResource). Built on a RemoteData tagged union (see\ncore/remote-data.ts), so the states are mutually exclusive by construction —\nthe UI can never show two at once (\"impossible states\"). Unprovided slots\nfall back to sensible defaults.\n", "type": "component", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put on children of . */\n@Directive({ selector: '[appAsyncLoaded]' })\nexport class AsyncLoadedDirective {\n constructor(public tpl: TemplateRef<{ $implicit: unknown }>) {}\n}\n@Directive({ selector: '[appAsyncLoading]' })\nexport class AsyncLoadingDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncEmpty]' })\nexport class AsyncEmptyDirective {\n constructor(public tpl: TemplateRef) {}\n}\n@Directive({ selector: '[appAsyncError]' })\nexport class AsyncErrorDirective {\n constructor(public tpl: TemplateRef<{ $implicit: Error | undefined; retry: () => void }>) {}\n}\n\n/**\n * Renders exactly ONE of loading / empty / error / loaded for a signal-based\n * resource (e.g. httpResource). Built on a RemoteData tagged union (see\n * core/remote-data.ts), so the states are mutually exclusive by construction —\n * the UI can never show two at once (\"impossible states\"). Unprovided slots\n * fall back to sensible defaults.\n */\n@Component({\n selector: 'app-async',\n imports: [NgTemplateOutlet, SpinnerComponent, AlertComponent, ButtonComponent],\n template: `\n @switch (rd().tag) {\n @case ('Loading') {\n @if (loadingTpl()) { }\n @else { }\n }\n @case ('Failure') {\n @if (errorTpl()) {\n \n } @else {\n Er ging iets mis bij het laden van de gegevens.\n
\n Opnieuw proberen\n
\n }\n }\n @case ('Empty') {\n @if (emptyTpl()) { }\n @else {

Geen gegevens gevonden.

}\n }\n @case ('Success') {\n \n }\n }\n `,\n})\nexport class AsyncComponent {\n // Two ways to feed this component:\n // [resource] — a raw httpResource (the common case), or\n // [data] — an already-combined RemoteData (e.g. from a store via map2).\n resource = input>();\n data = input>();\n isEmpty = input<(v: T) => boolean>(() => false);\n\n loadedTpl = contentChild.required(AsyncLoadedDirective);\n loadingTpl = contentChild(AsyncLoadingDirective);\n emptyTpl = contentChild(AsyncEmptyDirective);\n errorTpl = contentChild(AsyncErrorDirective);\n\n // Single source of truth: the supplied RemoteData, or the resource projected into one.\n protected rd = computed>(() => {\n const data = this.data();\n if (data) return data;\n const r = this.resource();\n return r ? fromResource(r, this.isEmpty()) : { tag: 'Loading' };\n });\n\n // value/error are pulled out via the exhaustive fold — only Success carries a\n // value, only Failure carries an error, so these can't lie.\n protected value = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: () => undefined, success: (v) => v }),\n );\n protected error = computed(() =>\n foldRemote(this.rd(), { loading: () => undefined, empty: () => undefined, failure: (e) => e, success: () => undefined }),\n );\n\n retry = () => {\n const r = this.resource();\n if (r && 'reload' in r && typeof (r as { reload?: unknown }).reload === 'function') {\n (r as { reload: () => void }).reload();\n }\n };\n}\n\n/** Convenience: import this array to get the wrapper + all slot directives. */\nexport const ASYNC = [\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const;\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "ButtonComponent", "id": "component-ButtonComponent-6eb936521438d91cc3a2276d1b8e366496e907e8a01d7b84b327c3cc31fa1dfadbb9502c6646472736722cf7ced9950fcaa4d8435ddf28224b3e7c9b7bd29505", "file": "src/app/shared/ui/button/button.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-button", "styleUrls": [], "styles": [], "template": "\n \n\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "disabled", "defaultValue": "false", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 25, "required": false }, { "name": "type", "defaultValue": "'button'", "deprecated": false, "deprecationMessage": "", "type": "\"button\" | \"submit\"", "indexKey": "", "optional": false, "description": "", "line": 24, "required": false }, { "name": "variant", "defaultValue": "'primary'", "deprecated": false, "deprecationMessage": "", "type": "Variant", "indexKey": "", "optional": false, "description": "", "line": 23, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: button. Thin wrapper over the Utrecht/RHC button CSS.

\n", "rawdescription": "\nAtom: button. Thin wrapper over the Utrecht/RHC button CSS.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\ntype Variant = 'primary' | 'secondary' | 'subtle' | 'danger';\n\n/** Atom: button. Thin wrapper over the Utrecht/RHC button CSS. */\n@Component({\n selector: 'app-button',\n template: `\n \n \n \n `,\n})\nexport class ButtonComponent {\n variant = input('primary');\n type = input<'button' | 'submit'>('button');\n disabled = input(false);\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "ChangeRequestFormComponent", "id": "component-ChangeRequestFormComponent-8d79b6a9ce75f62f4e04f9d3ed0867e00d005c9c05cf267503536c4eec9813372aff51a3c8686927fd07f46503b60ddb4107edcc5f57fdfa1b6b52fe2a98026c", "file": "src/app/registratie/ui/change-request-form/change-request-form.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-change-request-form", "styleUrls": [], "styles": [], "template": "Adreswijziging doorgeven\n
\n \n \n \n \n \n \n \n \n \n
\n Wijziging indienen\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [ { "name": "submitted", "deprecated": false, "deprecationMessage": "", "type": "ChangeRequest", "indexKey": "", "optional": false, "description": "", "line": 47, "required": false } ], "propertiesClass": [ { "name": "city", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 44 }, { "name": "street", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 42 }, { "name": "streetError", "defaultValue": "signal('')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 45 }, { "name": "zip", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 43 }, { "name": "zipError", "defaultValue": "signal('')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 46 } ], "methodsClass": [ { "name": "onSubmit", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 49, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "FormFieldComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" }, { "name": "HeadingComponent", "type": "component" } ], "description": "

Organism: change-request (adreswijziging) form. Reuses the same form-field\nmolecule + text-input/button atoms as the login form. Field errors come\nstraight from the parser's Result — no parallel "is it valid" flag to drift.

\n", "rawdescription": "\nOrganism: change-request (adreswijziging) form. Reuses the same form-field\nmolecule + text-input/button atoms as the login form. Field errors come\nstraight from the parser's Result — no parallel \"is it valid\" flag to drift.", "type": "component", "sourceCode": "import { Component, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { Postcode, parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** A submitted change request carries a *parsed* postcode (branded Postcode),\n not a raw string — downstream code can't receive an unvalidated one. */\nexport interface ChangeRequest {\n street: string;\n zip: Postcode;\n city: string;\n}\n\n/** Organism: change-request (adreswijziging) form. Reuses the same form-field\n molecule + text-input/button atoms as the login form. Field errors come\n straight from the parser's Result — no parallel \"is it valid\" flag to drift. */\n@Component({\n selector: 'app-change-request-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent, HeadingComponent],\n template: `\n Adreswijziging doorgeven\n
\n \n \n \n \n \n \n \n \n \n
\n Wijziging indienen\n
\n
\n `,\n})\nexport class ChangeRequestFormComponent {\n street = '';\n zip = '';\n city = '';\n streetError = signal('');\n zipError = signal('');\n submitted = output();\n\n onSubmit() {\n const street = this.street.trim();\n this.streetError.set(street ? '' : 'Vul straat en huisnummer in.');\n\n const postcode = parsePostcode(this.zip);\n this.zipError.set(postcode.ok ? '' : postcode.error);\n\n if (!street || !postcode.ok) return;\n this.submitted.emit({ street, zip: postcode.value, city: this.city.trim() });\n }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "ConceptsPage", "id": "component-ConceptsPage-951fb54ea356331be584db1248fbc5d516618c3b5b9f960359a4a642e7d9ce7d4d240852a31bbbcfea0e0bec6c0feeb398ae79c181480422a7477c3b600c88a5", "file": "src/app/showcase/concepts.page.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-concepts-page", "styleUrls": [], "styles": [ "\n .cols { display:flex; flex-wrap:wrap; gap:1.5rem; margin:1rem 0 2.5rem }\n .col { flex:1 1 20rem; min-width:18rem }\n .tag { font-weight:700; font-size:0.8rem; text-transform:uppercase; letter-spacing:0.04em }\n .bad { color:var(--rhc-color-rood-500) }\n .good { color:var(--rhc-color-groen-500) }\n pre { background:var(--rhc-color-grijs-100,#f3f3f3); padding:1rem; border-radius:4px; overflow:auto; font-size:0.85rem }\n " ], "template": "\n \n Vier functionele patronen die met atomic design makkelijker te tonen zijn — telkens \"fout\"\n (de oude vorm liet het toe) naast \"goed\" (het type maakt het onmogelijk).\n \n\n \n 1 · Discriminated unions\n
\n
\n

Fout — vlakke interface

\n
{{ unionBad }}
\n

Een doorgehaalde registratie houdt tóch een herregistratiedatum: onmogelijke toestand.

\n
\n
\n

Goed — sum type

\n \n

De variant Doorgehaald kent geen herregistratiedatum, dus de rij bestaat simpelweg niet.

\n
\n
\n\n \n 2 · RemoteData fold\n
\n
\n

Eén molecuul, vier elkaar uitsluitende toestanden

\n

Loading

\n {{ v }}\n

Empty

\n {{ v }}\n

Failure

\n {{ v }}\n

Success

\n
    @for (i of v; track i) {
  • {{ i }}
  • }
\n
\n
\n

De exhaustieve fold

\n
{{ foldCode }}
\n

Een nieuwe variant toevoegen breekt de compile via assertNever tot je hem afhandelt.

\n
\n
\n\n \n 3 · Parse, don't validate\n
\n
\n

Smart constructor → Result

\n \n
\n
\n @if (parsed().ok) {\n

ok

\n
Postcode = \"{{ parsed().ok ? $any(parsed()).value : '' }}\"
\n

Een gevalideerde Postcode is een ander type dan een ruwe string.

\n } @else {\n

err

\n
{{ $any(parsed()).error }}
\n }\n
\n
\n\n \n 4 · Form als state machine\n
\n
\n

Fout — losse booleans

\n
{{ machineBad }}
\n

Niets verhindert \"submitting\" mét validatiefouten of een successcherm met errors.

\n
\n
\n

Goed — één tagged union stuurt de UI

\n \n
\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [ { "name": "doorgehaald", "defaultValue": "{\n bigNummer: '19012345601', naam: 'Dr. A. (Anna) de Vries', beroep: 'Arts',\n registratiedatum: '2012-09-01', geboortedatum: '1985-03-14',\n status: { tag: 'Doorgehaald', doorgehaaldOp: '2024-05-01', reden: 'Op eigen verzoek' },\n }", "deprecated": false, "deprecationMessage": "", "type": "Registration", "indexKey": "", "optional": false, "description": "", "line": 117 }, { "name": "emptyRes", "defaultValue": "fakeResource('resolved', [])", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 124 }, { "name": "errorRes", "defaultValue": "fakeResource('error', undefined, new Error('Demo'))", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 125 }, { "name": "foldCode", "defaultValue": "`foldRemote(rd, {\n loading: () => spinner,\n empty: () => 'geen data',\n failure: (e) => alert(e),\n success: (v) => render(v),\n}); // mist er één → compile-fout`", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 136 }, { "name": "isEmpty", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 115 }, { "name": "loadingRes", "defaultValue": "fakeResource('loading')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 123 }, { "name": "machineBad", "defaultValue": "`submitting = signal(false);\nsubmitted = signal(false);\nerrors = signal<...>({});\n// submitting === true && errors.size > 0 ? 🤷`", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 143 }, { "name": "parsed", "defaultValue": "computed(() => parsePostcode(this.raw()))", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 129 }, { "name": "raw", "defaultValue": "signal('')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 128 }, { "name": "successRes", "defaultValue": "fakeResource('resolved', ['Huisartsgeneeskunde', 'Spoedeisende hulp'])", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 126 }, { "name": "unionBad", "defaultValue": "`interface Registration {\n status: 'Geregistreerd' | 'Doorgehaald';\n herregistratieDatum: string; // altijd aanwezig 😬\n}`", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 131 } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "PageShellComponent", "type": "component" }, { "name": "HeadingComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "ASYNC" }, { "name": "SkeletonComponent", "type": "component" }, { "name": "RegistrationSummaryComponent", "type": "component" }, { "name": "HerregistratieWizardComponent", "type": "component" } ], "description": "

Teaching showcase: each section pairs the impossible-state-permitting "before"\nwith the "after" where the type system rules it out. Composition-only.

\n", "rawdescription": "\nTeaching showcase: each section pairs the impossible-state-permitting \"before\"\nwith the \"after\" where the type system rules it out. Composition-only.", "type": "component", "sourceCode": "import { Component, computed, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport type { Resource } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';\nimport { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';\nimport { HerregistratieWizardComponent } from '@herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component';\nimport { Registration } from '@registratie/domain/registration';\nimport { parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** Minimal fake Resource so can be driven through every state without HTTP. */\nfunction fakeResource(status: string, value?: T, error?: Error): Resource {\n return { value: () => value as T, status: () => status, error: () => error, hasValue: () => value !== undefined, reload: () => {} } as unknown as Resource;\n}\n\n/** Teaching showcase: each section pairs the impossible-state-permitting \"before\"\n with the \"after\" where the type system rules it out. Composition-only. */\n@Component({\n selector: 'app-concepts-page',\n imports: [\n FormsModule, PageShellComponent, HeadingComponent, AlertComponent, TextInputComponent,\n ...ASYNC, SkeletonComponent, RegistrationSummaryComponent, HerregistratieWizardComponent,\n ],\n styles: [`\n .cols { display:flex; flex-wrap:wrap; gap:1.5rem; margin:1rem 0 2.5rem }\n .col { flex:1 1 20rem; min-width:18rem }\n .tag { font-weight:700; font-size:0.8rem; text-transform:uppercase; letter-spacing:0.04em }\n .bad { color:var(--rhc-color-rood-500) }\n .good { color:var(--rhc-color-groen-500) }\n pre { background:var(--rhc-color-grijs-100,#f3f3f3); padding:1rem; border-radius:4px; overflow:auto; font-size:0.85rem }\n `],\n template: `\n \n \n Vier functionele patronen die met atomic design makkelijker te tonen zijn — telkens \"fout\"\n (de oude vorm liet het toe) naast \"goed\" (het type maakt het onmogelijk).\n \n\n \n 1 · Discriminated unions\n
\n
\n

Fout — vlakke interface

\n
{{ unionBad }}
\n

Een doorgehaalde registratie houdt tóch een herregistratiedatum: onmogelijke toestand.

\n
\n
\n

Goed — sum type

\n \n

De variant Doorgehaald kent geen herregistratiedatum, dus de rij bestaat simpelweg niet.

\n
\n
\n\n \n 2 · RemoteData fold\n
\n
\n

Eén molecuul, vier elkaar uitsluitende toestanden

\n

Loading

\n {{ v }}\n

Empty

\n {{ v }}\n

Failure

\n {{ v }}\n

Success

\n
    @for (i of v; track i) {
  • {{ i }}
  • }
\n
\n
\n

De exhaustieve fold

\n
{{ foldCode }}
\n

Een nieuwe variant toevoegen breekt de compile via assertNever tot je hem afhandelt.

\n
\n
\n\n \n 3 · Parse, don't validate\n
\n
\n

Smart constructor → Result

\n \n
\n
\n @if (parsed().ok) {\n

ok

\n
Postcode = \"{{ parsed().ok ? $any(parsed()).value : '' }}\"
\n

Een gevalideerde Postcode is een ander type dan een ruwe string.

\n } @else {\n

err

\n
{{ $any(parsed()).error }}
\n }\n
\n
\n\n \n 4 · Form als state machine\n
\n
\n

Fout — losse booleans

\n
{{ machineBad }}
\n

Niets verhindert \"submitting\" mét validatiefouten of een successcherm met errors.

\n
\n
\n

Goed — één tagged union stuurt de UI

\n \n
\n
\n
\n `,\n})\nexport class ConceptsPage {\n isEmpty = (v: string[]) => !v || v.length === 0;\n\n doorgehaald: Registration = {\n bigNummer: '19012345601', naam: 'Dr. A. (Anna) de Vries', beroep: 'Arts',\n registratiedatum: '2012-09-01', geboortedatum: '1985-03-14',\n status: { tag: 'Doorgehaald', doorgehaaldOp: '2024-05-01', reden: 'Op eigen verzoek' },\n };\n\n loadingRes = fakeResource('loading');\n emptyRes = fakeResource('resolved', []);\n errorRes = fakeResource('error', undefined, new Error('Demo'));\n successRes = fakeResource('resolved', ['Huisartsgeneeskunde', 'Spoedeisende hulp']);\n\n raw = signal('');\n parsed = computed(() => parsePostcode(this.raw()));\n\n unionBad = `interface Registration {\n status: 'Geregistreerd' | 'Doorgehaald';\n herregistratieDatum: string; // altijd aanwezig 😬\n}`;\n\n foldCode = `foldRemote(rd, {\n loading: () => spinner,\n empty: () => 'geen data',\n failure: (e) => alert(e),\n success: (v) => render(v),\n}); // mist er één → compile-fout`;\n\n machineBad = `submitting = signal(false);\nsubmitted = signal(false);\nerrors = signal<...>({});\n// submitting === true && errors.size > 0 ? 🤷`;\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "\n .cols { display:flex; flex-wrap:wrap; gap:1.5rem; margin:1rem 0 2.5rem }\n .col { flex:1 1 20rem; min-width:18rem }\n .tag { font-weight:700; font-size:0.8rem; text-transform:uppercase; letter-spacing:0.04em }\n .bad { color:var(--rhc-color-rood-500) }\n .good { color:var(--rhc-color-groen-500) }\n pre { background:var(--rhc-color-grijs-100,#f3f3f3); padding:1rem; border-radius:4px; overflow:auto; font-size:0.85rem }\n \n", "extends": [] }, { "name": "DashboardPage", "id": "component-DashboardPage-3876b122573c06608aa1fa82196e04af53fa3720906e138b095aa46a13efbd18be0b42e0a6024ee8df168faecfbf50c6a9ad9a5a7afff5447fec52dcafc73d49", "file": "src/app/registratie/ui/dashboard.page.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-dashboard-page", "styleUrls": [], "styles": [], "template": "\n @if (store.pendingHerregistratie()) {\n Uw herregistratie-aanvraag is in behandeling.\n }\n\n \n \n \n \n
\n Persoonsgegevens (BRP)\n
\n \n \n \n
\n
\n
\n \n \n \n
\n\n
\n Specialismen en aantekeningen\n \n \n \n \n \n \n \n \n

U heeft nog geen specialismen of aantekeningen.

\n
\n
\n
\n\n

\n Gegevens bekijken of een wijziging doorgeven →\n

\n

\n Herregistratie aanvragen →\n

\n

\n Functionele patronen (impossible states) →\n

\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [ { "name": "store", "defaultValue": "inject(BigProfileStore)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 71, "modifierKind": [ 124 ] } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "PageShellComponent", "type": "component" }, { "name": "HeadingComponent", "type": "component" }, { "name": "LinkComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "SkeletonComponent", "type": "component" }, { "name": "DataRowComponent", "type": "component" }, { "name": "ASYNC" }, { "name": "RegistrationSummaryComponent", "type": "component" }, { "name": "RegistrationTableComponent", "type": "component" } ], "description": "", "rawdescription": "\n", "type": "component", "sourceCode": "import { Component, inject } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { LinkComponent } from '@shared/ui/link/link.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';\nimport { DataRowComponent } from '@shared/ui/data-row/data-row.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';\nimport { RegistrationTableComponent } from '@registratie/ui/registration-table/registration-table.component';\nimport { BigProfileStore } from '@registratie/application/big-profile.store';\n\n@Component({\n selector: 'app-dashboard-page',\n imports: [\n PageShellComponent, HeadingComponent, LinkComponent, AlertComponent, SkeletonComponent,\n DataRowComponent, ...ASYNC, RegistrationSummaryComponent, RegistrationTableComponent,\n ],\n template: `\n \n @if (store.pendingHerregistratie()) {\n Uw herregistratie-aanvraag is in behandeling.\n }\n\n \n \n \n \n
\n Persoonsgegevens (BRP)\n
\n \n \n \n
\n
\n
\n \n \n \n
\n\n
\n Specialismen en aantekeningen\n \n \n \n \n \n \n \n \n

U heeft nog geen specialismen of aantekeningen.

\n
\n
\n
\n\n

\n Gegevens bekijken of een wijziging doorgeven →\n

\n

\n Herregistratie aanvragen →\n

\n

\n Functionele patronen (impossible states) →\n

\n
\n `,\n})\nexport class DashboardPage {\n protected store = inject(BigProfileStore);\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "DataRowComponent", "id": "component-DataRowComponent-bf012e0b5e277c5c6d53311a7649373316677ab4f6d5ba0b313f5eaeb5a061ea55cb08b0af237c487dcc3be5b15014d5c2b21b6f6903ff7689881fc8607eb1b2", "file": "src/app/shared/ui/data-row/data-row.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-data-row", "styleUrls": [], "styles": [], "template": "
\n
{{ key() }}
\n
{{ value() }}
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "key", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 15, "required": true }, { "name": "value", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string | null", "indexKey": "", "optional": false, "description": "", "line": 16, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Molecule: one key/value row inside an RHC data-summary.\nWrap several of these in .rhc-data-summary (see registration-summary).

\n", "rawdescription": "\nMolecule: one key/value row inside an RHC data-summary.\nWrap several of these in .rhc-data-summary (see registration-summary).", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Molecule: one key/value row inside an RHC data-summary.\n Wrap several of these in .rhc-data-summary (see registration-summary). */\n@Component({\n selector: 'app-data-row',\n template: `\n
\n
{{ key() }}
\n
{{ value() }}
\n
\n `,\n})\nexport class DataRowComponent {\n key = input.required();\n value = input('');\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "FormFieldComponent", "id": "component-FormFieldComponent-9f7fb7fac967056161f8440bccbd87825bc2897463f63a612a12ac6154cfaa4e17a2a6469fbe936deba74319ac6029c6aa024abfc07095b226f5980e654cb12c", "file": "src/app/shared/ui/form-field/form-field.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-form-field", "styleUrls": [], "styles": [], "template": "
\n \n @if (description()) {\n
{{ description() }}
\n }\n \n @if (error()) {\n
{{ error() }}
\n }\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "description", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 23, "required": false }, { "name": "error", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 24, "required": false }, { "name": "fieldId", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 22, "required": true }, { "name": "label", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 21, "required": true } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Molecule: form field = label + projected control + optional error/description.\nReused by both the login form and the change-request form.

\n", "rawdescription": "\nMolecule: form field = label + projected control + optional error/description.\nReused by both the login form and the change-request form.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Molecule: form field = label + projected control + optional error/description.\n Reused by both the login form and the change-request form. */\n@Component({\n selector: 'app-form-field',\n template: `\n
\n \n @if (description()) {\n
{{ description() }}
\n }\n \n @if (error()) {\n
{{ error() }}
\n }\n
\n `,\n})\nexport class FormFieldComponent {\n label = input.required();\n fieldId = input.required();\n description = input();\n error = input();\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "HeadingComponent", "id": "component-HeadingComponent-0f0b442fc9ccbfde8481137b728000bb093868ddc931f507bbd4a86ee528820cf4c6dab36a9a82b4a940bb96c2355f42bc34a94700acc7df3e7dfeea627be67c", "file": "src/app/shared/ui/heading/heading.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-heading", "styleUrls": [], "styles": [], "template": "\n@switch (level()) {\n @case (1) {

}\n @case (2) {

}\n @case (3) {

}\n @case (4) {

}\n @default {
}\n}\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "level", "defaultValue": "2", "deprecated": false, "deprecationMessage": "", "type": "1 | 2 | 3 | 4 | 5", "indexKey": "", "optional": false, "description": "", "line": 22, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "NgTemplateOutlet" } ], "description": "

Atom: heading. Renders the right h1..h5 with RHC heading styling.\nSingle captured in a template — multiple ng-content across

\n", "rawdescription": "\nAtom: heading. Renders the right h1..h5 with RHC heading styling.\nSingle captured in a template — multiple ng-content across", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/** Atom: heading. Renders the right h1..h5 with RHC heading styling.\n Single captured in a template — multiple ng-content across\n @switch branches silently drops the projected content. */\n@Component({\n selector: 'app-heading',\n imports: [NgTemplateOutlet],\n template: `\n \n @switch (level()) {\n @case (1) {

}\n @case (2) {

}\n @case (3) {

}\n @case (4) {

}\n @default {
}\n }\n `,\n})\nexport class HeadingComponent {\n level = input<1 | 2 | 3 | 4 | 5>(2);\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "HerregistratiePage", "id": "component-HerregistratiePage-320bc6fae5182789d36effc63292c612ce5b125b9cf1bb77b7bdc1be837ca444255723e8a2a48eb9abcada973007eec4badbaf82e60644b869c5d66ffd68d97d", "file": "src/app/herregistratie/ui/herregistratie.page.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-herregistratie-page", "styleUrls": [], "styles": [], "template": "\n \n \n @if (eligible) {\n \n Uw huidige registratie verloopt binnenkort. Vraag tijdig herregistratie aan.\n \n
\n \n
\n } @else {\n \n Voor uw huidige registratiestatus is herregistratie niet mogelijk.\n \n }\n
\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [ { "name": "eligibility", "defaultValue": "computed(() =>\n map(this.store.profile(), (p) => isHerregistratieEligible(p.registration, new Date())),\n )", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 39, "modifierKind": [ 124 ] }, { "name": "store", "defaultValue": "inject(BigProfileStore)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 37, "modifierKind": [ 123 ] } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "PageShellComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "ASYNC" }, { "name": "HerregistratieWizardComponent", "type": "component" } ], "description": "

A whole new page built from existing building blocks. Eligibility is a pure\ndomain rule (registration.policy) read from the shared profile state.

\n", "rawdescription": "\nA whole new page built from existing building blocks. Eligibility is a pure\ndomain rule (registration.policy) read from the shared profile state.", "type": "component", "sourceCode": "import { Component, computed, inject } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { map } from '@shared/application/remote-data';\nimport { BigProfileStore } from '@registratie/application/big-profile.store';\nimport { isHerregistratieEligible } from '@registratie/domain/registration.policy';\nimport { HerregistratieWizardComponent } from '@herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component';\n\n/** A whole new page built from existing building blocks. Eligibility is a pure\n domain rule (registration.policy) read from the shared profile state. */\n@Component({\n selector: 'app-herregistratie-page',\n imports: [PageShellComponent, AlertComponent, ...ASYNC, HerregistratieWizardComponent],\n template: `\n \n \n \n @if (eligible) {\n \n Uw huidige registratie verloopt binnenkort. Vraag tijdig herregistratie aan.\n \n
\n \n
\n } @else {\n \n Voor uw huidige registratiestatus is herregistratie niet mogelijk.\n \n }\n
\n
\n
\n `,\n})\nexport class HerregistratiePage {\n private store = inject(BigProfileStore);\n // Derive a boolean RemoteData from the combined profile via map (pure).\n protected eligibility = computed(() =>\n map(this.store.profile(), (p) => isHerregistratieEligible(p.registration, new Date())),\n );\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "HerregistratieWizardComponent", "id": "component-HerregistratieWizardComponent-45976389894f1e7f8d41c6517df80210bfb72ce0c6d94a26e8efaea3128977466c34eab7a568b372079d6c5295253c988e2b3d96ffc7267e02a1160e75cef160", "file": "src/app/herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-herregistratie-wizard", "styleUrls": [], "styles": [], "template": "@switch (state().tag) {\n @case ('Editing') {\n

Stap {{ step() }} van 2

\n
\n @if (step() === 1) {\n \n \n \n Volgende\n } @else {\n \n \n \n
\n Vorige\n Herregistratie aanvragen\n
\n }\n
\n }\n @case ('Submitting') {\n Aanvraag wordt verwerkt…\n }\n @case ('Submitted') {\n Uw aanvraag tot herregistratie is ontvangen.\n }\n @case ('Failed') {\n Indienen mislukt: {{ failedError() }}\n
\n Opnieuw proberen\n
\n }\n}\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "seed", "defaultValue": "initial", "deprecated": false, "deprecationMessage": "", "type": "WizardState", "indexKey": "", "optional": false, "description": "

Optional seed so Storybook / the showcase can mount any state directly.

\n", "line": 65, "rawdescription": "\nOptional seed so Storybook / the showcase can mount any state directly.", "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "dispatch", "defaultValue": "this.store.dispatch", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 68, "modifierKind": [ 124 ] }, { "name": "draft", "defaultValue": "computed(() => this.editing()?.draft ?? { uren: '', punten: '' })", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 72, "modifierKind": [ 124 ] }, { "name": "editing", "defaultValue": "computed(() => (this.state().tag === 'Editing' ? (this.state() as Extract) : null))", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 70, "modifierKind": [ 123 ] }, { "name": "errPunten", "defaultValue": "computed(() => this.editing()?.errors.punten ?? '')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 74, "modifierKind": [ 124 ] }, { "name": "errUren", "defaultValue": "computed(() => this.editing()?.errors.uren ?? '')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 73, "modifierKind": [ 124 ] }, { "name": "failedError", "defaultValue": "computed(() => (this.state().tag === 'Failed' ? (this.state() as Extract).error : ''))", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 75, "modifierKind": [ 124 ] }, { "name": "profile", "defaultValue": "inject(BigProfileStore)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 61, "modifierKind": [ 123 ] }, { "name": "state", "defaultValue": "this.store.model", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 67, "modifierKind": [ 124 ] }, { "name": "step", "defaultValue": "computed(() => this.editing()?.step ?? 1)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 71, "modifierKind": [ 124 ] }, { "name": "store", "defaultValue": "createStore(initial, reduce)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 62, "modifierKind": [ 123 ] } ], "methodsClass": [ { "name": "onPrimary", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 81, "deprecated": false, "deprecationMessage": "" }, { "name": "onRetry", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 88, "deprecated": false, "deprecationMessage": "" }, { "name": "runIfSubmitting", "args": [], "optional": false, "returnType": "any", "typeParameters": [], "line": 95, "deprecated": false, "deprecationMessage": "", "rawdescription": "\nThe effect: when we entered Submitting, call the backend command, flip the\noptimistic cross-page flag, then dispatch the result (and commit/rollback).", "description": "

The effect: when we entered Submitting, call the backend command, flip the\noptimistic cross-page flag, then dispatch the result (and commit/rollback).

\n", "modifierKind": [ 123, 134 ] } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "FormFieldComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "SpinnerComponent", "type": "component" } ], "description": "

Organism: multi-step herregistratie wizard. ALL state lives in one signal\ndriven by the pure reduce function (see herregistratie.machine.ts) via an\nElm-style store. The UI just sends messages and folds over the state's tag —\nno booleans like submitting/submitted that could contradict each other.\nSubmitting also flips an optimistic flag on the shared BigProfileStore, so\nthe dashboard shows "in behandeling" immediately.

\n", "rawdescription": "\nOrganism: multi-step herregistratie wizard. ALL state lives in one signal\ndriven by the pure `reduce` function (see herregistratie.machine.ts) via an\nElm-style store. The UI just sends messages and folds over the state's tag —\nno booleans like `submitting`/`submitted` that could contradict each other.\nSubmitting also flips an optimistic flag on the shared BigProfileStore, so\nthe dashboard shows \"in behandeling\" immediately.", "type": "component", "sourceCode": "import { Component, computed, inject, input } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { createStore } from '@shared/application/store';\nimport { BigProfileStore } from '@registratie/application/big-profile.store';\nimport { WizardState, WizardMsg, Draft, initial, reduce } from '@herregistratie/domain/herregistratie.machine';\nimport { submitHerregistratie } from '@herregistratie/application/submit-herregistratie';\n\n/** Organism: multi-step herregistratie wizard. ALL state lives in one signal\n driven by the pure `reduce` function (see herregistratie.machine.ts) via an\n Elm-style store. The UI just sends messages and folds over the state's tag —\n no booleans like `submitting`/`submitted` that could contradict each other.\n Submitting also flips an optimistic flag on the shared BigProfileStore, so\n the dashboard shows \"in behandeling\" immediately. */\n@Component({\n selector: 'app-herregistratie-wizard',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent, AlertComponent, SpinnerComponent],\n template: `\n @switch (state().tag) {\n @case ('Editing') {\n

Stap {{ step() }} van 2

\n
\n @if (step() === 1) {\n \n \n \n Volgende\n } @else {\n \n \n \n
\n Vorige\n Herregistratie aanvragen\n
\n }\n
\n }\n @case ('Submitting') {\n Aanvraag wordt verwerkt…\n }\n @case ('Submitted') {\n Uw aanvraag tot herregistratie is ontvangen.\n }\n @case ('Failed') {\n Indienen mislukt: {{ failedError() }}\n
\n Opnieuw proberen\n
\n }\n }\n `,\n})\nexport class HerregistratieWizardComponent {\n private profile = inject(BigProfileStore);\n private store = createStore(initial, reduce);\n\n /** Optional seed so Storybook / the showcase can mount any state directly. */\n seed = input(initial);\n\n protected state = this.store.model;\n protected dispatch = this.store.dispatch;\n\n private editing = computed(() => (this.state().tag === 'Editing' ? (this.state() as Extract) : null));\n protected step = computed(() => this.editing()?.step ?? 1);\n protected draft = computed(() => this.editing()?.draft ?? { uren: '', punten: '' });\n protected errUren = computed(() => this.editing()?.errors.uren ?? '');\n protected errPunten = computed(() => this.editing()?.errors.punten ?? '');\n protected failedError = computed(() => (this.state().tag === 'Failed' ? (this.state() as Extract).error : ''));\n\n constructor() {\n queueMicrotask(() => this.dispatch({ tag: 'Seed', state: this.seed() }));\n }\n\n onPrimary() {\n const s = this.state();\n if (s.tag !== 'Editing') return;\n this.dispatch(s.step === 1 ? { tag: 'Next' } : { tag: 'Submit' });\n this.runIfSubmitting();\n }\n\n onRetry() {\n this.dispatch({ tag: 'Retry' });\n this.runIfSubmitting();\n }\n\n /** The effect: when we entered Submitting, call the backend command, flip the\n optimistic cross-page flag, then dispatch the result (and commit/rollback). */\n private async runIfSubmitting() {\n const s = this.state();\n if (s.tag !== 'Submitting') return;\n this.profile.beginHerregistratie();\n const r = await submitHerregistratie(s.data);\n if (r.ok) {\n this.dispatch({ tag: 'SubmitConfirmed' });\n this.profile.confirmHerregistratie();\n } else {\n this.dispatch({ tag: 'SubmitFailed', error: r.error });\n this.profile.rollbackHerregistratie();\n }\n }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "constructorObj": { "name": "constructor", "description": "", "deprecated": false, "deprecationMessage": "", "args": [], "line": 75 }, "extends": [] }, { "name": "LinkComponent", "id": "component-LinkComponent-81d97782386b884f56c43d583cbf6d1005dda96974f169366a9af853aeb8b8f4e99f9cce2f9a7ef0fdafce32f51e6049483a44ab35614c486f82535b65ce2818", "file": "src/app/shared/ui/link/link.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-link", "styleUrls": [], "styles": [], "template": "", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "to", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 11, "required": true } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "RouterLink" } ], "description": "

Atom: link. Internal router link styled as an RHC/Utrecht link.

\n", "rawdescription": "\nAtom: link. Internal router link styled as an RHC/Utrecht link.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\n/** Atom: link. Internal router link styled as an RHC/Utrecht link. */\n@Component({\n selector: 'app-link',\n imports: [RouterLink],\n template: ``,\n})\nexport class LinkComponent {\n to = input.required();\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "LoginFormComponent", "id": "component-LoginFormComponent-5a1ea0dfad0a47819d0884389f35e026337bfc135ed3cb5f34d5874d22b773b812864e1dfdcebf784acf886a77e9f59d3f244c7f3bbe1edafb38f0d8fb866a43", "file": "src/app/auth/ui/login-form/login-form.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-login-form", "styleUrls": [], "styles": [], "template": "
\n \n \n \n\n \n \n \n\n
\n Inloggen met DigiD\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [ { "name": "submit", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 30, "required": false } ], "propertiesClass": [ { "name": "bsn", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 28 }, { "name": "password", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 29 } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "FormFieldComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" } ], "description": "

Organism: DigiD-style mock login. No real auth — just composes atoms/molecules.

\n", "rawdescription": "\nOrganism: DigiD-style mock login. No real auth — just composes atoms/molecules.", "type": "component", "sourceCode": "import { Component, output } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\n\n/** Organism: DigiD-style mock login. No real auth — just composes atoms/molecules. */\n@Component({\n selector: 'app-login-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent],\n template: `\n
\n \n \n \n\n \n \n \n\n
\n Inloggen met DigiD\n
\n
\n `,\n})\nexport class LoginFormComponent {\n bsn = '';\n password = '';\n submit = output();\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "LoginPage", "id": "component-LoginPage-9e33c7b584edbd0642e3db190f47b540bad1779cd292050761380e92715a150b03eb5d869d57c6678b4d73523803c07e2d70d6e70183b34461ac31c15cafa95b", "file": "src/app/auth/ui/login.page.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-login-page", "styleUrls": [], "styles": [], "template": "\n @if (error()) { {{ error() }} }\n \n\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [ { "name": "error", "defaultValue": "signal('')", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 22 }, { "name": "router", "defaultValue": "inject(Router)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 21, "modifierKind": [ 123 ] }, { "name": "store", "defaultValue": "inject(SessionStore)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 20, "modifierKind": [ 123 ] } ], "methodsClass": [ { "name": "login", "args": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "any", "typeParameters": [], "line": 24, "deprecated": false, "deprecationMessage": "", "modifierKind": [ 134 ], "jsdoctags": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "PageShellComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "LoginFormComponent", "type": "component" } ], "description": "", "rawdescription": "\n", "type": "component", "sourceCode": "import { Component, inject, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { LoginFormComponent } from '@auth/ui/login-form/login-form.component';\nimport { SessionStore } from '@auth/application/session.store';\n\n@Component({\n selector: 'app-login-page',\n imports: [PageShellComponent, AlertComponent, LoginFormComponent],\n template: `\n \n @if (error()) { {{ error() }} }\n \n \n `,\n})\nexport class LoginPage {\n private store = inject(SessionStore);\n private router = inject(Router);\n error = signal('');\n\n async login(bsn: string) {\n const r = await this.store.login(bsn);\n if (r.ok) this.router.navigate(['/dashboard']);\n else this.error.set(r.error);\n }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "PageShellComponent", "id": "component-PageShellComponent-e203d646c83aa0fbb8c86fd2fd55c90f86a13538dcec381ed765f73d2d49424819da915fe6cc8a91700f890997d9d2407b4376630d984875e90277fe97679453", "file": "src/app/shared/layout/page-shell/page-shell.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-page-shell", "styleUrls": [], "styles": [ ":host{display:block}" ], "template": "
\n @if (backLink()) {\n

← {{ backLabel() }}

\n }\n {{ heading() }}\n @if (intro()) {\n

{{ intro() }}

\n }\n \n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "backLabel", "defaultValue": "'Terug naar overzicht'", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 29, "required": false }, { "name": "backLink", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 28, "required": false }, { "name": "heading", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 26, "required": true }, { "name": "intro", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 27, "required": false }, { "name": "width", "defaultValue": "'default'", "deprecated": false, "deprecationMessage": "", "type": "\"default\" | \"narrow\"", "indexKey": "", "optional": false, "description": "", "line": 30, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "HeadingComponent", "type": "component" }, { "name": "LinkComponent", "type": "component" } ], "description": "

Template: standard page body — optional back-link, a heading, optional intro,\nand projected content. Rendered inside the persistent ShellComponent via the\nrouter outlet, so it owns only the content (not the header/footer chrome).

\n", "rawdescription": "\nTemplate: standard page body — optional back-link, a heading, optional intro,\nand projected content. Rendered inside the persistent ShellComponent via the\nrouter outlet, so it owns only the content (not the header/footer chrome).", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { LinkComponent } from '@shared/ui/link/link.component';\n\n/** Template: standard page body — optional back-link, a heading, optional intro,\n and projected content. Rendered inside the persistent ShellComponent via the\n router outlet, so it owns only the content (not the header/footer chrome). */\n@Component({\n selector: 'app-page-shell',\n imports: [HeadingComponent, LinkComponent],\n styles: [':host{display:block}'],\n template: `\n
\n @if (backLink()) {\n

← {{ backLabel() }}

\n }\n {{ heading() }}\n @if (intro()) {\n

{{ intro() }}

\n }\n \n
\n `,\n})\nexport class PageShellComponent {\n heading = input.required();\n intro = input();\n backLink = input();\n backLabel = input('Terug naar overzicht');\n width = input<'default' | 'narrow'>('default');\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": ":host{display:block}\n", "extends": [] }, { "name": "RegistrationDetailPage", "id": "component-RegistrationDetailPage-5aa270b47adfa8bd0334225a51df3a1656468e109d14ca9967660455a734884f4fb358b0f2a6c97e19b4df859f4c5e9773d5dd9c728dbcd785a3d43a60472811", "file": "src/app/registratie/ui/registration-detail.page.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-registration-detail-page", "styleUrls": [], "styles": [], "template": "\n \n \n \n \n \n \n \n \n\n
\n @if (submitted()) {\n Uw adreswijziging is ontvangen. U ontvangt binnen 5 werkdagen bericht.\n } @else {\n \n }\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [ { "name": "store", "defaultValue": "inject(BigProfileStore)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 38, "modifierKind": [ 124 ] }, { "name": "submitted", "defaultValue": "signal(false)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 39 } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "PageShellComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "SkeletonComponent", "type": "component" }, { "name": "ASYNC" }, { "name": "RegistrationSummaryComponent", "type": "component" }, { "name": "ChangeRequestFormComponent", "type": "component" } ], "description": "", "rawdescription": "\n", "type": "component", "sourceCode": "import { Component, inject, signal } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';\nimport { ChangeRequestFormComponent } from '@registratie/ui/change-request-form/change-request-form.component';\nimport { BigProfileStore } from '@registratie/application/big-profile.store';\n\n@Component({\n selector: 'app-registration-detail-page',\n imports: [\n PageShellComponent, AlertComponent, SkeletonComponent, ...ASYNC,\n RegistrationSummaryComponent, ChangeRequestFormComponent,\n ],\n template: `\n \n \n \n \n \n \n \n \n \n\n
\n @if (submitted()) {\n Uw adreswijziging is ontvangen. U ontvangt binnen 5 werkdagen bericht.\n } @else {\n \n }\n
\n
\n `,\n})\nexport class RegistrationDetailPage {\n protected store = inject(BigProfileStore);\n submitted = signal(false);\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "RegistrationSummaryComponent", "id": "component-RegistrationSummaryComponent-15a446478708503b850ebbf635068398874034b3824504dc3a05802f6743029578088280540988dacfb6c768b92a2ee0371368369f455edc6dda03cf5f179e17", "file": "src/app/registratie/ui/registration-summary/registration-summary.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-registration-summary", "styleUrls": [], "styles": [], "template": "
\n
\n \n \n \n \n \n \n \n \n @switch (reg().status.tag) {\n @case ('Geregistreerd') {\n \n }\n @case ('Geschorst') {\n \n \n }\n @case ('Doorgehaald') {\n \n \n }\n }\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "reg", "deprecated": false, "deprecationMessage": "", "type": "Registration", "indexKey": "", "optional": false, "description": "", "line": 41, "required": true } ], "outputsClass": [], "propertiesClass": [ { "name": "color", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 43, "modifierKind": [ 124 ] }, { "name": "label", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 42, "modifierKind": [ 124 ] } ], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "DatePipe", "type": "pipe" }, { "name": "DataRowComponent", "type": "component" }, { "name": "StatusBadgeComponent", "type": "component" } ], "description": "

Organism: registration summary card. Composes data-row molecules + status-badge atom.

\n", "rawdescription": "\nOrganism: registration summary card. Composes data-row molecules + status-badge atom.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Registration } from '@registratie/domain/registration';\nimport { statusColor, statusLabel } from '@registratie/domain/registration.policy';\nimport { DataRowComponent } from '@shared/ui/data-row/data-row.component';\nimport { StatusBadgeComponent } from '@shared/ui/status-badge/status-badge.component';\n\n/** Organism: registration summary card. Composes data-row molecules + status-badge atom. */\n@Component({\n selector: 'app-registration-summary',\n imports: [DatePipe, DataRowComponent, StatusBadgeComponent],\n template: `\n
\n
\n \n \n \n \n \n \n \n \n @switch (reg().status.tag) {\n @case ('Geregistreerd') {\n \n }\n @case ('Geschorst') {\n \n \n }\n @case ('Doorgehaald') {\n \n \n }\n }\n
\n
\n `,\n})\nexport class RegistrationSummaryComponent {\n reg = input.required();\n protected label = () => statusLabel(this.reg().status.tag);\n protected color = () => statusColor(this.reg().status.tag);\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "RegistrationTableComponent", "id": "component-RegistrationTableComponent-d1fcc222260a33b20e1562a1bf325269cd07ebaed4838e1d74e883be3fbc1ef521d9250ba478316f93f8e133c0c5576cde367822159d6dff36d7b9da2c4d0a79", "file": "src/app/registratie/ui/registration-table/registration-table.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-registration-table", "styleUrls": [], "styles": [], "template": "
\n \n \n \n \n \n \n \n \n \n @for (row of rows(); track row.omschrijving) {\n \n \n \n \n \n }\n \n
TypeOmschrijvingDatum
{{ row.type }}{{ row.omschrijving }}{{ row.datum | date:'mediumDate' }}
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "rows", "deprecated": false, "deprecationMessage": "", "type": "Aantekening[]", "indexKey": "", "optional": false, "description": "", "line": 33, "required": true } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "DatePipe", "type": "pipe" } ], "description": "

Organism: table of specialismen/aantekeningen.

\n", "rawdescription": "\nOrganism: table of specialismen/aantekeningen.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Aantekening } from '@registratie/domain/registration';\n\n/** Organism: table of specialismen/aantekeningen. */\n@Component({\n selector: 'app-registration-table',\n imports: [DatePipe],\n template: `\n
\n \n \n \n \n \n \n \n \n \n @for (row of rows(); track row.omschrijving) {\n \n \n \n \n \n }\n \n
TypeOmschrijvingDatum
{{ row.type }}{{ row.omschrijving }}{{ row.datum | date:'mediumDate' }}
\n
\n `,\n})\nexport class RegistrationTableComponent {\n rows = input.required();\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "ShellComponent", "id": "component-ShellComponent-a66788510e6c68711bf080318372cd2c0d790797488b8ff39c17623325904a91e1ac98f1d49d6f6f81f416cc64206126a4d0f1ce50d66403bdd3fb6b6f924279", "file": "src/app/shared/layout/shell/shell.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-shell", "styleUrls": [], "styles": [ ":host{display:block}" ], "template": "Naar de inhoud\n
\n \n
\n
\n \n
\n
\n \n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "RouterOutlet" }, { "name": "SiteHeaderComponent", "type": "component" }, { "name": "SiteFooterComponent", "type": "component" } ], "description": "

Template: persistent app chrome. Header + footer mount once; only the routed\ncontent inside changes (and cross-fades — see styles.scss).

\n", "rawdescription": "\nTemplate: persistent app chrome. Header + footer mount once; only the routed\ncontent inside changes (and cross-fades — see styles.scss).", "type": "component", "sourceCode": "import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { SiteHeaderComponent } from '@shared/layout/site-header/site-header.component';\nimport { SiteFooterComponent } from '@shared/layout/site-footer/site-footer.component';\n\n/** Template: persistent app chrome. Header + footer mount once; only the routed\n content inside changes (and cross-fades — see styles.scss). */\n@Component({\n selector: 'app-shell',\n imports: [RouterOutlet, SiteHeaderComponent, SiteFooterComponent],\n styles: [':host{display:block}'],\n template: `\n Naar de inhoud\n
\n \n
\n
\n \n
\n
\n \n
\n `,\n})\nexport class ShellComponent {}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": ":host{display:block}\n", "extends": [] }, { "name": "SiteFooterComponent", "id": "component-SiteFooterComponent-90391287c6e8f3ad80c034a7a6fdabdd0514fd9c0dcf549a8e4a2d3bc3d885fcd5a45a2eeeb24fa8a4bbcf2cfe865093d712765d9d1ed11b4bfca26d1fb35153", "file": "src/app/shared/layout/site-footer/site-footer.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-site-footer", "styleUrls": [], "styles": [ ":host{display:block}" ], "template": "
\n
\n BIG-register\n CIBG — Ministerie van Volksgezondheid, Welzijn en Sport\n Demo / POC — geen echte gegevens\n
\n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Organism: site footer.

\n", "rawdescription": "\nOrganism: site footer.", "type": "component", "sourceCode": "import { Component } from '@angular/core';\n\n/** Organism: site footer. */\n@Component({\n selector: 'app-site-footer',\n styles: [':host{display:block}'],\n template: `\n
\n
\n BIG-register\n CIBG — Ministerie van Volksgezondheid, Welzijn en Sport\n Demo / POC — geen echte gegevens\n
\n
\n `,\n})\nexport class SiteFooterComponent {}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": ":host{display:block}\n", "extends": [] }, { "name": "SiteHeaderComponent", "id": "component-SiteHeaderComponent-710f1c109f26ae5f1888aa77ac682c58c9534fbba74aeae04b903e169f674c1ce04b8ae9e379a936c8ddef16e53c500e93d132021bcdd4ef743a601e05808f66", "file": "src/app/shared/layout/site-header/site-header.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-site-header", "styleUrls": [], "styles": [ ":host{display:block}" ], "template": "
\n \n
\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "subtitle", "defaultValue": "'Mijn omgeving'", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 27, "required": false } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "RouterLink" } ], "description": "

Organism: site header with Rijksoverheid-style wordmark + title.\nponytail: text wordmark instead of the licensed Rijksoverheid logo.

\n", "rawdescription": "\nOrganism: site header with Rijksoverheid-style wordmark + title.\nponytail: text wordmark instead of the licensed Rijksoverheid logo.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\n/** Organism: site header with Rijksoverheid-style wordmark + title.\n ponytail: text wordmark instead of the licensed Rijksoverheid logo. */\n@Component({\n selector: 'app-site-header',\n imports: [RouterLink],\n // :host display:block so the full-bleed bar fills the flex column (custom\n // elements default to display:inline, which collapsed the bar to its content).\n styles: [':host{display:block}'],\n template: `\n
\n \n
\n `,\n})\nexport class SiteHeaderComponent {\n subtitle = input('Mijn omgeving');\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": ":host{display:block}\n", "extends": [] }, { "name": "SkeletonComponent", "id": "component-SkeletonComponent-608d7384a7cd5705153c042fd961a63d69e4f61409276c2aec354b33db4199192d161fa81305090c262e18ab0a019913f469e85603ccefa6fba5c0dbc40d4f72", "file": "src/app/shared/ui/skeleton/skeleton.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-skeleton", "styleUrls": [], "styles": [ "\n :host{display:block}\n .sk{background:linear-gradient(90deg,#e8ebee 25%,#f3f5f6 37%,#e8ebee 63%);\n background-size:400% 100%;animation:sh 1.4s ease infinite;border-radius:4px;\n margin-block-end:0.6rem}\n @keyframes sh{0%{background-position:100% 0}100%{background-position:0 0}}\n " ], "template": "@if (visible()) {\n @for (l of lines(); track $index) {\n
\n }\n}\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "count", "defaultValue": "1", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 25, "required": false }, { "name": "delay", "defaultValue": "150", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 26, "required": false }, { "name": "height", "defaultValue": "'1rem'", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 24, "required": false }, { "name": "width", "defaultValue": "'100%'", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 23, "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "lines", "defaultValue": "computed(() => Array(this.count()).fill(0))", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 28, "modifierKind": [ 124 ] }, { "name": "timer", "deprecated": false, "deprecationMessage": "", "type": "ReturnType", "indexKey": "", "optional": true, "description": "", "line": 29, "modifierKind": [ 123 ] }, { "name": "visible", "defaultValue": "signal(false)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 27, "modifierKind": [ 124 ] } ], "methodsClass": [ { "name": "ngOnDestroy", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 32, "deprecated": false, "deprecationMessage": "" }, { "name": "ngOnInit", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 31, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: skeleton placeholder (grey shimmer). Delay-gated so it never flashes\non fast responses. Render count lines shaped roughly like the content.

\n", "rawdescription": "\nAtom: skeleton placeholder (grey shimmer). Delay-gated so it never flashes\non fast responses. Render `count` lines shaped roughly like the content.", "type": "component", "sourceCode": "import { Component, OnDestroy, OnInit, computed, input, signal } from '@angular/core';\n\n/** Atom: skeleton placeholder (grey shimmer). Delay-gated so it never flashes\n on fast responses. Render `count` lines shaped roughly like the content. */\n@Component({\n selector: 'app-skeleton',\n styles: [`\n :host{display:block}\n .sk{background:linear-gradient(90deg,#e8ebee 25%,#f3f5f6 37%,#e8ebee 63%);\n background-size:400% 100%;animation:sh 1.4s ease infinite;border-radius:4px;\n margin-block-end:0.6rem}\n @keyframes sh{0%{background-position:100% 0}100%{background-position:0 0}}\n `],\n template: `\n @if (visible()) {\n @for (l of lines(); track $index) {\n
\n }\n }\n `,\n})\nexport class SkeletonComponent implements OnInit, OnDestroy {\n width = input('100%');\n height = input('1rem');\n count = input(1);\n delay = input(150);\n protected visible = signal(false);\n protected lines = computed(() => Array(this.count()).fill(0));\n private timer?: ReturnType;\n\n ngOnInit() { this.timer = setTimeout(() => this.visible.set(true), this.delay()); }\n ngOnDestroy() { clearTimeout(this.timer); }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "\n :host{display:block}\n .sk{background:linear-gradient(90deg,#e8ebee 25%,#f3f5f6 37%,#e8ebee 63%);\n background-size:400% 100%;animation:sh 1.4s ease infinite;border-radius:4px;\n margin-block-end:0.6rem}\n @keyframes sh{0%{background-position:100% 0}100%{background-position:0 0}}\n \n", "extends": [], "implements": [ "OnInit", "OnDestroy" ] }, { "name": "SpinnerComponent", "id": "component-SpinnerComponent-4ac83777af1737425f1eec0d4c22a830297cca57c3140ef014842789163b2c2873312a9ae4e9dc7554241ac3b3dc339b7bab22e02fd8a4fe748a985264126ca4", "file": "src/app/shared/ui/spinner/spinner.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-spinner", "styleUrls": [], "styles": [ "\n :host{display:block}\n .sp{width:2rem;height:2rem;border-radius:50%;\n border:3px solid var(--rhc-color-grijs-300,#cad0d6);\n border-block-start-color:var(--rhc-color-lintblauw-700,#154273);\n animation:sp 0.8s linear infinite;margin:1.5rem auto}\n @keyframes sp{to{transform:rotate(360deg)}}\n " ], "template": "@if (visible()) {\n
\n}\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "delay", "defaultValue": "250", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 22, "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "timer", "deprecated": false, "deprecationMessage": "", "type": "ReturnType", "indexKey": "", "optional": true, "description": "", "line": 24, "modifierKind": [ 123 ] }, { "name": "visible", "defaultValue": "signal(false)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 23, "modifierKind": [ 124 ] } ], "methodsClass": [ { "name": "ngOnDestroy", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 27, "deprecated": false, "deprecationMessage": "" }, { "name": "ngOnInit", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 26, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: spinner that only appears after delay ms — fast responses never\nflash a spinner, slow ones get feedback.

\n", "rawdescription": "\nAtom: spinner that only appears after `delay` ms — fast responses never\nflash a spinner, slow ones get feedback.", "type": "component", "sourceCode": "import { Component, OnDestroy, OnInit, input, signal } from '@angular/core';\n\n/** Atom: spinner that only appears after `delay` ms — fast responses never\n flash a spinner, slow ones get feedback. */\n@Component({\n selector: 'app-spinner',\n styles: [`\n :host{display:block}\n .sp{width:2rem;height:2rem;border-radius:50%;\n border:3px solid var(--rhc-color-grijs-300,#cad0d6);\n border-block-start-color:var(--rhc-color-lintblauw-700,#154273);\n animation:sp 0.8s linear infinite;margin:1.5rem auto}\n @keyframes sp{to{transform:rotate(360deg)}}\n `],\n template: `\n @if (visible()) {\n
\n }\n `,\n})\nexport class SpinnerComponent implements OnInit, OnDestroy {\n delay = input(250);\n protected visible = signal(false);\n private timer?: ReturnType;\n\n ngOnInit() { this.timer = setTimeout(() => this.visible.set(true), this.delay()); }\n ngOnDestroy() { clearTimeout(this.timer); }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "\n :host{display:block}\n .sp{width:2rem;height:2rem;border-radius:50%;\n border:3px solid var(--rhc-color-grijs-300,#cad0d6);\n border-block-start-color:var(--rhc-color-lintblauw-700,#154273);\n animation:sp 0.8s linear infinite;margin:1.5rem auto}\n @keyframes sp{to{transform:rotate(360deg)}}\n \n", "extends": [], "implements": [ "OnInit", "OnDestroy" ] }, { "name": "StatusBadgeComponent", "id": "component-StatusBadgeComponent-4f1df6eb29e4abe21602ed3d03fe37881d253c2a9653306c7c95978022565da00b7c482db530f0eea482adf500359371cc588e7abcc8378d7e422cd7a18f00ad", "file": "src/app/shared/ui/status-badge/status-badge.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-status-badge", "styleUrls": [], "styles": [], "template": "\n \n {{ label() }}\n\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "color", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 17, "required": true }, { "name": "label", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 16, "required": true } ], "outputsClass": [], "propertiesClass": [], "methodsClass": [], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: a coloured dot + label. Purely presentational and domain-free — the\ncaller decides what colour and label mean (e.g. via registration.policy).\nThis keeps the shared UI kernel free of any domain knowledge.

\n", "rawdescription": "\nAtom: a coloured dot + label. Purely presentational and domain-free — the\ncaller decides what colour and label mean (e.g. via registration.policy).\nThis keeps the shared UI kernel free of any domain knowledge.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Atom: a coloured dot + label. Purely presentational and domain-free — the\n caller decides what colour and label mean (e.g. via registration.policy).\n This keeps the shared UI kernel free of any domain knowledge. */\n@Component({\n selector: 'app-status-badge',\n template: `\n \n \n {{ label() }}\n \n `,\n})\nexport class StatusBadgeComponent {\n label = input.required();\n color = input.required();\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [] }, { "name": "TextInputComponent", "id": "component-TextInputComponent-9d0cd6c2d7892958e9a016b570670f0186d410ea16a22925126f9eeea1aa178f081a4e5647af633f8a0bc1c458422a9f30169f159f930e9048702995fbb827e6", "file": "src/app/shared/ui/text-input/text-input.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [ { "name": ")" } ], "selector": "app-text-input", "styleUrls": [], "styles": [], "template": "\n", "templateUrl": [], "viewProviders": [], "hostDirectives": [], "inputsClass": [ { "name": "inputId", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 25, "required": false }, { "name": "invalid", "defaultValue": "false", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 24, "required": false }, { "name": "placeholder", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "indexKey": "", "optional": false, "description": "", "line": 23, "required": false }, { "name": "type", "defaultValue": "'text'", "deprecated": false, "deprecationMessage": "", "type": "\"text\" | \"password\" | \"email\"", "indexKey": "", "optional": false, "description": "", "line": 22, "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "disabled", "defaultValue": "false", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 28 }, { "name": "onChange", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "function", "indexKey": "", "optional": false, "description": "", "line": 29 }, { "name": "onTouched", "defaultValue": "() => {...}", "deprecated": false, "deprecationMessage": "", "type": "function", "indexKey": "", "optional": false, "description": "", "line": 30 }, { "name": "value", "defaultValue": "''", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 27 } ], "methodsClass": [ { "name": "onInput", "args": [ { "name": "e", "type": "Event", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 32, "deprecated": false, "deprecationMessage": "", "jsdoctags": [ { "name": "e", "type": "Event", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "registerOnChange", "args": [ { "name": "fn", "type": "function", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "function": [ { "name": "v", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ] } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 37, "deprecated": false, "deprecationMessage": "", "jsdoctags": [ { "name": "fn", "type": "function", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "function": [ { "name": "v", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "tagName": { "text": "param" } } ] }, { "name": "registerOnTouched", "args": [ { "name": "fn", "type": "function", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "function": [] } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 38, "deprecated": false, "deprecationMessage": "", "jsdoctags": [ { "name": "fn", "type": "function", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "function": [], "tagName": { "text": "param" } } ] }, { "name": "setDisabledState", "args": [ { "name": "d", "type": "boolean", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 39, "deprecated": false, "deprecationMessage": "", "jsdoctags": [ { "name": "d", "type": "boolean", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "writeValue", "args": [ { "name": "v", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "" } ], "optional": false, "returnType": "void", "typeParameters": [], "line": 36, "deprecated": false, "deprecationMessage": "", "jsdoctags": [ { "name": "v", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [], "description": "

Atom: text input. Utrecht textbox wired up as a form control (ngModel/reactive).

\n", "rawdescription": "\nAtom: text input. Utrecht textbox wired up as a form control (ngModel/reactive).", "type": "component", "sourceCode": "import { Component, forwardRef, input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/** Atom: text input. Utrecht textbox wired up as a form control (ngModel/reactive). */\n@Component({\n selector: 'app-text-input',\n template: `\n \n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextInputComponent), multi: true }],\n})\nexport class TextInputComponent implements ControlValueAccessor {\n type = input<'text' | 'password' | 'email'>('text');\n placeholder = input('');\n invalid = input(false);\n inputId = input();\n\n value = '';\n disabled = false;\n onChange: (v: string) => void = () => {};\n onTouched: () => void = () => {};\n\n onInput(e: Event) {\n this.value = (e.target as HTMLInputElement).value;\n this.onChange(this.value);\n }\n writeValue(v: string) { this.value = v ?? ''; }\n registerOnChange(fn: (v: string) => void) { this.onChange = fn; }\n registerOnTouched(fn: () => void) { this.onTouched = fn; }\n setDisabledState(d: boolean) { this.disabled = d; }\n}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": "", "extends": [], "implements": [ "ControlValueAccessor" ] } ], "modules": [], "miscellaneous": { "variables": [ { "name": "appConfig", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/app.config.ts", "deprecated": false, "deprecationMessage": "", "type": "ApplicationConfig", "defaultValue": "{\n providers: [\n provideBrowserGlobalErrorListeners(),\n provideRouter(routes, withViewTransitions()),\n provideHttpClient(withInterceptors([scenarioInterceptor])),\n { provide: LOCALE_ID, useValue: 'nl' },\n ]\n}" }, { "name": "ASYNC", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/ui/async/async.component.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "[\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const", "rawdescription": "Convenience: import this array to get the wrapper + all slot directives.", "description": "

Convenience: import this array to get the wrapper + all slot directives.

\n" }, { "name": "authGuard", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/auth/auth.guard.ts", "deprecated": false, "deprecationMessage": "", "type": "CanActivateFn", "defaultValue": "() => {\n const store = inject(SessionStore);\n const router = inject(Router);\n return store.isAuthenticated() ? true : router.createUrlTree(['/login']);\n}", "rawdescription": "Route guard: only let authenticated users in; otherwise redirect to /login.", "description": "

Route guard: only let authenticated users in; otherwise redirect to /login.

\n" }, { "name": "err", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "(error: E): Result => ({ ok: false, error })" }, { "name": "initial", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "WizardState", "defaultValue": "{ tag: 'Editing', step: 1, draft: { uren: '', punten: '' }, errors: {} }" }, { "name": "ok", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "(value: T): Result => ({ ok: true, value })" }, { "name": "routes", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/app.routes.ts", "deprecated": false, "deprecationMessage": "", "type": "Routes", "defaultValue": "[\n {\n path: '',\n component: ShellComponent, // persistent header/footer; only children swap\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'login' },\n { path: 'login', loadComponent: () => \"import('@auth/ui/login.page').then(m => m.LoginPage)\" },\n { path: 'dashboard', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/dashboard.page').then(m => m.DashboardPage)\" },\n { path: 'registratie', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/registration-detail.page').then(m => m.RegistrationDetailPage)\" },\n { path: 'herregistratie', canActivate: [authGuard], loadComponent: () => \"import('@herregistratie/ui/herregistratie.page').then(m => m.HerregistratiePage)\" },\n { path: 'concepts', loadComponent: () => \"import('./showcase/concepts.page').then(m => m.ConceptsPage)\" },\n { path: '**', redirectTo: 'login' },\n ],\n },\n]" }, { "name": "scenarioInterceptor", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.interceptor.ts", "deprecated": false, "deprecationMessage": "", "type": "HttpInterceptorFn", "defaultValue": "(req, next) => {\n if (!req.url.includes('mock/')) return next(req);\n\n switch (currentScenario()) {\n case 'slow':\n return next(req).pipe(delay(2500));\n case 'loading':\n return next(req).pipe(delay(600_000)); // effectively never resolves\n case 'empty':\n return of(new HttpResponse({ status: 200, body: [] })).pipe(delay(400));\n case 'error':\n return timer(400).pipe(\n switchMap(() => throwError(() =>\n new HttpErrorResponse({ status: 500, statusText: 'Demo-fout', url: req.url }))),\n );\n default:\n return next(req);\n }\n}", "rawdescription": "Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.", "description": "

Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.

\n" }, { "name": "VALID", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "type": "Scenario[]", "defaultValue": "['default', 'slow', 'loading', 'empty', 'error']" } ], "functions": [ { "name": "andThen", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Chain a second source that depends on the first one's value.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "assertNever", "file": "src/app/shared/kernel/fp.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Tiny native-TS functional toolkit. No dependency — this is the whole "library".\nReused by every "impossible states" concept in the POC.

\n", "args": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "" } ], "returnType": "never", "jsdoctags": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "back", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "createStore", "file": "src/app/shared/application/store.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "" }, { "name": "update", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Store", "jsdoctags": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "update", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "currentScenario", "file": "src/app/shared/infrastructure/scenario.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Reads ?scenario= from the URL so a demo can force each async state.

\n", "args": [], "returnType": "Scenario" }, { "name": "fakeResource", "file": "src/app/showcase/concepts.page.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Minimal fake Resource so can be driven through every state without HTTP.

\n", "args": [ { "name": "status", "type": "string", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "T", "deprecated": false, "deprecationMessage": "", "optional": true }, { "name": "error", "type": "Error", "deprecated": false, "deprecationMessage": "", "optional": true } ], "returnType": "Resource", "jsdoctags": [ { "name": "status", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "T", "deprecated": false, "deprecationMessage": "", "optional": true, "tagName": { "text": "param" } }, { "name": "error", "type": "Error", "deprecated": false, "deprecationMessage": "", "optional": true, "tagName": { "text": "param" } } ] }, { "name": "foldRemote", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Exhaustive fold: you must handle every case, checked at compile time.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "h", "deprecated": false, "deprecationMessage": "" } ], "returnType": "R", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "h", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "fromResource", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Project Angular's loosely-typed Resource into a RemoteData value.

\n", "args": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "" }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false", "tagName": { "text": "param" } } ] }, { "name": "herregistratieDeadline", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

The herregistratie deadline, if the status has one (only the active state does).

\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Date | null", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isAuthenticated", "file": "src/app/auth/domain/session.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Session", "jsdoctags": [ { "name": "s", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isHerregistratieEligible", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

A registration may apply for herregistratie only while active and within the\nwindow before its deadline. A struck-off or suspended registration may not.

\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "" }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12" } ], "returnType": "boolean", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12", "tagName": { "text": "param" } } ] }, { "name": "isStatusConsistent", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Invariant check used in tests/demos: a non-active status must not carry a\nherregistratie date. The union already enforces this structurally; this is\nthe runtime statement of the same rule.

\n", "args": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Transform the value inside a Success; pass other states through unchanged.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map2", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Combine two sources into one. Use this to merge e.g. a BIG-register call\nand a BRP call into a single state the page can render.

\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map3", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Combine three sources (built on map2).

\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "next", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Step 1 → 2: only advance if the uren field parses. Illegal elsewhere = no-op.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "parseBigNummer", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "parsePostcode", "file": "src/app/registratie/domain/value-objects/postcode.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "parseUren", "file": "src/app/registratie/domain/value-objects/uren.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "reduce", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "resolve", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Resolve the async submit. Only meaningful while Submitting.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setField", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Update one draft field while editing; ignored in any other state.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusColor", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Brand colour token for a status. assertNever forces a colour for every new\nstatus variant at compile time.

\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusLabel", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Domain logic for a registration — pure functions, NO Angular. This is where\n"what the business rules say" lives, separate from "how it looks" (UI) and\n"where the data comes from" (infrastructure). Keeping it framework-free means\nit is trivial to read and unit-test.

\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Step 2 submit: parse everything; move to Submitting only with Valid data.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submitHerregistratie", "file": "src/app/herregistratie/application/submit-herregistratie.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

The mutation/command: send a herregistratie application to the backend.\nReturns a Result so the caller can branch on success/failure without\ntry/catch. ponytail: faked with a timer; swap for a real POST when there's\nan API. The "uren must be > 0" rule lets the demo show a failure path.

\n", "args": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Promise>", "jsdoctags": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "validate", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Parse every field; on success hand back a Valid, else the per-field errors.

\n", "args": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result>, Valid>", "jsdoctags": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "typealiases": [ { "name": "AlertType", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"info\" | \"ok\" | \"warning\" | \"error\"", "file": "src/app/shared/ui/alert/alert.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "BigNummer", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a BIG registration number — 11 digits.

\n", "kind": 184 }, { "name": "Brand", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "unknown", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "

Nominal typing: Brand<string, 'Postcode'> is assignable from a plain string\nonly through an explicit cast — so a smart constructor is the only minter.

\n", "kind": 194 }, { "name": "Err", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Error | undefined", "file": "src/app/registratie/application/big-profile.store.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "Postcode", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/postcode.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a Dutch postcode. "Parse, don't validate" — a Postcode is a\ndistinct type from a raw string, mintable only via parsePostcode, so holding\none is proof it is well-formed.

\n", "kind": 184 }, { "name": "RegistrationStatus", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "

Registration status as a discriminated union: each variant owns exactly the\ndata that makes sense for it. Only an active (Geregistreerd) registration has\na herregistratie date; a struck-off (Doorgehaald) one cannot carry one. The\nold flat interface allowed that impossible combination — this makes it\nunrepresentable.

\n", "kind": 193 }, { "name": "RemoteData", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/shared/application/remote-data.ts", "deprecated": false, "deprecationMessage": "", "description": "

The four mutually-exclusive states of an async fetch, as a tagged union.\nCrucially the data lives ON the state: only Failure has an error, only\nSuccess has a value. "Loaded but no value" or "error with stale value"\nare unrepresentable — Richard Feldman's RemoteData.

\n", "kind": 193 }, { "name": "Result", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "

A computation that either succeeded with a value or failed with an error.\nPlain objects (no classes) to match the signal/httpResource ergonomics.

\n", "kind": 193 }, { "name": "Scenario", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"default\" | \"slow\" | \"loading\" | \"empty\" | \"error\"", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "StatusTag", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "RegistrationStatus", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "

Just the discriminant — for atoms that only need the label/color.

\n", "kind": 200 }, { "name": "Uren", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/uren.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a non-negative whole number of hours.

\n", "kind": 184 }, { "name": "Variant", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"primary\" | \"secondary\" | \"subtle\" | \"danger\"", "file": "src/app/shared/ui/button/button.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "WizardMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "

Every event that can happen to the wizard, as one message type. The component\nsends a WizardMsg; reduce decides the next state. This is the Elm\nModel+Msg+update pattern: ONE pure function describes all state changes.

\n", "kind": 193 }, { "name": "WizardState", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "

The whole wizard as one tagged union. step and errors exist ONLY while\nEditing; Submitting/Submitted/Failed carry a Valid payload and nothing else.\nSo "submitting while a field is invalid" or "showing the success screen with\nerrors set" are unrepresentable — the bug class is gone by construction.

\n", "kind": 193 } ], "enumerations": [], "groupedVariables": { "src/app/app.config.ts": [ { "name": "appConfig", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/app.config.ts", "deprecated": false, "deprecationMessage": "", "type": "ApplicationConfig", "defaultValue": "{\n providers: [\n provideBrowserGlobalErrorListeners(),\n provideRouter(routes, withViewTransitions()),\n provideHttpClient(withInterceptors([scenarioInterceptor])),\n { provide: LOCALE_ID, useValue: 'nl' },\n ]\n}" } ], "src/app/shared/ui/async/async.component.ts": [ { "name": "ASYNC", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/ui/async/async.component.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "[\n AsyncComponent, AsyncLoadedDirective, AsyncLoadingDirective,\n AsyncEmptyDirective, AsyncErrorDirective,\n] as const", "rawdescription": "Convenience: import this array to get the wrapper + all slot directives.", "description": "

Convenience: import this array to get the wrapper + all slot directives.

\n" } ], "src/app/auth/auth.guard.ts": [ { "name": "authGuard", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/auth/auth.guard.ts", "deprecated": false, "deprecationMessage": "", "type": "CanActivateFn", "defaultValue": "() => {\n const store = inject(SessionStore);\n const router = inject(Router);\n return store.isAuthenticated() ? true : router.createUrlTree(['/login']);\n}", "rawdescription": "Route guard: only let authenticated users in; otherwise redirect to /login.", "description": "

Route guard: only let authenticated users in; otherwise redirect to /login.

\n" } ], "src/app/shared/kernel/fp.ts": [ { "name": "err", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "(error: E): Result => ({ ok: false, error })" }, { "name": "ok", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "(value: T): Result => ({ ok: true, value })" } ], "src/app/herregistratie/domain/herregistratie.machine.ts": [ { "name": "initial", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "WizardState", "defaultValue": "{ tag: 'Editing', step: 1, draft: { uren: '', punten: '' }, errors: {} }" } ], "src/app/app.routes.ts": [ { "name": "routes", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/app.routes.ts", "deprecated": false, "deprecationMessage": "", "type": "Routes", "defaultValue": "[\n {\n path: '',\n component: ShellComponent, // persistent header/footer; only children swap\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'login' },\n { path: 'login', loadComponent: () => \"import('@auth/ui/login.page').then(m => m.LoginPage)\" },\n { path: 'dashboard', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/dashboard.page').then(m => m.DashboardPage)\" },\n { path: 'registratie', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/registration-detail.page').then(m => m.RegistrationDetailPage)\" },\n { path: 'herregistratie', canActivate: [authGuard], loadComponent: () => \"import('@herregistratie/ui/herregistratie.page').then(m => m.HerregistratiePage)\" },\n { path: 'concepts', loadComponent: () => \"import('./showcase/concepts.page').then(m => m.ConceptsPage)\" },\n { path: '**', redirectTo: 'login' },\n ],\n },\n]" } ], "src/app/shared/infrastructure/scenario.interceptor.ts": [ { "name": "scenarioInterceptor", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.interceptor.ts", "deprecated": false, "deprecationMessage": "", "type": "HttpInterceptorFn", "defaultValue": "(req, next) => {\n if (!req.url.includes('mock/')) return next(req);\n\n switch (currentScenario()) {\n case 'slow':\n return next(req).pipe(delay(2500));\n case 'loading':\n return next(req).pipe(delay(600_000)); // effectively never resolves\n case 'empty':\n return of(new HttpResponse({ status: 200, body: [] })).pipe(delay(400));\n case 'error':\n return timer(400).pipe(\n switchMap(() => throwError(() =>\n new HttpErrorResponse({ status: 500, statusText: 'Demo-fout', url: req.url }))),\n );\n default:\n return next(req);\n }\n}", "rawdescription": "Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.", "description": "

Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.

\n" } ], "src/app/shared/infrastructure/scenario.ts": [ { "name": "VALID", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "type": "Scenario[]", "defaultValue": "['default', 'slow', 'loading', 'empty', 'error']" } ] }, "groupedFunctions": { "src/app/shared/application/remote-data.ts": [ { "name": "andThen", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Chain a second source that depends on the first one's value.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "foldRemote", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Exhaustive fold: you must handle every case, checked at compile time.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "h", "deprecated": false, "deprecationMessage": "" } ], "returnType": "R", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "h", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "fromResource", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Project Angular's loosely-typed Resource into a RemoteData value.

\n", "args": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "" }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false", "tagName": { "text": "param" } } ] }, { "name": "map", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Transform the value inside a Success; pass other states through unchanged.

\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map2", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Combine two sources into one. Use this to merge e.g. a BIG-register call\nand a BRP call into a single state the page can render.

\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map3", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Combine three sources (built on map2).

\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteData", "jsdoctags": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "f", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/shared/kernel/fp.ts": [ { "name": "assertNever", "file": "src/app/shared/kernel/fp.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Tiny native-TS functional toolkit. No dependency — this is the whole "library".\nReused by every "impossible states" concept in the POC.

\n", "args": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "" } ], "returnType": "never", "jsdoctags": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/herregistratie/domain/herregistratie.machine.ts": [ { "name": "back", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "next", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Step 1 → 2: only advance if the uren field parses. Illegal elsewhere = no-op.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "reduce", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "resolve", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Resolve the async submit. Only meaningful while Submitting.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setField", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Update one draft field while editing; ignored in any other state.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Step 2 submit: parse everything; move to Submitting only with Valid data.

\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "validate", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Parse every field; on success hand back a Valid, else the per-field errors.

\n", "args": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result>, Valid>", "jsdoctags": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/shared/application/store.ts": [ { "name": "createStore", "file": "src/app/shared/application/store.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "" }, { "name": "update", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Store", "jsdoctags": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "update", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/shared/infrastructure/scenario.ts": [ { "name": "currentScenario", "file": "src/app/shared/infrastructure/scenario.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Reads ?scenario= from the URL so a demo can force each async state.

\n", "args": [], "returnType": "Scenario" } ], "src/app/showcase/concepts.page.ts": [ { "name": "fakeResource", "file": "src/app/showcase/concepts.page.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Minimal fake Resource so can be driven through every state without HTTP.

\n", "args": [ { "name": "status", "type": "string", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "T", "deprecated": false, "deprecationMessage": "", "optional": true }, { "name": "error", "type": "Error", "deprecated": false, "deprecationMessage": "", "optional": true } ], "returnType": "Resource", "jsdoctags": [ { "name": "status", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "T", "deprecated": false, "deprecationMessage": "", "optional": true, "tagName": { "text": "param" } }, { "name": "error", "type": "Error", "deprecated": false, "deprecationMessage": "", "optional": true, "tagName": { "text": "param" } } ] } ], "src/app/registratie/domain/registration.policy.ts": [ { "name": "herregistratieDeadline", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

The herregistratie deadline, if the status has one (only the active state does).

\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Date | null", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isHerregistratieEligible", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

A registration may apply for herregistratie only while active and within the\nwindow before its deadline. A struck-off or suspended registration may not.

\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "" }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12" } ], "returnType": "boolean", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12", "tagName": { "text": "param" } } ] }, { "name": "isStatusConsistent", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Invariant check used in tests/demos: a non-active status must not carry a\nherregistratie date. The union already enforces this structurally; this is\nthe runtime statement of the same rule.

\n", "args": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusColor", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Brand colour token for a status. assertNever forces a colour for every new\nstatus variant at compile time.

\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusLabel", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

Domain logic for a registration — pure functions, NO Angular. This is where\n"what the business rules say" lives, separate from "how it looks" (UI) and\n"where the data comes from" (infrastructure). Keeping it framework-free means\nit is trivial to read and unit-test.

\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/auth/domain/session.ts": [ { "name": "isAuthenticated", "file": "src/app/auth/domain/session.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Session", "jsdoctags": [ { "name": "s", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/registratie/domain/value-objects/big-nummer.ts": [ { "name": "parseBigNummer", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/registratie/domain/value-objects/postcode.ts": [ { "name": "parsePostcode", "file": "src/app/registratie/domain/value-objects/postcode.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/registratie/domain/value-objects/uren.ts": [ { "name": "parseUren", "file": "src/app/registratie/domain/value-objects/uren.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Result", "jsdoctags": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/herregistratie/application/submit-herregistratie.ts": [ { "name": "submitHerregistratie", "file": "src/app/herregistratie/application/submit-herregistratie.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "

The mutation/command: send a herregistratie application to the backend.\nReturns a Result so the caller can branch on success/failure without\ntry/catch. ponytail: faked with a timer; swap for a real POST when there's\nan API. The "uren must be > 0" rule lets the demo show a failure path.

\n", "args": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Promise>", "jsdoctags": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ] }, "groupedEnumerations": {}, "groupedTypeAliases": { "src/app/shared/ui/alert/alert.component.ts": [ { "name": "AlertType", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"info\" | \"ok\" | \"warning\" | \"error\"", "file": "src/app/shared/ui/alert/alert.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/registratie/domain/value-objects/big-nummer.ts": [ { "name": "BigNummer", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a BIG registration number — 11 digits.

\n", "kind": 184 } ], "src/app/shared/kernel/fp.ts": [ { "name": "Brand", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "unknown", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "

Nominal typing: Brand<string, 'Postcode'> is assignable from a plain string\nonly through an explicit cast — so a smart constructor is the only minter.

\n", "kind": 194 }, { "name": "Result", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "

A computation that either succeeded with a value or failed with an error.\nPlain objects (no classes) to match the signal/httpResource ergonomics.

\n", "kind": 193 } ], "src/app/registratie/application/big-profile.store.ts": [ { "name": "Err", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Error | undefined", "file": "src/app/registratie/application/big-profile.store.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/registratie/domain/value-objects/postcode.ts": [ { "name": "Postcode", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/postcode.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a Dutch postcode. "Parse, don't validate" — a Postcode is a\ndistinct type from a raw string, mintable only via parsePostcode, so holding\none is proof it is well-formed.

\n", "kind": 184 } ], "src/app/registratie/domain/registration.ts": [ { "name": "RegistrationStatus", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "

Registration status as a discriminated union: each variant owns exactly the\ndata that makes sense for it. Only an active (Geregistreerd) registration has\na herregistratie date; a struck-off (Doorgehaald) one cannot carry one. The\nold flat interface allowed that impossible combination — this makes it\nunrepresentable.

\n", "kind": 193 }, { "name": "StatusTag", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "RegistrationStatus", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "

Just the discriminant — for atoms that only need the label/color.

\n", "kind": 200 } ], "src/app/shared/application/remote-data.ts": [ { "name": "RemoteData", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/shared/application/remote-data.ts", "deprecated": false, "deprecationMessage": "", "description": "

The four mutually-exclusive states of an async fetch, as a tagged union.\nCrucially the data lives ON the state: only Failure has an error, only\nSuccess has a value. "Loaded but no value" or "error with stale value"\nare unrepresentable — Richard Feldman's RemoteData.

\n", "kind": 193 } ], "src/app/shared/infrastructure/scenario.ts": [ { "name": "Scenario", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"default\" | \"slow\" | \"loading\" | \"empty\" | \"error\"", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/registratie/domain/value-objects/uren.ts": [ { "name": "Uren", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Brand", "file": "src/app/registratie/domain/value-objects/uren.ts", "deprecated": false, "deprecationMessage": "", "description": "

Value object: a non-negative whole number of hours.

\n", "kind": 184 } ], "src/app/shared/ui/button/button.component.ts": [ { "name": "Variant", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"primary\" | \"secondary\" | \"subtle\" | \"danger\"", "file": "src/app/shared/ui/button/button.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/herregistratie/domain/herregistratie.machine.ts": [ { "name": "WizardMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "

Every event that can happen to the wizard, as one message type. The component\nsends a WizardMsg; reduce decides the next state. This is the Elm\nModel+Msg+update pattern: ONE pure function describes all state changes.

\n", "kind": 193 }, { "name": "WizardState", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "

The whole wizard as one tagged union. step and errors exist ONLY while\nEditing; Submitting/Submitted/Failed carry a Valid payload and nothing else.\nSo "submitting while a field is invalid" or "showing the success screen with\nerrors set" are unrepresentable — the bug class is gone by construction.

\n", "kind": 193 } ] } }, "routes": { "name": "", "kind": "module", "children": [ { "name": "ShellComponent", "kind": "component", "filename": "src/app/app.routes.ts" }, { "name": "login", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "dashboard", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "registratie", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "herregistratie", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "concepts", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "**", "kind": "route-path", "filename": "src/app/app.routes.ts" }, { "name": "login", "kind": "route-redirect", "filename": "src/app/app.routes.ts" }, { "name": "login", "kind": "route-redirect", "filename": "src/app/app.routes.ts" } ] }, "coverage": { "count": 47, "status": "medium", "files": [ { "filePath": "src/app/app.config.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "appConfig", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/app.routes.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "routes", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/app.ts", "type": "component", "linktype": "component", "name": "App", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/auth/application/session.store.ts", "type": "injectable", "linktype": "injectable", "name": "SessionStore", "coveragePercent": 28, "coverageCount": "2/7", "status": "medium" }, { "filePath": "src/app/auth/auth.guard.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "authGuard", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/auth/domain/session.ts", "type": "interface", "linktype": "interface", "name": "Session", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/auth/domain/session.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "isAuthenticated", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/auth/infrastructure/digid.adapter.ts", "type": "injectable", "linktype": "injectable", "name": "DigidAdapter", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/auth/ui/login-form/login-form.component.ts", "type": "component", "linktype": "component", "name": "LoginFormComponent", "coveragePercent": 25, "coverageCount": "1/4", "status": "low" }, { "filePath": "src/app/auth/ui/login.page.ts", "type": "component", "linktype": "component", "name": "LoginPage", "coveragePercent": 0, "coverageCount": "0/5", "status": "low" }, { "filePath": "src/app/herregistratie/application/submit-herregistratie.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "submitHerregistratie", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "interface", "linktype": "interface", "name": "Draft", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "interface", "linktype": "interface", "name": "Valid", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "back", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "next", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "reduce", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "resolve", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "setField", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "submit", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "validate", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "initial", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "WizardMsg", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/domain/herregistratie.machine.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "WizardState", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component.ts", "type": "component", "linktype": "component", "name": "HerregistratieWizardComponent", "coveragePercent": 18, "coverageCount": "3/16", "status": "low" }, { "filePath": "src/app/herregistratie/ui/herregistratie.page.ts", "type": "component", "linktype": "component", "name": "HerregistratiePage", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/registratie/application/big-profile.store.ts", "type": "injectable", "linktype": "injectable", "name": "BigProfileStore", "coveragePercent": 30, "coverageCount": "4/13", "status": "medium" }, { "filePath": "src/app/registratie/application/big-profile.store.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Err", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/registratie/domain/big-profile.ts", "type": "interface", "linktype": "interface", "name": "BigProfile", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/registratie/domain/person.ts", "type": "interface", "linktype": "interface", "name": "Adres", "coveragePercent": 25, "coverageCount": "1/4", "status": "low" }, { "filePath": "src/app/registratie/domain/person.ts", "type": "interface", "linktype": "interface", "name": "Person", "coveragePercent": 0, "coverageCount": "0/4", "status": "low" }, { "filePath": "src/app/registratie/domain/registration.policy.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "herregistratieDeadline", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.policy.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "isHerregistratieEligible", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.policy.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "isStatusConsistent", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.policy.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "statusColor", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.policy.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "statusLabel", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.ts", "type": "interface", "linktype": "interface", "name": "Aantekening", "coveragePercent": 0, "coverageCount": "0/4", "status": "low" }, { "filePath": "src/app/registratie/domain/registration.ts", "type": "interface", "linktype": "interface", "name": "Registration", "coveragePercent": 0, "coverageCount": "0/7", "status": "low" }, { "filePath": "src/app/registratie/domain/registration.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "RegistrationStatus", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/registration.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "StatusTag", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/value-objects/big-nummer.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "parseBigNummer", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/registratie/domain/value-objects/big-nummer.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "BigNummer", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/value-objects/postcode.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "parsePostcode", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/registratie/domain/value-objects/postcode.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Postcode", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/domain/value-objects/uren.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "parseUren", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/registratie/domain/value-objects/uren.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Uren", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/registratie/infrastructure/big-register.adapter.ts", "type": "injectable", "linktype": "injectable", "name": "BigRegisterAdapter", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/registratie/infrastructure/brp.adapter.ts", "type": "injectable", "linktype": "injectable", "name": "BrpAdapter", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/registratie/ui/change-request-form/change-request-form.component.ts", "type": "component", "linktype": "component", "name": "ChangeRequestFormComponent", "coveragePercent": 12, "coverageCount": "1/8", "status": "low" }, { "filePath": "src/app/registratie/ui/change-request-form/change-request-form.component.ts", "type": "interface", "linktype": "interface", "name": "ChangeRequest", "coveragePercent": 25, "coverageCount": "1/4", "status": "low" }, { "filePath": "src/app/registratie/ui/dashboard.page.ts", "type": "component", "linktype": "component", "name": "DashboardPage", "coveragePercent": 0, "coverageCount": "0/2", "status": "low" }, { "filePath": "src/app/registratie/ui/registration-detail.page.ts", "type": "component", "linktype": "component", "name": "RegistrationDetailPage", "coveragePercent": 0, "coverageCount": "0/3", "status": "low" }, { "filePath": "src/app/registratie/ui/registration-summary/registration-summary.component.ts", "type": "component", "linktype": "component", "name": "RegistrationSummaryComponent", "coveragePercent": 25, "coverageCount": "1/4", "status": "low" }, { "filePath": "src/app/registratie/ui/registration-table/registration-table.component.ts", "type": "component", "linktype": "component", "name": "RegistrationTableComponent", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "andThen", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "foldRemote", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "fromResource", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "map", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "map2", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "map3", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/remote-data.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "RemoteData", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/application/store.ts", "type": "interface", "linktype": "interface", "name": "Store", "coveragePercent": 100, "coverageCount": "3/3", "status": "very-good" }, { "filePath": "src/app/shared/application/store.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "createStore", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/infrastructure/scenario.interceptor.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "scenarioInterceptor", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/infrastructure/scenario.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "currentScenario", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/infrastructure/scenario.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "VALID", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/infrastructure/scenario.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Scenario", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/kernel/fp.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "assertNever", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/kernel/fp.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "err", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/kernel/fp.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "ok", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/kernel/fp.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Brand", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/kernel/fp.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Result", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/layout/page-shell/page-shell.component.ts", "type": "component", "linktype": "component", "name": "PageShellComponent", "coveragePercent": 16, "coverageCount": "1/6", "status": "low" }, { "filePath": "src/app/shared/layout/shell/shell.component.ts", "type": "component", "linktype": "component", "name": "ShellComponent", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/layout/site-footer/site-footer.component.ts", "type": "component", "linktype": "component", "name": "SiteFooterComponent", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/layout/site-header/site-header.component.ts", "type": "component", "linktype": "component", "name": "SiteHeaderComponent", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/shared/ui/alert/alert.component.ts", "type": "component", "linktype": "component", "name": "AlertComponent", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/shared/ui/alert/alert.component.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "AlertType", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "component", "linktype": "component", "name": "AsyncComponent", "coveragePercent": 8, "coverageCount": "1/12", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "directive", "linktype": "directive", "name": "AsyncEmptyDirective", "coveragePercent": 0, "coverageCount": "0/3", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "directive", "linktype": "directive", "name": "AsyncErrorDirective", "coveragePercent": 0, "coverageCount": "0/3", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "directive", "linktype": "directive", "name": "AsyncLoadedDirective", "coveragePercent": 0, "coverageCount": "0/3", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "directive", "linktype": "directive", "name": "AsyncLoadingDirective", "coveragePercent": 0, "coverageCount": "0/3", "status": "low" }, { "filePath": "src/app/shared/ui/async/async.component.ts", "type": "variable", "linktype": "miscellaneous", "linksubtype": "variable", "name": "ASYNC", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" }, { "filePath": "src/app/shared/ui/button/button.component.ts", "type": "component", "linktype": "component", "name": "ButtonComponent", "coveragePercent": 25, "coverageCount": "1/4", "status": "low" }, { "filePath": "src/app/shared/ui/button/button.component.ts", "type": "type alias", "linktype": "miscellaneous", "linksubtype": "typealias", "name": "Variant", "coveragePercent": 0, "coverageCount": "0/1", "status": "low" }, { "filePath": "src/app/shared/ui/data-row/data-row.component.ts", "type": "component", "linktype": "component", "name": "DataRowComponent", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/shared/ui/form-field/form-field.component.ts", "type": "component", "linktype": "component", "name": "FormFieldComponent", "coveragePercent": 20, "coverageCount": "1/5", "status": "low" }, { "filePath": "src/app/shared/ui/heading/heading.component.ts", "type": "component", "linktype": "component", "name": "HeadingComponent", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/shared/ui/link/link.component.ts", "type": "component", "linktype": "component", "name": "LinkComponent", "coveragePercent": 50, "coverageCount": "1/2", "status": "medium" }, { "filePath": "src/app/shared/ui/skeleton/skeleton.component.ts", "type": "component", "linktype": "component", "name": "SkeletonComponent", "coveragePercent": 10, "coverageCount": "1/10", "status": "low" }, { "filePath": "src/app/shared/ui/spinner/spinner.component.ts", "type": "component", "linktype": "component", "name": "SpinnerComponent", "coveragePercent": 16, "coverageCount": "1/6", "status": "low" }, { "filePath": "src/app/shared/ui/status-badge/status-badge.component.ts", "type": "component", "linktype": "component", "name": "StatusBadgeComponent", "coveragePercent": 33, "coverageCount": "1/3", "status": "medium" }, { "filePath": "src/app/shared/ui/text-input/text-input.component.ts", "type": "component", "linktype": "component", "name": "TextInputComponent", "coveragePercent": 7, "coverageCount": "1/14", "status": "low" }, { "filePath": "src/app/showcase/concepts.page.ts", "type": "component", "linktype": "component", "name": "ConceptsPage", "coveragePercent": 8, "coverageCount": "1/12", "status": "low" }, { "filePath": "src/app/showcase/concepts.page.ts", "type": "function", "linktype": "miscellaneous", "linksubtype": "function", "name": "fakeResource", "coveragePercent": 100, "coverageCount": "1/1", "status": "very-good" } ] } }