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>
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>
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>
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>
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>
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>
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>
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>
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>
- .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>
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>
Storybook 10.4.2 (react-vite) with the addon-vitest/a11y/docs/mcp addons.
.storybook/preview.tsx wired to the real provider tree (QueryClient + ConfigProvider
+ MemoryRouter), real CSS + i18n, and MSW reusing src/test/handlers.ts. 8 colocated
stories for real components (Button/Badge/Input/Checkbox/VisibilityBadge/LabelEditor/
Highlight/SearchResultRow) incl. one CssCheck. Boilerplate removed.
112 web tests (existing 85 survived + 27 storybook); typecheck/lint/build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#38 enum-type SearchHitView.visibility + tighten VisibilityBadge prop.
#28 set_fields 422 carries the offending field (FieldErrorView); the object form
highlights it (both direct-edit and create-redirect paths name the field).
#41 normalize localized_text values to the default language on save.
#26 pin pnpm via packageManager + align CI to pnpm 11.
85 web tests; api suite green; bundle 145.8 KB gz; en/sv parity.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>