dashboard: make the agents table columns configurable - #225
Merged
Conversation
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.
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.
Owner
|
Thanks for the PR I extended it a bit on the way in. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The agents table renders
Status,TimeandTitlein 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 throughsidebar.templates, so this brings the same idea to the dashboard in the smallest form that fits the table.What
New
dashboard.columnsoption, listing the columns that follow the fixed#,Project,Worktree,Gitand optionalPRones:Any of
status,timeandtitle, in any order. A column left out is not rendered, socolumns: [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 letsTitletake the remaining width follows the column wherever it is placed.Defaults are unchanged: without the option the table renders exactly as before.
Testing
cargo fmt --checkclean, andcargo clippy --all-targetsreports nothing in the touched files.columns: [status, title, time]: header and rows both follow the new order and the title keeps the flexible width.