Skip to content

dashboard: make the agents table columns configurable - #225

Merged
raine merged 5 commits into
raine:mainfrom
alebiscotto:dashboard-columns
Aug 21, 2026
Merged

dashboard: make the agents table columns configurable#225
raine merged 5 commits into
raine:mainfrom
alebiscotto:dashboard-columns

Conversation

@alebiscotto

Copy link
Copy Markdown
Contributor

Why

The agents table renders Status, Time and Title in a fixed order. Reading the title — usually the interesting part when scanning a list of agents — means skipping over an elapsed timer that sits between the status and it. The sidebar already lets its fields be arranged freely through sidebar.templates, so this brings the same idea to the dashboard in the smallest form that fits the table.

What

New dashboard.columns option, listing the columns that follow the fixed #, Project, Worktree, Git and optional PR ones:

dashboard:
  columns: [status, title, time]

Any of status, time and title, in any order. A column left out is not rendered, so columns: [status, title] drops the timer entirely. Duplicates are ignored and an empty list falls back to the default, so a malformed config degrades to today's layout rather than to a broken table.

Header cells, row cells and width constraints previously repeated the same order in three places. They now all derive from the configured list, so they cannot drift apart — the Fill(1) that lets Title take the remaining width follows the column wherever it is placed.

Defaults are unchanged: without the option the table renders exactly as before.

Testing

  • Four unit tests covering the default, a reordered list, duplicate handling and the empty-list fallback.
  • Full suite green (1421 passed), cargo fmt --check clean, and cargo clippy --all-targets reports nothing in the touched files.
  • Checked in a real terminal with columns: [status, title, time]: header and rows both follow the new order and the title keeps the flexible width.

The columns after Git were fixed as status, time, title, so reading the title
meant skipping over a timer that is rarely the interesting part. Header cells,
row cells and width constraints now all derive from dashboard.columns, which
keeps them in sync by construction, and an omitted column simply is not
rendered. Defaults are unchanged.
raine added 4 commits August 21, 2026 09:32
The agents table let only the trailing Status, Time and Title columns be
arranged. Project, Worktree, Git and PR stayed in a fixed block ahead of them,
so the layouts people actually want - title first, or a table without the
project name - were out of reach. dashboard.columns now lists every column of
the table except the `#` jump key, which stays pinned first because it labels
the row rather than describing the agent.

Listing a column renders it, omitting it drops it, and the order of the list is
the order on screen. The PR column keeps its existing behaviour of appearing
only once an agent has a pull request or checks to report, wherever it sits in
the list.

The header row, the row cells and the width constraints are built from the same
list in one place, build_agent_table, so they cannot drift apart. The
per-agent cell data moved from a twelve element tuple into AgentRowData, since
positional access no longer matches the display order. Taking a palette rather
than the whole App makes that function renderable in tests: three of them draw
the table into a TestBackend and assert the header and row text for the
default order, a reordered list and a list that leaves columns out.

Defaults are unchanged, and an unknown column name is a config parse error that
names the valid values.
The `#` jump key column was pinned to the front of the agents table while every
other column could be arranged freely. It is now an ordinary entry in
dashboard.columns under the name `number`, so it can sit anywhere in the table
or be dropped from it.

The name is `number` rather than `#` because `#` starts a comment in YAML and
would have to be quoted in the list.

Dropping the column only hides the label; `1`-`9` still jump to the first nine
rows, since the jump keys come from row position rather than from the rendered
cell. With no column left to special case, the header cells, row cells and
width constraints of the whole table now come from a single pass over the
configured list.

Defaults are unchanged.
Review of the column ordering feature surfaced two rendering bugs and a stale
docs page.

Title was always Constraint::Fill(1), and a Fill column absorbs slack at its own
position rather than at the end of the row. Any list that placed title before
another column therefore opened a gap and pinned everything after it to the
right edge. The example the documentation recommended,
[number, status, title, project, worktree, git, pr, time], was exactly that
shape, so the one non-default layout users were told to try looked the worst.
Title now takes the remaining width only as the trailing column and otherwise
sizes to its content, which leaves the slack at the right edge where the table's
Flex::Start default puts it.

The PR column drops out of the list until an agent has a pull request or checks
to report. For `columns: [pr]` that filter emptied the list, and ratatui renders
a table with no columns as a blank pane with no indication why. Hiding it now
stops short of emptying the table, so the column stays with its header and
fetch spinner. The filter moved into `visible_columns` so it can be tested
without an App.

The dashboard overview listed the worktree column as "Agent" and omitted PR
entirely, names that became user-facing config values with this feature. It now
lists every column with the value that selects it.
The dashboard has two tabs, and only the agents table reads this option, so
`dashboard.columns` claimed more than it configured and left no room for the
worktrees table to gain the same treatment later.

The key is `agent_columns`, with `DashboardColumn` renamed to `AgentColumn` to
match. Singular follows the surrounding config, where a qualifier is singular
(worktree_dir, window_prefix, status_icons, sidebar.agent_icons) and a plural
means the field is itself a collection (panes, layouts, windows, agents).

The option stays flat rather than nesting under a per-tab section, because
show_check_counts already applies to both tables; a `dashboard.agents` section
would imply a split that the rest of the dashboard config does not have.
@raine raine changed the title dashboard: let the trailing table columns be reordered dashboard: make the agents table columns configurable Aug 21, 2026
@raine
raine merged commit 38ff3c5 into raine:main Aug 21, 2026
3 checks passed
@raine

raine commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR

I extended it a bit on the way in.

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