Non-SEK article prices became first-class in #1166, so a mixed register needs a
way to look at one currency at a time (user request, christian@odinaero.se
2026-07-25).
- ContextPicker chip far right in the toolbar (convention 8), options = the
currencies actually present in the register, default "Alla valutor". A
single-currency register does not render it: a control with one meaningful
position is noise.
- The scope lives in the URL alongside sort/dir, so a filtered register survives
opening an article and coming back, and can be linked to. A code that is not
in the register (last EUR article deleted, hand-edited link) falls back to
"Alla" instead of hiding every row.
- Search and scope combine, and the no-matches copy names the scope when one is
active: otherwise "no articles match X" reads as a claim about the whole
register when it is only true inside the current currency.
- Predicates live in lib/articles/currency-scope.ts with unit tests; blank and
legacy-null currencies fold into SEK the way the price column already
displays them.
New strings in both messages/sv.json and messages/en.json. npm test 11369
passed, lint 0 errors, no new tsc errors. Chip screenshotted against the design
system via a temporary sandbox route.
Closes#1189
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: article number ordering, free-text rows, invoice back-nav, onboarding resilience (#1053)
Four fixes from Discord feedback in issue #1053:
- Articles now order by article number with numeric-aware comparison
('2' before '10', unnumbered last, name tiebreak) in the invoice
editor's article picker and as the register's default sort, via a
shared lib/articles/sort.ts. Name order put article "1" last.
- Invoice rows with no amounts (quantity 0, unit price 0) render as
pure text rows on the PDF, the invoice detail page, and the review
step via shared isTextLikeLine(), instead of printing
"0 / 0,00 SEK / 0,00 SEK". Display-only; booking untouched.
- The invoice editor navigates with router.replace after saving, so
the detail page's back arrow returns to the list instead of
reopening a fresh editor from history.
- A transient query failure no longer reads as "no companies" /
"onboarding not done": getActiveCompanyId throws
CompanyContextError('resolution_failed') instead of returning null,
the Edge middleware fails open on a degraded resolution (no
onboarding redirect, no cookie clearing, no locale overwrite), and
the dashboard page only redirects to /onboarding on a positively
read incomplete/missing settings row. This is the likely cause of
the completed onboarding wizard reappearing.
Fixes#1053
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: CLAUDE.md tenancy line matches actual resolution order (prefs-first, cookie not read)
The middleware stopped reading the gnubok-company-id cookie when
user_preferences became authoritative (RLS parity); the stale doc line
still described cookie-first order and misled review tooling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>