hyperhive#4020, mara. TableColumn gets two new optional extractors,
each one the whole signal for its capability (mara: 'why separate
selector and flag?' — dropped the sortable/filterable booleans that
would've said the same thing twice and could disagree with the
extractor's presence):
- sortBy: (row) => string | number — column is click-to-sort iff
present. Table owns the sort state (one active column, header click
cycles none -> ascending -> descending), since a rendered cell often
isn't the sortable value itself (e.g. AgentsPage's status column
renders a Badge, not a plain string).
- filterValue: (row) => string — column is filterable iff present. A
text input row under the headers, substring match case-insensitive.
Client-side only, no backend change - every consuming page already
fetches its full row set. Wired into AgentsPage and HivesPage, the two
pages with a real per-row Table. Left IssueReportPage alone (already
has its own purpose-built sort + label/hide-blocked filters, predates
this and covers its own domain better than a generic per-column text
filter would) and JobsPage alone (renders an indented state tree via
JobqGraph, no column table at all despite what my original scoping
comment assumed).
Verified: typecheck + build clean, nix fmt clean, static render of the
actual built CSS confirms the new sort-header + filter-row markup
doesn't break table layout.