From 68704e15b47139f45855378d63d42d90977f090e Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:05:50 +0200 Subject: [PATCH] feat(ui): exchange list reads ?attr= URL params and renders filter chips (carries forward pre-existing attribute-badge color-by-key tweak) --- ui/src/pages/Dashboard/Dashboard.module.css | 20 +++++++ ui/src/pages/Dashboard/Dashboard.tsx | 62 +++++++++++++++++---- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/ui/src/pages/Dashboard/Dashboard.module.css b/ui/src/pages/Dashboard/Dashboard.module.css index 63d4d9dd..610beb90 100644 --- a/ui/src/pages/Dashboard/Dashboard.module.css +++ b/ui/src/pages/Dashboard/Dashboard.module.css @@ -139,3 +139,23 @@ color: var(--text-muted); } +.attrChip { + display: inline-flex; + align-items: center; + gap: 4px; + margin-left: 8px; + padding: 2px 8px; + background: var(--bg-hover); + border: 1px solid var(--border); + border-radius: 10px; + font-size: 11px; + font-family: var(--font-mono); + color: var(--text-primary); +} + +.attrChip code { + background: transparent; + font-family: inherit; + color: var(--text-primary); +} + diff --git a/ui/src/pages/Dashboard/Dashboard.tsx b/ui/src/pages/Dashboard/Dashboard.tsx index 65ec6ba7..b720aca9 100644 --- a/ui/src/pages/Dashboard/Dashboard.tsx +++ b/ui/src/pages/Dashboard/Dashboard.tsx @@ -15,6 +15,8 @@ import { import { useEnvironmentStore } from '../../api/environment-store' import type { ExecutionSummary } from '../../api/types' import { attributeBadgeColor } from '../../utils/attribute-color' +import { parseAttrParam, formatAttrParam } from '../../utils/attribute-filter'; +import type { AttributeFilter } from '../../utils/attribute-filter'; import { formatDuration, statusLabel } from '../../utils/format-utils' import styles from './Dashboard.module.css' import tableStyles from '../../styles/table-section.module.css' @@ -84,7 +86,7 @@ function buildColumns(hasAttributes: boolean): Column[] {
{shown.map(([k, v]) => ( - + ))} {overflow > 0 && +{overflow}} @@ -147,6 +149,12 @@ export default function Dashboard({ onExchangeSelect, activeExchangeId }: Dashbo const navigate = useNavigate() const [searchParams, setSearchParams] = useSearchParams() const textFilter = searchParams.get('text') || undefined + const attributeFilters = useMemo( + () => searchParams.getAll('attr') + .map(parseAttrParam) + .filter((f): f is AttributeFilter => f != null), + [searchParams], + ); const [selectedId, setSelectedId] = useState(activeExchangeId) const [sortField, setSortField] = useState('startTime') const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc') @@ -180,12 +188,13 @@ export default function Dashboard({ onExchangeSelect, activeExchangeId }: Dashbo environment: selectedEnv, status: statusParam, text: textFilter, + attributeFilters: attributeFilters.length > 0 ? attributeFilters : undefined, sortField, sortDir, offset: 0, - limit: textFilter ? 200 : 50, + limit: textFilter || attributeFilters.length > 0 ? 200 : 50, }, - !textFilter, + !textFilter && attributeFilters.length === 0, ) // ─── Rows ──────────────────────────────────────────────────────────────── @@ -221,17 +230,46 @@ export default function Dashboard({ onExchangeSelect, activeExchangeId }: Dashbo
- {textFilter ? ( + {textFilter || attributeFilters.length > 0 ? ( <> - Search: “{textFilter}” - + {textFilter && ( + <> + Search: “{textFilter}” + + + )} + {attributeFilters.map((f, i) => ( + + {f.value === undefined + ? <>has {f.key} + : <>{f.key} = {f.value}} + + + ))} ) : 'Recent Exchanges'}