feat(fp): WP-27 — brief UX layer (undo/redo, standaardbrief, passage search, diff badges)
CI / frontend (push) Failing after 1m15s
CI / storybook-a11y (push) Failing after 4m43s
CI / backend (push) Successful in 1m24s
CI / codeql (csharp) (push) Failing after 2m51s
CI / e2e (push) Failing after 3h4m8s
CI / codeql (javascript-typescript) (push) Failing after 1m30s
CI / api-client-drift (push) Successful in 1m53s

Brief letter-composition UX improvements:
- undo/redo history in the brief store (snapshot stacks, Ctrl/Cmd+Z) + retry-save
- "Standaardbrief invoegen" starter for empty sections; isDefault library passages
  (backend DTO/seed + adapter parse)
- passage-picker client-side search (rich-text textOf helper)
- rejection diff badges on the letter canvas + show/hide changes toggle
  (pure brief-diff domain fns + spec)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-07-20 14:36:32 +02:00
co-authored by Claude Opus 4.8
parent 950fb5f0b2
commit 5e36d68f11
21 changed files with 3537 additions and 1907 deletions
@@ -226,10 +226,12 @@ public static class BriefSeed
{
new("p-aanhef-1", "global", "aanhef", "Standaard aanhef",
Block(T("Geachte heer/mevrouw "), P("naam_zorgverlener"), T(",")), 1),
// The "standaardbrief" kern starter set (IsDefault): one button drops these
// in when the kern is still empty (WP-27).
new("p-kern-1", "global", "kern", "Beoordeling ontvangen",
Block(T("Op "), P("datum"), T(" hebben wij uw aanvraag beoordeeld.")), 1),
Block(T("Op "), P("datum"), T(" hebben wij uw aanvraag beoordeeld.")), 1, IsDefault: true),
new("p-kern-arts", "beroep", "kern", "Toelichting arts",
Block(T("Als arts met BIG-nummer "), P("big_nummer"), T(" delen wij u het volgende mee.")), 1, Beroep: "arts"),
Block(T("Als arts met BIG-nummer "), P("big_nummer"), T(" delen wij u het volgende mee.")), 1, Beroep: "arts", IsDefault: true),
new("p-slot-1", "global", "slot", "Standaard slot",
Block(T("Met vriendelijke groet,")), 1),
// These reference a deprecated / not-fillable field so the linter's