Frontend UX: object list should be a scannable, sortable, filterable table #44
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: High. From a frontend UX audit. The object list is the screen curators triage in all day; today it's a thin nav list, not a data overview ("easy to get an overview of the data" is a core goal).
Problems
web/src/objects/object-list.tsx:63-82renders each object as one<li>showing onlyobject_number+object_name+ a visibility badge. The list payload already carries the fullAdminObjectView(current_location,current_owner,number_of_objects), so surfacing more columns is essentially free on the wire.list_objectsaccepts onlylimit/offset(nosort/order_by/visibility). The only filter/free-text lives in a separatesearch-panel.tsxwith a different interaction model (infinite "Load more" vs offset paging) — two parallel browsing UIs. A curator can't do "all drafts" or "sort by object number" from the list.LIMIT=50hardcoded (object-list.tsx:10); no page-size selector, page jump, first/last, or keyboard paging. (Thefrom–to of totalfooter is good.)created_at/updated_atfields onAdminObjectView— a backend schema gap. "What did I touch recently / what's stale" is the most common triage axis and is currently impossible.<ul>/<li>/<a>markup isn't grid-navigable (noaria-sort, no column headers).Suggested fixes
<table>/aria-sortsemantics.sort/order_by+ avisibilityfilter param; surface visibility filter chips and column-sort in the list. Unify the list and the search panel into one browsing surface (pick offset-paging or infinite-scroll for both).created_at/updated_atto the object API view to back an "Updated" column + sort.Source: frontend UX/design audit, 2026-06-06.
Done in
0a88a86(merged tomain)./objectsis now a full-width, scannable data table: server-sidesort/order+visibilityfilter + a Postgresqquick-filter on number/name (injection-safe — ORDER BY from a whitelisted enum, all values bound) with a correct filtered total;created_at/updated_atexposed onAdminObjectViewand an Updated column (no migration — the columns already existed). All table state (sort/order/visibility/q/limit/offset) lives in the URL, so it's shareable and survives the row→detail→back round-trip. Pagination has prev/next + page-size (25/50/100/200).Also landed the shell pieces (overlap with #58): a collapsible icon sidebar (lucide + Base UI tooltip, persisted, auto-collapse on narrow) and responsive object detail — a right pane on wide viewports / a Base UI Drawer on narrow — at a canonical, shareable
/objects/:id.Deferred to follow-ups: Meilisearch full-text unified into the table's search box (the dedicated Search screen stays for now) and the object-detail content fixes (#45).