Skip to content

improve(ui): sessions page fits on one screen with per-session overrides in a row drawer#100943

Merged
steipete merged 3 commits into
mainfrom
claude/trusting-cori-a398a9
Jul 6, 2026
Merged

improve(ui): sessions page fits on one screen with per-session overrides in a row drawer#100943
steipete merged 3 commits into
mainfrom
claude/trusting-cori-a398a9

Conversation

@steipete

@steipete steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

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:

  • The table drops to 8 columns (9 in category-grouping mode) with no forced horizontal scroll; user labels render as chips next to the session key instead of a column of text inputs.
  • Every row now opens a details drawer (chevron, row click, or Enter/Space) containing a new Overrides section (Label, Thinking, Fast, Verbose, Reasoning — same sessions.patch semantics), 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.
  • Search, the Updated-within/Limit fields, the Global/Unknown/Archived-only toggles, and Group-by merge into one toolbar; the separate collapsible Filters panel (and its filtersCollapsed state) is deleted.
  • The card header shows a session count and a live-session pulse instead of the store path, which moves into a tooltip on the summary line.
  • Session styles move out of components.css into a dedicated sessions.css, replacing inline style= attributes on selects/inputs with classes. This also fixes two latent bugs: badge colors referenced undefined --success/--warning tokens (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 renamed expandedCheckpointKeyexpandedSessionKey to match the drawer model).

Two follow-ups from review landed in the branch:

  • Drawer expansion is now pure UI state, decoupled from the ?session= deep-link key that narrows the sessions.list query. 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.
  • The responsive column-hiding rules in layout.mobile.css were 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 with pnpm ui:i18n:sync.

Evidence

Sessions roster, before → after (1440×900, dark, deterministic mock-gateway fixture):

Before After
before table after table

Expanded row, before → after (overrides now live in the drawer):

Before After
before details after details

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.
  • tsgo UI test lane clean; pnpm check:changed clean.
  • Codex autoreview: one P1 accepted (the drawer/deep-link coupling above) and fixed; rerun clean.
  • Screenshots captured via the startControlUiE2eServer + installMockGateway harness for pixel-identical fixtures across before/after.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: XL maintainer Maintainer-authored PR labels Jul 6, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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.

💡 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".

Comment on lines +801 to 803
.sessions-table th:nth-child(5),
.sessions-table td:nth-child(5) {
display: none;

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.

P2 Badge 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 👍 / 👎.

Comment on lines +629 to +630
// Any interactive toggle ends deep-link mode so reloads return the roster.
this.deepLinkSessionKey = null;

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.

P2 Badge 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 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 6, 2026, 1:26 PM ET / 17:26 UTC.

Summary
The branch redesigns the Control UI Sessions page into a compact roster with per-row details and overrides drawer, moves session styling into a dedicated stylesheet, updates responsive rules, tests, and generated UI locale bundles.

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.

  • Persisted UI setting affected: 1 existing localStorage preference path affected. The stored sessions group-by mode can select category mode, so responsive column rules must remain safe for upgraded users with that saved preference.

Stored data model
Persistent data-model change detected: serialized state: ui/src/pages/sessions/route.ts, serialized state: ui/src/pages/sessions/sessions-page.ts, serialized state: ui/src/pages/sessions/view.browser.test.ts, serialized state: ui/src/pages/sessions/view.test.ts, serialized state: ui/src/pages/sessions/view.ts, serialized state: ui/src/styles/sessions.css, and 6 more. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Fix the category-mode mobile status visibility and add/extend browser coverage for that saved group-by layout.
  • Reload the full roster when interactive actions exit a route deep link, then refresh the targeted Sessions tests/proof.

Risk before merge

  • [P1] Merging as-is can break an existing user's saved category group-by preference on tablet-width layouts by hiding the Status column.
  • [P1] Route-deep-linked Sessions pages can remain stuck on the single loaded session after an interactive collapse until a later manual refresh or filter reload.

Maintainer options:

  1. Fix saved-category and deep-link paths before merge (recommended)
    Update the responsive selectors/tests for category mode and reload after clearing deep-link mode so existing saved UI state keeps working.
  2. Accept the UI compatibility risk
    Maintainers could intentionally accept category-mode tablet status loss and deep-link escape friction, but that would leave known operator regressions in the redesign.

Next step before merge

  • [P2] The maintainer-labeled PR has concrete P2 blockers that should be fixed and reviewed on the branch before merge.

Security
Cleared: No concrete security or supply-chain concern found; the diff is Control UI rendering, styles, tests, and generated locale metadata with no workflow, dependency, lockfile, secret, or code-execution surface changes.

Review findings

  • [P2] Preserve status in grouped mobile tables — ui/src/styles/layout.mobile.css:775-777
  • [P2] Reload after leaving a session deep link — ui/src/pages/sessions/sessions-page.ts:629-633
Review details

Best 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:

  • [P2] Preserve status in grouped mobile tables — ui/src/styles/layout.mobile.css:775-777
    This previous blocker is still present at the current head. In category mode, renderSessions inserts the Group column before Kind, making Status the fifth column, but this <=900px rule hides nth-child(5). Since group-by mode is persisted, users who saved category grouping will lose the live/failed/idle status on tablet-width layouts.
    Confidence: 0.95
  • [P2] Reload after leaving a session deep link — ui/src/pages/sessions/sessions-page.ts:629-633
    This previous blocker is still present at the current head. A route opened with ?session=... is loaded through a narrowed sessions.list query; this handler clears deepLinkSessionKey but returns on collapse without calling loadSessions, so the roster remains stuck on that single row until some later manual refresh. Capture whether deep-link mode was active and reload the full roster when interactive actions exit it.
    Confidence: 0.94

Overall correctness: patch is incorrect
Overall confidence: 0.92

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3ad77774f0e5.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: The PR changes behavior for users with the existing saved sessions group-by preference and can hide status on narrower layouts.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.
  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.

Label justifications:

  • P2: This is a normal-priority Control UI improvement with concrete but limited operator-facing regressions before merge.
  • merge-risk: 🚨 compatibility: The PR changes behavior for users with the existing saved sessions group-by preference and can hide status on narrower layouts.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes inspected before/after screenshots that directly show the redesigned roster and drawer in a real Control UI fixture, though they do not cover the two remaining edge regressions.
Evidence reviewed

PR surface:

Source +153, Tests +5. Total +158 across 50 files.

View PR surface stats
Area Files Added Removed Net
Source 48 1748 1595 +153
Tests 2 119 114 +5
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 50 1867 1709 +158

What I checked:

  • Repository policy read: Root and UI-scoped AGENTS.md were read; their review-depth and generated-i18n guidance were applied to this Control UI PR review. (AGENTS.md:1, 3ad77774f0e5)
  • Current main still has the wide Sessions table: Current main renders the old Sessions table with label, compaction, thinking, fast, verbose, and reasoning columns plus a 1340px table minimum, so the PR is not obsolete. (ui/src/pages/sessions/view.ts:943, 3ad77774f0e5)
  • Deep-link route still narrows the loaded roster: The PR route loader continues to pass the ?session key as sessions.list search, so an interactive escape must trigger a later full roster load. (ui/src/pages/sessions/route.ts:24, 9debfc2665ab)
  • Deep-link escape clears state without reloading: toggleSessionDetails clears deepLinkSessionKey, then returns on collapse without calling loadSessions, leaving the one-row route-loaded result in place. (ui/src/pages/sessions/sessions-page.ts:629, 9debfc2665ab)
  • Category grouping shifts Status into the hidden column: The PR inserts the optional Group column before Kind, so Status is column 5 in category mode, while the <=900px CSS rule hides nth-child(5). (ui/src/pages/sessions/view.ts:960, 9debfc2665ab)
  • Responsive browser test covers only the default column order: The PR browser fixture hardcodes the default eight-column header list, so it does not exercise category-mode column shifts. (ui/src/pages/sessions/view.browser.test.ts:38, 9debfc2665ab)

Likely related people:

  • steipete: Authored and merged the session grouping/full-controls work in PRs 100262 and 100814 that this redesign builds on; included for prior merged ownership, not merely for authoring this PR. (role: feature owner / prior merged session UI contributor; confidence: high; commits: 3b19b88db8a7, 17aa0eb8361f, e0852f05e320; files: ui/src/pages/sessions/view.ts, ui/src/pages/sessions/sessions-page.ts, ui/src/lib/sessions/grouping.ts)
  • vincentkoc: Current-main blame and log show the present Sessions page and responsive CSS in the recent refactor(workboard): localize private store types #100989 refactor, making this a useful routing signal for the current code shape. (role: recent area contributor; confidence: medium; commits: 8fc88be21643; files: ui/src/pages/sessions/view.ts, ui/src/pages/sessions/sessions-page.ts, ui/src/styles/layout.mobile.css)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-06T15:01:19.243Z sha 2e4b9a1 :: found issues before merge. :: [P2] Preserve status in grouped mobile tables | [P2] Reload after leaving a session deep link

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 6, 2026
@steipete
steipete force-pushed the claude/trusting-cori-a398a9 branch from 2e4b9a1 to df47b91 Compare July 6, 2026 16:13
@steipete
steipete force-pushed the claude/trusting-cori-a398a9 branch from df47b91 to 9debfc2 Compare July 6, 2026 17:07
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. labels Jul 6, 2026
@steipete
steipete merged commit 6f0f985 into main Jul 6, 2026
228 of 241 checks passed
@steipete
steipete deleted the claude/trusting-cori-a398a9 branch July 6, 2026 17:33
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…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
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant