swarm-ui: persist table filters, add reset button, multi-select, negate
Per mara's issue: tables should remember their filters (with a reset
button), the labels filter should be multi-select, and any filter should
support negation (search vs exclude).
All in the shared Table component (ui/table/Table.tsx), used by
AgentsPage/HivesPage/IssueReportPage:
- filters now persist via the same useLocalSetting hook IssueReportPage
already used for its own state, keyed by a new required storageKey
prop (required, not optional, so no caller can forget it and every
table gets persistence for free)
- a small 'reset filters' button clears every column's filter at once,
shown only when at least one is active
- new filterMode: "multiselect" (+ a filterValues extractor, alongside
the existing single-value filterValue) renders a checkbox list and
matches on any overlap - IssueReportPage's own bespoke label-checkbox
sidebar is folded into this instead of staying a second, separate
filter mechanism
- a negate toggle ('exclude') sits under every filter mode's control,
applying uniformly to text/select/multiselect
Verified: tsc --noEmit and the esbuild bundle both clean.
This commit is contained in:
parent
948525de09
commit
915c6c6f92
7 changed files with 386 additions and 197 deletions
|
|
@ -141,3 +141,60 @@
|
|||
font: inherit;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* `filterMode: "multiselect"` — a scrollable checkbox list rather than
|
||||
a `<select multiple>`, which needs a modifier key to pick more than
|
||||
one option and reads as unfamiliar to most operators; a plain
|
||||
checkbox list needs neither. `max-height` + scroll keeps a
|
||||
long option set (many labels) from pushing the popover off-screen. */
|
||||
.ui-table-filter-multiselect {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3em;
|
||||
max-height: 12em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.ui-table-filter-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35em;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* The negate toggle sits under every filter mode's own control (mara:
|
||||
"you should be able to change if the filter is negated or not") —
|
||||
a hairline rule separates it from the control above so "exclude"
|
||||
doesn't read as one more option belonging to that control. */
|
||||
.ui-table-filter-negate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35em;
|
||||
margin-top: 0.5em;
|
||||
padding-top: 0.5em;
|
||||
border-top: 1px solid var(--border);
|
||||
color: var(--muted);
|
||||
font-size: 0.85em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* One button clears every column's filter on this table at once (mara:
|
||||
"have a small reset filters btn") — text-button styling matching
|
||||
`.ui-table-sort-button`'s "no chrome, just a clickable label"
|
||||
treatment, not a full `Badge`/bordered-button — this is a quiet
|
||||
secondary action, not a primary one. */
|
||||
.ui-table-reset-filters {
|
||||
display: inline-block;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0 0 0.5em;
|
||||
font: inherit;
|
||||
font-size: 0.85em;
|
||||
color: var(--muted);
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-table-reset-filters:hover {
|
||||
color: var(--fg);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue