Skip to content

fix(sidebar): restore the in-flow "Show all older sessions" row - #8720

Merged
buluoray merged 1 commit into
mainfrom
fix/restore-older-sessions-inflow-hint
Sep 5, 2026
Merged

fix(sidebar): restore the in-flow "Show all older sessions" row#8720
buluoray merged 1 commit into
mainfrom
fix/restore-older-sessions-inflow-hint

Conversation

@CrysisDeu

@CrysisDeu CrysisDeu commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Closes #8710

Summary

Restores the in-flow "Show all older sessions" row that follows the last session of a sidebar lane (list-view root lane and flat view). It opens the Older Sessions pane and fetches history — the same action as the footer — and is hidden while the pane is open.

The row was removed in #1211 as a duplicate of the Older Sessions footer. The two answer different questions: the footer is a persistent structural control for a user who already knows the pane exists; the in-flow row sits where a user scanning the list runs out of rows without finding their chat — exactly where a session evicted from the open-tab list (idle eviction, restart, cleanup, a closed tab) has gone. A new user has no other cue that sessions move anywhere, so removing the row removed the only in-flow answer to "where did my chat go". Details in #8710.

What changed

  • ChatSidebar.tsx: one renderOlderSessionsHint(lane) helper, mounted in the flat lane (after the hidden-folders reveal row) and in the root lane's ungrouped bucket after the dormant-sessions expander, so it stays the lane's last line even when rows are folded. Hidden while historyOpen.
  • Catalog key pages.chatSidebar.show_all_older_sessions restored in en.manual.json and all 11 translations (ja/ko newly authored, consistent with their existing "older sessions" wording); en-XA regenerated with npm run i18n:pseudo.
  • New test ChatSidebar.olderSessionsHint.test.tsx: last element of the root bucket after the dormant expander; opens the pane and calls the sessions API; hidden while the pane is open via the footer and back when it closes; same for the flat lane.
  • Capture harness scripts/capture-older-sessions-hint.mjs (real built SPA, stubbed API).

Footer unchanged. No backend change.

Screenshots

Root lane, light — the row follows the dormant expander:

root lane light

Root lane, dark:

root lane dark

After clicking it — the pane opens with the closed sessions, the row is gone:

pane opened

Flat view, dark:

flat lane dark

Pattern harvest

Rule candidate: a "remove as duplicate" refactor must first name the distinct user context each of the two affordances serves, not just their shared action. #1211 deleted the in-flow row purely because it fired the same handler as the footer, treating equal behavior as equal purpose. But an affordance's value is where it appears, not only what it does: the footer answers "open the pane" for a user who already knows it exists; the in-flow row answers "where did my chat go" for a user who has scanned to the end of the list and found nothing. A dedup that collapses two placements into one silently removes discovery for the second context.

Gate this class points at: the reviewer/design-lane checklist for a deletion labeled "duplicate" — require the PR to state the user journey the removed instance covered and confirm a surviving instance covers the same journey, not merely the same code path. Not expressible as a semgrep/static rule: "same handler, different discovery context" is a UX-intent judgement, not a syntactic pattern in the diff. The regression-guard is behavioral: the new ChatSidebar.olderSessionsHint.test.tsx pins the in-flow row as the lane's last line after the dormant expander and asserts it opens the pane, so a future dedup that removes it again reddens a test instead of shipping silently.

Verification

Static gates run locally (this desk does not run test suites — CI is the test oracle):

  • npx tsc -b clean; npx eslint on the changed files clean; npm run i18n:check green.
  • Feature-map and brand-name gates pass against origin/main.
  • The 4 new vitest cases, the full website suite, and the backend cross-surface guards are left to CI.

@CrysisDeu
CrysisDeu requested a review from a team September 5, 2026 09:36
@CrysisDeu
CrysisDeu requested a review from a team as a code owner September 5, 2026 09:36
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — ✅ PASS

Design-level review of f5842a1cff86fe7cdac34994edaf0ca0fa667792 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

A documented reversal of an over-aggressive de-clutter, with the rationale for both controls now pinned in a code comment so it won't be re-removed.

[DESIGN-REVIEWED] f5842a1

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5) — 🟡 CONCERNS

UX-level review of f5842a1cff86fe7cdac34994edaf0ca0fa667792 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

UX-Verdict: CONCERNS

Keyboard activation of the new row strands focus: the button unmounts itself, so the user who just asked "where did my chat go" also loses their place.

Watch

  • Activating the row sets historyOpen, and renderOlderSessionsHint then return null — the focused button unmounts, focus drops to <body>, and the pane opens at the far end of the sidebar with no announcement. A keyboard or screen-reader user must re-Tab from the top to reach what they just opened; the footer toggle (line 7062) keeps focus, so only this path regresses. Low frequency (discovery moment) × friction × every keyboard use. Fix: after setHistoryOpen(true), move focus into the pane (its SearchInput) or onto the footer's aria-expanded toggle.

Suggestions

  • Add w-full to renderOlderSessionsHint's button className: both sibling in-flow rows (renderStaleSection line 3220, renderHiddenReveal line 5445) are full-width, so this row's text-width hit target and snug hover pill read as a different control; text-[11px] would complete the match.

[UX-REVIEWED] f5842a1

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of f5842a1cff86fe7cdac34994edaf0ca0fa667792 and found no blocking issues.

This comment is updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] f5842a1

False positive or not applicable? A repository writer can comment:
/ai-review override gpt f5842a1cff86fe7cdac34994edaf0ca0fa667792: <one-sentence reason>

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed f5842a1cff86fe7cdac34994edaf0ca0fa667792 — this comment is updated in place on each push.

Review details

No candidates were proposed by the discovery pass, and none survive to add. The diff is a UI-only change: an always-rendered (when the pane is closed) in-flow "Show all older sessions" button dispatching the same action as the existing footer, the matching i18n key across all catalogs, a dev-only screenshot harness, and a test. I re-derived the behavioral surface — the hint's action path (setHistoryOpen(true) + fetchHistory(false)) mirrors the unconditionally-rendered footer, the root/flat render paths are mutually exclusive so no duplicate data-testid, and the key is present in every locale plus the pseudolocale and en.manual. No reachable crash, data loss, boundary crossing, or blocking: true rule violation lands on a changed line.

No findings.

[OPUS-REVIEWED] f5842a1

Verdict parsed from the review's SHA-scoped output markers for commit f5842a1cff86fe7cdac34994edaf0ca0fa667792.

False positive or not applicable? A repository writer can comment:
/ai-review override fable f5842a1cff86fe7cdac34994edaf0ca0fa667792: <one-sentence reason>

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — 🟡 CONCERNS

Premise-level review of f5842a1cff86fe7cdac34994edaf0ca0fa667792 — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

First-Principles-Verdict: CONCERNS

The fix's own worst case is uncovered: a list-view sidebar emptied entirely by eviction renders no row, because the hint mounts inside the ungrouped bucket's existence guard.

What this change ships

Intent: give a user who scanned to the end of the sidebar without finding their chat an in-flow pointer to Older Sessions — a FIX for reported defect #8710.

  1. "Show all older sessions" row ends the list-view root lane — justified (reported defect)
  2. Same row ends the flat-view lane — justified, declared
  3. Row hides while the Older Sessions pane is open — justified, declared
  4. Label ships in all 12 locales — mandated by the i18n invariant
  5. Regression test pins placement and behavior — justified, guards the feat: redesign sidebar folders and de-clutter the sessions sidebar #1211 failure mode
  6. Capture harness script — conventional (395 capture-*.mjs siblings counted)
  7. Four PNGs under temp-screenshots/ — documented evidence convention (PR template, cleanup workflow)

Watch

  • The hint's stated harm ("runs out of rows without finding their chat") is most acute when every session was evicted, but renderOlderSessionsHint('root') sits inside (rootFolders.length > 0 || ungroupedSlots.length > 0) (ChatSidebar.tsx:6697), so the fully-emptied list-view lane — the default view for a folderless user — shows nothing. Flat view mounts it unconditionally (ChatSidebar.tsx:6638); list view should match. One unfixed sibling of the fix's own cause, same file, in scope.
  • 3 sidebar lanes counted (flat, list, column strip at ChatSidebar.tsx:6746); 2 get the row. The description declares the scope but never says why a column-view user scanning a lane's end is excluded.

[FIRST-PRINCIPLES-REVIEWED] f5842a1

The text row below the last session of a lane opens the Older Sessions
pane in place. It was removed as a duplicate of the pane's footer, but
the two answer different questions: the footer is a persistent control
for a user who already knows the pane exists, while the in-flow row sits
where a user scanning the list runs out of rows without finding their
chat -- exactly where a session evicted from the open-tab list (idle
eviction, restart, cleanup, a closed tab) has gone. A new user has no
other cue that sessions move anywhere, so removing the row removed the
only in-flow answer to "where did my chat go".

Restore it in the list-view root lane and in flat view, placed after the
dormant-sessions expander so it stays the lane's last line, and hidden
while the pane is open. The catalog key comes back in all 12 languages.

Closes #8710
@CrysisDeu
CrysisDeu force-pushed the fix/restore-older-sessions-inflow-hint branch from 52ddbe3 to f5842a1 Compare September 5, 2026 13:03
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 5, 2026
@buluoray
buluoray merged commit 2052424 into main Sep 5, 2026
67 of 73 checks passed
@buluoray
buluoray deleted the fix/restore-older-sessions-inflow-hint branch September 5, 2026 21:06
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Sep 5, 2026
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.

Sidebar lost its in-flow "Show all older sessions" hint below the last session

2 participants