refactor(register): customer, supplier and article detail as documents, not card piles (#1624)

The three register detail pages rendered a handful of facts as a grid of
sparse bordered cards floating in an empty page. They now read as one
flowing document: serif entity name over a quiet type/status kicker,
quiet ghost actions top right (delete turns terracotta only on hover),
and hairline-kickered definition sections (KONTAKT, KUNDUPPGIFTER,
PRIS, BOKFORING, BETALNINGSUPPGIFTER, FAKTUROR) with aligned label/value
rows in a constrained column (max-w-2xl, supplier max-w-3xl for its
invoice table). Sections land with the standard stagger-enter.

New shared primitive components/ui/detail-section.tsx (DetailSection,
DefRow, DefEmpty) carries the grammar. Empty values render a muted
en dash for facts that matter (email, phone, expense account) and are
omitted row-wise otherwise; a section with nothing to say is omitted.

Behavior preserved: edit/deactivate/delete flows, confirm dialogs,
personal-number reveal + AttnLine, account-activation retry, viewer
lock states, routing and all existing i18n keys. New def_* label keys
added line-wise to both sv.json and en.json; customer invoice_count
gained ICU plural (1 faktura, not 1 fakturor).

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-16 17:28:45 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5
parent 51539b93ed
commit a977a67063
7 changed files with 556 additions and 539 deletions
+1
View File
@@ -993,6 +993,7 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-08-14] The onboarding branch question ("Var fanns bokföringen innan?") became its own journey step at the existing KLART station (done -> source, same station grammar as momsyn/moms under MOMSEN) instead of a sixth rail station: a 6-point rail crowds the 680px band's 150px label slots, "BOKFÖRINGEN INNAN" would sit next to the existing "BOKFÖRINGEN" station, and mode='add' (which never sees the branch question) would need an asymmetric rail. The done screen ends in a revealed Fortsätt that dispatches DONE_CONTINUE (mode='first' only, reducer-guarded).
[2026-08-14] Migration /preview fetches ALL allowed fiscal years (dropped latestOnly): the connect step's "Hittade X konton och Y verifikationer" renders from /preview's sieStats, not /sie-data's generateImportPreview, so fixing only /sie-data would have left the founder-reported "0 verifikationer" (actual: 4153) on screen. Costs one SIE export per extra year at connect time, the same work /sie-data repeats right after; honest counts won over latency.
[2026-08-14] /sie-data validation stays newest-file-only (not per-file, not on the merged parse): preserves exactly which datasets are accepted today, and validateSIEFile assumes single-file invariants (balance yearIndexes relative to ONE current year) that mergeParsedSIEFiles deliberately does not preserve. Older files' problems still surface per-file at import time.
[2026-08-15] Register detail de-box (customers/suppliers/articles): added new def_* label keys next to the old colon-suffixed and inline-format keys instead of renaming or deleting them: message files are only ever edited line-wise (duplicate-key hazard forbids JSON round-trips), so dead keys are cheaper than a risky rewrite. Also converted the customer invoice list's per-row status Badge to muted text with a chip only for Förfallen, per the locked "chips mark exceptions" convention: paid on every row was the same-chip-on-every-row bug the convention names.
[2026-08-15] Employee form save-scope fix: moved the self-saving sections (Förmåner, Ingående saldon) OUTSIDE the page <form> under a "Sparas separat" kicker with a one-line scope hint, kept them as Cards (locked section pattern; the task-suggested hairline no-box region would deviate from every sibling section) and rejected the tab/sub-page shape (page has no tab structure, would be more invasive). This also fixes a real double-fire: shadcn Button has no default type, so the panels' save/add/delete buttons inside the form implicitly submitted the whole employee PATCH on every click; opening-balances now has its own <form> whose save enables only when dirty.
[2026-08-14] SKV manual-verifikat deep link payload moved from URL params to single-use sessionStorage (supersedes same-day URL-params decision): compliance swarm flagged financial data in query strings landing in history/access logs/Referer (GDPR Art.5(1)(f), ISO A.8.12); URL now carries only the opaque row id.
[2026-08-14] SKV prefill sessionStorage XSS window accepted as residual risk (ISO A.8.12 low, swarm PR #1621): script execution already implies full ledger read via authenticated APIs; a server-issued staging token adds a roundtrip, not protection. Documented in manual-verifikat-prefill.ts header.