improve(ui): sessions page fits on one screen with per-session overrides in a row drawer#100943
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e4b9a1931
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .sessions-table th:nth-child(5), | ||
| .sessions-table td:nth-child(5) { | ||
| display: none; |
There was a problem hiding this comment.
Keep status visible in category grouping
When the saved Group-by setting is category, renderSessions inserts the optional Group column before Kind, so Status becomes the 5th column rather than Runtime. This unconditional mobile rule therefore hides the live/failed/idle status at widths ≤900px for any user who had category grouping enabled, even though the default 8-column roster tests still pass.
Useful? React with 👍 / 👎.
| // Any interactive toggle ends deep-link mode so reloads return the roster. | ||
| this.deepLinkSessionKey = null; |
There was a problem hiding this comment.
Reload after leaving a deep-linked session
When the page is opened with ?session=..., the loader/result is already narrowed to that single session via deepLinkSessionKey; this toggle only clears the field for future requests and returns without calling loadSessions, so collapsing or opening the row leaves the roster stuck on the one deep-linked session until some later manual refresh/filter change. Capture whether a deep link was active and reload after clearing it so the advertised interactive escape actually restores the full roster.
Useful? React with 👍 / 👎.
|
Codex review: found issues before merge. Reviewed July 6, 2026, 1:26 PM ET / 17:26 UTC. Summary PR surface: Source +153, Tests +5. Total +158 across 50 files. Reproducibility: yes. from source inspection: category mode inserts Group before Status while the mobile CSS hides nth-child(5), and route deep links narrow sessions.list while the toggle exits without reloading. I did not execute browser tests in this read-only review. Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep the drawer redesign, but make the responsive rules safe for both default and category column layouts and reload the full roster whenever interactive UI exits route deep-link mode before merge. Do we have a high-confidence way to reproduce the issue? Yes from source inspection: category mode inserts Group before Status while the mobile CSS hides nth-child(5), and route deep links narrow sessions.list while the toggle exits without reloading. I did not execute browser tests in this read-only review. Is this the best way to solve the issue? No; the redesign is a plausible and useful direction, but this head is not the best mergeable solution until it preserves saved category-mode status visibility and reloads after leaving deep-link mode. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 3ad77774f0e5. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +153, Tests +5. Total +158 across 50 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
2e4b9a1 to
df47b91
Compare
…owing; update mobile column hiding for new roster
df47b91 to
9debfc2
Compare
|
Merged via squash.
|
…des in a row drawer (openclaw#100943) * feat(ui): redesign sessions page into roster table with details drawer * fix(ui): decouple sessions drawer expansion from deep-link query narrowing; update mobile column hiding for new roster * fix(ui): reload open session drawer when a session gains compaction checkpoints
…des in a row drawer (openclaw#100943) * feat(ui): redesign sessions page into roster table with details drawer * fix(ui): decouple sessions drawer expansion from deep-link query narrowing; update mobile column hiding for new roster * fix(ui): reload open session drawer when a session gains compaction checkpoints
What Problem This Solves
The Sessions page in the Control UI rendered every per-session control as its own table column: Key, Label, Kind, Status, Runtime, Updated, Tokens, Compaction, Thinking, Fast, Verbose, Reasoning, Actions (plus Group in category mode). The table had a hard
min-width: 1340px, so on typical windows the Fast/Verbose/Reasoning/Actions columns were cut off behind a horizontal scrollbar, the Label column showed truncated stub inputs, and the header burned its subtitle on the raw session-store filesystem path. Filters lived in a separate collapsible panel above a second toolbar row, spending ~200px of vertical space before the first row of data.Why This Change Was Made
The redesign reshapes the page around what operators scan for (identity → status → activity) and moves what they occasionally edit (per-session overrides) into a per-row details drawer:
sessions.patchsemantics), the session stats grid, and the compaction history with branch/restore. Checkpoint counts show as a pill on the drawer disclosure; checkpoint data is only fetched for rows that report checkpoints.filtersCollapsedstate) is deleted.components.cssinto a dedicatedsessions.css, replacing inlinestyle=attributes on selects/inputs with classes. This also fixes two latent bugs: badge colors referenced undefined--success/--warningtokens (now--ok/--warn), and the row action buttons (.icon-btn) had no styles anywhere, so pin/archive glyphs painted as solid black squares on dark surfaces.Behavior is otherwise unchanged: sorting, pagination, bulk select/delete, grouping with drag-and-drop category assignment, workboard capture, pin/archive rules, deep-linking a session via
?session=, and the archived-only view all work as before (the deep-link state was renamedexpandedCheckpointKey→expandedSessionKeyto match the drawer model).Two follow-ups from review landed in the branch:
?session=deep-link key that narrows thesessions.listquery. Previously the two shared one field, so expanding any drawer and then refreshing collapsed the roster to that single session; a route deep link still narrows the initial load, and any interactive toggle or filter edit returns to the full roster.layout.mobile.csswere rewritten for the new 8-column roster (they still targeted the old 14-column indexes and would have hidden the Status column on tablets): Runtime hides ≤900px, Tokens ≤768px, Kind and Updated ≤500px.User Impact
Operators see the whole session roster on one screen — no sideways scrolling to reach actions, no truncated label inputs, and a header that says what is happening (
6 sessions · 2 live) instead of printing a filesystem path. Per-session tuning is one click away in the drawer, grouped and labeled, instead of four bare dropdowns per row. Session-list i18n keys for the removed filter panel were dropped and new ones added; all 20 locale bundles were regenerated withpnpm ui:i18n:sync.Evidence
Sessions roster, before → after (1440×900, dark, deterministic mock-gateway fixture):
Expanded row, before → after (overrides now live in the drawer):
Validation:
pnpm test ui/src/pages/sessions/view.test.ts— 31 tests pass (filter callbacks, grouping + drag/drop, thinking/fast/verbose/reasoning patch semantics in the drawer, status badges, checkpoint disclosure, empty states, pagination selection).pnpm test ui/src/pages/sessions/view.browser.test.ts— 4/4 viewports pass (375/430/768/1440px): no horizontal body overflow, status and actions stay visible inside the scroll container with the updated mobile column hiding.tsgoUI test lane clean;pnpm check:changedclean.startControlUiE2eServer+installMockGatewayharness for pixel-identical fixtures across before/after.