416 Commits

Author SHA1 Message Date
logaritmisk 04ed0c50e2 feat(web): indigo brand token + status tokens + Badge success/warning variants (#49)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 14:08:08 +02:00
logaritmisk 67e486df46 docs(plans): design-token adoption across feature screens (#49)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 14:04:15 +02:00
logaritmisk d408464e91 docs(specs): design-token adoption across feature screens (#49)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 14:00:42 +02:00
logaritmisk 1bfa44a0ed merge: toast notifications + consistent mutation feedback (#47)
CI / web (push) Has been cancelled
Base UI toast region bridged to the QueryClient via an out-of-React manager; global
MutationCache gives every mutation feedback (opt-in success + catch-all type-aware
error toast, suppressible where errors show inline). Inline 422/409 UX preserved.
Closes #47.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:47:05 +02:00
logaritmisk 303c986d40 chore(web): raise bundle budget 180→250 KB gz (#47)
Generous ceiling so the budget stops blocking per-feature work (this is the third
raise in three frontend milestones) while still catching gross regressions. A
vendor-split / bundle audit can revisit always-loaded weight later.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:35:35 +02:00
logaritmisk fcad638549 feat(web): per-mutation success/error toast metadata (#47)
Declare meta on all 18 mutation hooks: meta.successMessage (toast.* key)
on every discrete user action, meta.suppressErrorToast where the consuming
component already renders the error inline. Corrected useUpdateFieldDefinition
to suppress (FieldForm renders update.isError as form.rejected inline).

Add an RTL+MSW integration test wiring the real MutationCache via
makeQueryClient() + ToastRegion: success toast, catch-all error toast, and
suppressed-no-toast. Tidy the toast Close aria-label to t("common.close")
with en/sv parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:55:54 +02:00
logaritmisk 604d4f6005 feat(web): Base UI toast region + global mutation feedback wiring (#47)
Add a module-scope Base UI toast manager bridged to the QueryClient so
every mutation can give consistent feedback. A MutationCache (extracted
into a makeQueryClient() factory for test reuse) emits a catch-all,
type-aware error toast (unless meta.suppressErrorToast) and an opt-in
success toast (meta.successMessage), reading mutation.meta + i18n.t
outside React. meta is type-checked via a react-query Register
augmentation. ToastRegion is mounted app-wide in main.tsx. Adds a toast
i18n namespace (en/sv parity) and a validated story.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:46:26 +02:00
logaritmisk 63bfff417b docs(plans): toast notifications + mutation feedback (#47)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:30:30 +02:00
logaritmisk 8eb527957b docs(specs): toast notifications + consistent mutation feedback (#47)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:09:09 +02:00
logaritmisk e2ae093ed8 merge: object detail readability — resolve labels, group fields (#45)
Object detail resolves term/authority ids to labels, localized_text to the active
language, dates locale-formatted; flexible fields grouped by definition; core fields
always shown with placeholders; Edit/Delete actions toolbar. Closes #45.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:54:53 +02:00
logaritmisk 03d5b59b48 feat(web): readable, grouped object detail (labels, placeholders, actions toolbar) (#45)
Refactor object-detail.tsx to resolve term/authority ids to labels via
FlexibleFieldValue, group flexible fields by def.group in definition order
(ungrouped → trailing "Other"), always show core fields with "—" placeholders,
and move Edit (button-styled Link) + Delete into a right-aligned toolbar.

Move formatDate into lib/format-date.ts so the component module no longer
co-exports a non-component (clears the react-refresh/only-export-components
warning); both flexible-field-value.tsx and object-detail.tsx import it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:44:35 +02:00
logaritmisk 2e38af565a feat(web): FlexibleFieldValue — resolve term/authority/localized field values (#45)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:32:17 +02:00
logaritmisk 7258b3fd03 docs(plans): object detail readability (#45)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 11:24:58 +02:00
logaritmisk 6ec31b6c51 docs(specs): object detail readability — resolve labels, group fields (#45)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:54:41 +02:00
logaritmisk 0a88a86bb3 merge: objects data-overview table + responsive shell (#44, #58 shell)
CI / web (push) Has been cancelled
Full-width sortable/filterable objects table (server-side sort/filter/quick-search,
exposed timestamps, URL-synced state); collapsible icon sidebar; responsive object
detail (pane wide / Base UI drawer narrow) at canonical /objects/:id. Closes #44.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 09:48:50 +02:00
logaritmisk 6a62cf64bf chore(web): drop dead objects.selectPrompt i18n key (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 00:13:32 +02:00
logaritmisk c052ddc5af test(web): widen findBy timeout for the lazy/portaled narrow-drawer detail test (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 00:03:46 +02:00
logaritmisk e7b0f65686 chore(web): raise bundle budget 165→180 KB gz (#44)
The collapsed-sidebar tooltips use Base UI's Tooltip, which pulls floating-ui
into the always-loaded shell chunk. Kept the richer tooltip over native title;
the index is a feature-rich admin SPA bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:58:03 +02:00
logaritmisk b8f70212a1 feat(web): responsive object detail (pane/drawer) at canonical /objects/:id (#44, #58)
Wide (>=1024px): right-hand pane beside the table with a close control.
Narrow: Base UI Drawer sliding from the right (lazy-loaded so its code splits
out of the main chunk). Both preserve the table's query string on close.

Remove the index SelectPrompt route (the table is the landing view) and delete
the now-unused SelectPrompt. Make table rows keyboard-activatable
(role=link, tabIndex, Enter).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:53:10 +02:00
logaritmisk 184e4ea2a5 feat(web): collapsible icon sidebar (persisted, auto-collapse on narrow) (#44, #58)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:44:40 +02:00
logaritmisk 04c33cb1aa feat(web): useMediaQuery hook + Base UI tooltip wrapper (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:40:19 +02:00
logaritmisk 49f694d1fb feat(web): full-width sortable/filterable objects table with URL state (#44)
Replace the narrow ObjectList with a full-width ObjectsTable whose state
(sort/order/q/visibility/limit/offset) lives entirely in the URL via
useSearchParams. Sortable headers toggle sort+dir with aria-sort, a
debounced quick-filter and visibility chips mirror the search-panel
pattern, and a pagination footer offers prev/next + page-size select.
Rows deep-link to /objects/:id preserving the query string.

useObjectsPage now takes an ObjectListParams object (sort/order/
visibility/q) with keepPreviousData. ObjectsPage renders the table as
the full-width landing view, surfacing the nested <Outlet/> detail as a
simple right-side panel only when a :id child route is active (Phase 3
makes this responsive). object-list.tsx and its test are removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:34:13 +02:00
logaritmisk 98c00d3732 chore(web): regenerate API types (object list params + timestamps) (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:24:42 +02:00
logaritmisk 60a1b8dccf feat: object list sort/filter/quick-search (server-side, injection-safe) (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:21:04 +02:00
logaritmisk 5efa7b8a16 feat(api): expose object created_at/updated_at in AdminObjectView (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 23:17:50 +02:00
logaritmisk e7ff817c63 docs(plans): objects data-overview table + responsive shell (#44)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:58:06 +02:00
logaritmisk fb80146430 docs(specs): objects data-overview table + responsive shell (#44, subsumes #58)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:50:13 +02:00
logaritmisk b49699175d feat(server): load .env via dotenvy on startup
CI / web (push) Has been cancelled
The binary now reads a .env file itself (dotenvy::dotenv() at the top of main),
so 'cargo run -p server' / the release binary pick up config without relying on
just's 'set dotenv-load'. Missing .env is a no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 14:39:24 +02:00
logaritmisk e700e1d3cf chore: add 'just run-release' (build web + run server with embed-web)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 14:30:56 +02:00
logaritmisk de035bd032 merge: searchable term/authority combobox picker (#27)
CI / web (push) Has been cancelled
Replace the native <select> for term/authority object fields with a searchable
Base UI combobox (client-side filter by active-locale label; value=id contract
preserved). Server-side ?q= search deferred to a follow-up. Closes #27.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 11:00:50 +02:00
logaritmisk 4267aae4e5 chore(web): raise bundle budget 150→165 KB gz (#27)
The index chunk is a feature-rich admin SPA bundle (Base UI + TanStack Query +
react-hook-form + i18n); 150 KB was set early and now trips on most features.
The combobox itself lands in the lazy object-form chunk.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 10:59:12 +02:00
logaritmisk c84b84b153 feat(web): use searchable combobox for term/authority fields on the object form (#27) 2026-06-06 10:41:28 +02:00
logaritmisk 0188e730e8 feat(web): searchable combobox (Base UI) for term/authority options (#27) 2026-06-06 10:37:01 +02:00
logaritmisk 6e52a331bc docs(plans): searchable term/authority combobox picker (#27)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 10:24:39 +02:00
logaritmisk 8e57789dd7 docs(specs): searchable term/authority combobox picker (#27)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 10:20:26 +02:00
logaritmisk 8ed747c6a7 merge: wire Spectrum seed into runtime via 'server seed' (#14)
CI / web (push) Has been cancelled
server seed subcommand (idempotent; migrates then seeds the baseline Spectrum
cataloguing vocabularies + field definitions), just seed recipe, README step.
Closes #14.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 07:18:40 +02:00
logaritmisk dd02bddb07 docs: 'just seed' recipe + README seed step (#14) 2026-06-06 00:18:11 +02:00
logaritmisk 6ebcc10405 feat(server): 'seed' subcommand wiring the Spectrum cataloguing seed (#14) 2026-06-06 00:15:19 +02:00
logaritmisk 325917a98e docs(plans): wire Spectrum seed via 'server seed' subcommand (#14)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 00:12:15 +02:00
logaritmisk d74500f901 docs(specs): wire Spectrum seed into runtime via 'server seed' (#14)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 22:55:27 +02:00
logaritmisk 7d40a2cd56 chore: use cargo-nextest as the test runner
- .config/nextest.toml: hang-timeout profile (warn 60s, kill 120s)
- justfile: 'just test' = cargo nextest run --workspace + cargo test --doc
- CLAUDE.md: refresh stale Status + Commands for the real workspace + nextest

163 tests run in ~7s (vs multi-minute serial cargo test).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 22:36:59 +02:00
logaritmisk 873efe199f merge: reference-data edit/delete lifecycle (#30 + #36)
CI / web (push) Has been cancelled
Backend update/delete endpoints (audited, 409+count when referenced) and in-place
frontend edit/delete UI for vocabularies (rename), terms, authorities, and field
definitions. Shared DeleteConfirmDialog; Storybook stories. Closes #30, #36.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 22:30:00 +02:00
logaritmisk 27caaa9787 test+refactor: audit-row assertions + uniform PATCH rollback (review follow-ups)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 21:04:09 +02:00
logaritmisk c9120848f5 feat(web): edit/delete authorities in place (#30) 2026-06-05 20:35:26 +02:00
logaritmisk 83ca506702 feat(web): rename vocabularies + edit/delete terms in place (#30) 2026-06-05 20:32:35 +02:00
logaritmisk 65ca79f2bd feat(web): edit/delete field definitions on /fields (in-place edit pane) (#36) 2026-06-05 20:24:57 +02:00
logaritmisk 194f18c8ed feat(web): reusable DeleteConfirmDialog with in-use handling + stories 2026-06-05 20:12:23 +02:00
logaritmisk 282e6430d4 feat(web): mutation hooks + InUseError + i18n for reference-data edit/delete 2026-06-05 20:06:23 +02:00
logaritmisk 78c950d2ee chore(web): regenerate API types for reference-data edit/delete
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 20:04:03 +02:00
logaritmisk 3e7c6ad712 feat: edit/delete field definitions — audited, blocked when in use (#36)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 19:58:38 +02:00