Skip to content

Dashboard sortable table column headers - #353

Open
MillanWangGadget wants to merge 1 commit into
mainfrom
mill/sortableTableHeaders
Open

Dashboard sortable table column headers#353
MillanWangGadget wants to merge 1 commit into
mainfrom
mill/sortableTableHeaders

Conversation

@MillanWangGadget

@MillanWangGadget MillanWangGadget commented Jun 5, 2026

Copy link
Copy Markdown

Dashboard Sortable Table Column Headers

Summary

Adds sortable column headers to the web UI dashboard tables. Two distinct
mechanisms are introduced, one for each kind of table:

  1. Client-side sorting for non-paginated tables — clicking a header sorts
    the rows in-browser with no server round trip.
  2. Server-side sorting for the paginated tenants table — clicking a header
    reloads the page with sort/dir query parameters so the sort applies
    across all pages, not just the visible one.

Client-side sorting (non-paginated tables)

A self-contained script in templates/base.html upgrades any
<table data-sortable> into a sortable table:

  • Each header (<th>) becomes clickable and gets a sort indicator ( idle,
    / when active). Add data-no-sort to a <th> to exclude it.
  • First click on a column opens descending if numeric, ascending if text
    (matching the server-side tenants convention); clicking the active column
    toggles direction.
  • A column is treated as numeric only if every non-empty cell parses as a
    number — mixing numeric and string comparison in one sort would be
    non-transitive, so one comparison type is chosen per column. Empty cells in a
    numeric column sort as the smallest value.
  • A cell may carry data-sort-value="..." to override its sort key when the
    displayed text isn't directly comparable (e.g. P5, 1.50 MiB).
  • It re-scans content swapped in by htmx (htmx:afterSwap), so the SQL results
    table stays sortable after a query.

Tables marked data-sortable in this commit:

Template Table(s)
cluster.html Parent shards, shards, cluster members
job.html Metadata, limits
queue.html Current holders, waiting requests
queues.html Concurrency queues
shard.html Sorted runs
sql_result.html SQL query results
tenant.html Active queue entries, waiting jobs

data-sort-value overrides added:

  • queue.html — priority cell (data-sort-value="{{ req.priority }}" so P5
    sorts by 5).
  • shard.html — size cell (data-sort-value="{{ sr.estimated_size_bytes }}"
    so 1.50 MiB sorts by raw byte count).

Server-side sorting (paginated tenants table)

The tenants table is paginated, so sorting must happen on the server to order
rows across the whole dataset rather than just the current page. Changes in
src/webui.rs:

  • TenantsParams gains sort and dir query params, defaulting to
    scheduled / desc (the prior hard-coded order).
  • TENANT_SORT_COLUMNS defines the five sortable columns
    (name, jobs, scheduled, running, terminal) with display labels.
  • normalize_tenant_sort validates the requested column, falling back to
    scheduled for anything unrecognized (guards against query-string injection).
  • tenant_column_is_numeric — only name is textual; this drives default
    click direction (numeric → desc, text → asc).
  • sort_tenant_rows sorts in place by the chosen column/direction with a stable
    ascending tiebreaker on tenant name (tiebreaker stays ascending regardless of
    primary direction).
  • build_tenant_sort_headers produces SortHeader structs (label, href,
    is_active, indicator) consumed by the template. The active column's link
    toggles its direction; inactive columns open in their default direction.
  • tenants_handler replaces the old hard-coded sort_by with this configurable
    path and passes sort, dir, and sort_headers into the template.
  • SortedRunView gains estimated_size_bytes (raw u64) so the shard template
    can expose it as a numeric sort key.

The tenants.html template renders the headers in a loop, each as a link with
an active arrow (/) or idle . Pagination Previous/Next links now carry
sort and dir so the sort persists when changing pages.

Tests

A #[cfg(test)] module in src/webui.rs covers the server-side logic:

  • normalize_tenant_sort accepts known columns and falls back to scheduled (including a DROP TABLE injection-style input).
  • tenant_column_is_numeric classification.
  • Sorting by jobs respects direction; sorting by name is alphabetical.
  • Ties broken by name ascending regardless of primary direction.
  • Each sort key selects the correct field.
  • Headers cover all columns with correct labels.
  • Active header toggles direction and shows the right arrow; per_page is preserved in the href.
  • Inactive header default direction matches the client convention (numeric → desc, text → asc).

@MillanWangGadget
MillanWangGadget force-pushed the mill/sortableTableHeaders branch from b3dd0ad to 4ad386f Compare June 5, 2026 13:08
Comment thread src/webui.rs

/// Sort tenant rows in place by the given (already-normalized) column and
/// direction, with a stable tiebreaker on the tenant name.
fn sort_tenant_rows(rows: &mut [TenantSummaryRow], sort_key: &str, ascending: bool) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this causes all queries in the tenant view to time out in our staging env.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants