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 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>
Per WAI-ARIA, aria-selected must be on the same element carrying role="tab".
The previous impl placed it on an inner <span> via the render-prop, making it
invisible to assistive technology. Move both role="tab" and aria-selected to
the NavLink, compute currentKind once from useParams, drop the render-prop.
Add a Vitest assertion that the selected tab has aria-selected="true" and an
unselected tab has aria-selected="false".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expose full-text search over catalogue objects via a new admin endpoint
backed by the Meilisearch SearchClient. Validates visibility filter values,
short-circuits on empty queries, clamps pagination, and returns 503 when
search is not configured. Registered in OpenAPI; schema.d.ts regenerated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>