feat(ui): sidebar redesign — project zones, grouping modes, full-page surfaces (#2480)
* checkpoint: flatten sidebar core (flat sessions, zones, single mode, folders flat) * checkpoint: sidebar nav + scheduled/archive full-page surfaces, recent zone header * checkpoint: worktrees management surface via project menu * checkpoint: docs, i18n, validation for sidebar redesign * checkpoint: unified row/zone geometry, recent backfill, tooltips everywhere, primary spinner * checkpoint: branch icon marker, date moved to rich tooltip, recent back to pure time window * checkpoint: PR state on branch markers + tooltip, no reserved right space, aligned show-more, instant tooltips * checkpoint: reserve hover-action space so title text is not overlapped * checkpoint: tighten hover-action reserve * checkpoint: color-only unread emphasis to avoid title reflow * checkpoint: drop new-subfolder action, folder actions overlay on hover * checkpoint: fix sticky project headers (sticky on trigger div), stuck elevation * checkpoint: full-bleed semibold zone headers, no top scroll fade * checkpoint: headers without background tint (typography-only emphasis) * checkpoint: recent header flush with scroll top (no pre-stick bump) * checkpoint: shared tooltip provider with grouping (instant handoff between rows) * checkpoint: blur pointer-click focus so hover chrome hides on mouse-leave * checkpoint: tooltip closeDelay bridges inter-row gap * checkpoint: nav above controls, merged view dropdown, project-scoped bulk selection, cross-worktree folders * checkpoint: folder header tooltip with full path name * checkpoint: true page surfaces (hidden chat, header title, close-on-select), multirun page, run-now jump, folders on top, controls row polish * checkpoint: rename mode — dual-instance outside-click fix, no vertical shift * checkpoint: session grouping mode toggle (by-worktree default, flat option) * checkpoint: worktree header — hover padding reserve + delete worktree action * checkpoint: frosted sticky header backing under desktop vibrancy * checkpoint: align worktree sub-header with project header icon column * checkpoint: restore worktree group DnD reorder; dense vibrancy header tint (Chromium mask+backdrop-filter) * checkpoint: vibrancy — drop scroller mask so backdrop-filter samples rows (Chromium backdrop-root limitation) * checkpoint: vibrancy headers use opaque sidebar tone (Electron transparent-window backdrop-filter bug) * checkpoint: nav collapsed to one row (New session + surface icons), mirrors Add project row * checkpoint: raise sticky zone headers above row action layers (z-20) * checkpoint: New session as full-width CTA + single quiet toolbar row * checkpoint: New session row back to quiet text form above the toolbar * checkpoint: align toolbar left icon with New session icon column * checkpoint: hoverless flat header controls (color-only hover states) * checkpoint: sticky project headers toggle in view dropdown (default on) * checkpoint: full-page surfaces adapted — archive directory filter panel, scheduled master-detail, multirun without duplicate title bar * checkpoint: multirun joins mutually exclusive surface set * checkpoint: surfaces leave via navigation only (no close/cancel buttons), robust close-on-new-session, drop dead MultiRunWindow * checkpoint: no scheduled header description, aligned empty-worktree note, collapse/expand covers worktree groups * checkpoint: overlay scrollbar above sticky zone headers * checkpoint: archive delete icons reveal on hover with padding shift * checkpoint: new worktrees surface at top of the worktree list * checkpoint: no grab cursor on worktree headers * checkpoint: worktrees page list-only with inline action, no worktrees in edit dialog, drop menu ellipsis * checkpoint: worktrees page uses full content width * checkpoint: worktrees header — 'in' instead of em dash, no description * checkpoint: drop legacy OpenCode badge from worktree list, tooltip without OpenCode mention * review: bound pr summary cache
This commit is contained in:
committed by
GitHub
parent
5787ea5d49
commit
1291cde5c2
@@ -1,16 +1,24 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
|
||||
type SessionDisplayMode = 'default' | 'minimal';
|
||||
|
||||
type ProjectSortOrder = 'manual' | 'a-z' | 'z-a' | 'date-added' | 'recent';
|
||||
|
||||
// 'by-worktree' keeps per-worktree sub-headers inside each project zone
|
||||
// (parallel-work overview); 'flat' merges everything into one recency list.
|
||||
type SessionGroupingMode = 'by-worktree' | 'flat';
|
||||
|
||||
type SessionDisplayStore = {
|
||||
displayMode: SessionDisplayMode;
|
||||
sessionGroupingMode: SessionGroupingMode;
|
||||
setSessionGroupingMode: (mode: SessionGroupingMode) => void;
|
||||
/** Project/recent zone headers stick to the top while their zone scrolls. */
|
||||
stickyZoneHeaders: boolean;
|
||||
toggleStickyZoneHeaders: () => void;
|
||||
showRecentSection: boolean;
|
||||
// VS Code only: the compact webview keeps archived buckets inline because it
|
||||
// has no room for the full Archive page. Web/desktop ignore this flag and
|
||||
// always route archived sessions to the Archive page instead.
|
||||
showArchivedSessions: boolean;
|
||||
projectSortOrder: ProjectSortOrder;
|
||||
setDisplayMode: (mode: SessionDisplayMode) => void;
|
||||
setShowRecentSection: (show: boolean) => void;
|
||||
setShowArchivedSessions: (show: boolean) => void;
|
||||
toggleRecentSection: () => void;
|
||||
@@ -22,15 +30,19 @@ export const migrateSessionDisplayState = (
|
||||
persisted: unknown,
|
||||
version: number,
|
||||
): Partial<SessionDisplayStore> => {
|
||||
const state = (persisted ?? {}) as Partial<SessionDisplayStore>;
|
||||
if (version < 1) {
|
||||
return { ...state, displayMode: 'minimal', projectSortOrder: 'manual' };
|
||||
}
|
||||
const state = (persisted ?? {}) as Partial<SessionDisplayStore> & {
|
||||
displayMode?: string;
|
||||
};
|
||||
if (version < 2) {
|
||||
return { ...state, projectSortOrder: 'manual' };
|
||||
state.projectSortOrder = 'manual';
|
||||
}
|
||||
if (version < 3 && state.projectSortOrder === 'recent') {
|
||||
return { ...state, projectSortOrder: 'manual' };
|
||||
state.projectSortOrder = 'manual';
|
||||
}
|
||||
if (version < 4) {
|
||||
// v4 removes the default/minimal display mode: the sidebar now has a
|
||||
// single row layout. Drop the stale key from persisted state.
|
||||
delete state.displayMode;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
@@ -38,15 +50,16 @@ export const migrateSessionDisplayState = (
|
||||
export const useSessionDisplayStore = create<SessionDisplayStore>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
displayMode: 'minimal',
|
||||
sessionGroupingMode: 'by-worktree',
|
||||
setSessionGroupingMode: (mode) => set({ sessionGroupingMode: mode }),
|
||||
stickyZoneHeaders: true,
|
||||
toggleStickyZoneHeaders: () => set((state) => ({ stickyZoneHeaders: !state.stickyZoneHeaders })),
|
||||
showRecentSection: true,
|
||||
// Default to HIDDEN so the pre-hydration state matches the quiet/safe
|
||||
// option: archived sessions must never flash visible on startup and then
|
||||
// disappear once the persisted preference rehydrates. Users who opted into
|
||||
// showing archived have `true` persisted, which is preserved on rehydrate.
|
||||
// disappear once the persisted preference rehydrates.
|
||||
showArchivedSessions: false,
|
||||
projectSortOrder: 'manual',
|
||||
setDisplayMode: (mode) => set({ displayMode: mode }),
|
||||
setShowRecentSection: (show) => set({ showRecentSection: show }),
|
||||
setShowArchivedSessions: (show) => set({ showArchivedSessions: show }),
|
||||
toggleRecentSection: () => set((state) => ({ showRecentSection: !state.showRecentSection })),
|
||||
@@ -55,15 +68,13 @@ export const useSessionDisplayStore = create<SessionDisplayStore>()(
|
||||
}),
|
||||
{
|
||||
name: 'session-display-mode',
|
||||
version: 3,
|
||||
// v0 shipped 'default' as the only/initial mode, so most existing users
|
||||
// have it persisted by accident rather than choice. Nudge everyone onto
|
||||
// minimal once so the mode can be evaluated before removing it entirely.
|
||||
version: 4,
|
||||
// v1→v2 adds projectSortOrder using the canonical manual ordering.
|
||||
// v2→v3 replaces the previously shipped recent default with manual.
|
||||
// v3→v4 removes displayMode (single sidebar row layout).
|
||||
migrate: migrateSessionDisplayState,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export type { ProjectSortOrder };
|
||||
export type { ProjectSortOrder, SessionGroupingMode };
|
||||
|
||||
Reference in New Issue
Block a user