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
@@ -31,11 +31,17 @@ import { useI18n } from '@/lib/i18n';
|
||||
|
||||
export interface WorktreeSectionContentProps {
|
||||
projectRef?: { id: string; path: string } | null;
|
||||
/**
|
||||
* 'all' renders setup commands + the worktree list (settings panel);
|
||||
* 'list-only' renders just the list (the Worktrees page — setup commands
|
||||
* stay a settings concern).
|
||||
*/
|
||||
sections?: 'all' | 'list-only';
|
||||
}
|
||||
|
||||
const SETUP_COMMANDS_SAVE_DELAY_MS = 450;
|
||||
|
||||
export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({ projectRef: projectRefProp = null }) => {
|
||||
export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({ projectRef: projectRefProp = null, sections = 'all' }) => {
|
||||
const { t } = useI18n();
|
||||
const { isMobile, isTablet } = useDeviceInfo();
|
||||
const alwaysShowActions = isMobile || isTablet;
|
||||
@@ -369,6 +375,7 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{sections === 'all' ? (
|
||||
<ProjectSettingsSubsection
|
||||
title={t('settings.projects.page.section.worktree')}
|
||||
settingsItem="projects.worktree"
|
||||
@@ -428,6 +435,7 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
||||
</div>
|
||||
)}
|
||||
</ProjectSettingsSubsection>
|
||||
) : null}
|
||||
|
||||
<ProjectSettingsSubsection
|
||||
title={t('settings.openchamber.worktrees.list.title')}
|
||||
@@ -440,7 +448,9 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
||||
{t('settings.openchamber.worktrees.list.empty')}
|
||||
</p>
|
||||
) : (
|
||||
<div className={cn('space-y-1', PROJECT_SETTINGS_CONTROL_WIDTH)}>
|
||||
// The settings panel keeps its narrow control column; the full-page
|
||||
// Worktrees surface lets rows use the whole content width.
|
||||
<div className={cn('space-y-1', sections === 'all' && PROJECT_SETTINGS_CONTROL_WIDTH)}>
|
||||
{availableWorktrees.map((worktree) => (
|
||||
<div
|
||||
key={worktree.path}
|
||||
@@ -451,9 +461,6 @@ export const WorktreeSectionContent: React.FC<WorktreeSectionContentProps> = ({
|
||||
<p className="typography-meta min-w-0 truncate text-foreground">
|
||||
{worktree.label || worktree.branch || t('settings.openchamber.worktrees.list.detachedHead')}
|
||||
</p>
|
||||
<span className="typography-micro flex-shrink-0 self-center rounded bg-sidebar-accent/40 px-1.5 py-[1px] leading-none text-muted-foreground/60">
|
||||
OpenCode
|
||||
</span>
|
||||
</div>
|
||||
<p className="typography-micro truncate text-muted-foreground/60">
|
||||
{formatPathForDisplay(worktree.path, homeDirectory)}
|
||||
|
||||
@@ -12,11 +12,18 @@ import type { ProjectEntry } from '@/lib/api/types';
|
||||
type ProjectSettingsPanelProps = {
|
||||
project: ProjectEntry | null;
|
||||
onIdentitySave: (data: ProjectIdentitySaveData) => void | Promise<void>;
|
||||
/**
|
||||
* The project-edit dialog hides the worktree section — worktrees have
|
||||
* their own full-page surface (project menu → Manage worktrees). Settings
|
||||
* keeps the full panel.
|
||||
*/
|
||||
showWorktrees?: boolean;
|
||||
};
|
||||
|
||||
export const ProjectSettingsPanel: React.FC<ProjectSettingsPanelProps> = ({
|
||||
project,
|
||||
onIdentitySave,
|
||||
showWorktrees = true,
|
||||
}) => {
|
||||
const form = useProjectIdentityForm(project);
|
||||
|
||||
@@ -41,7 +48,7 @@ export const ProjectSettingsPanel: React.FC<ProjectSettingsPanelProps> = ({
|
||||
<div className="space-y-0">
|
||||
<ProjectIdentityFields form={form} />
|
||||
<ProjectActionsSection projectRef={projectRef} />
|
||||
<WorktreeSectionContent projectRef={projectRef} />
|
||||
{showWorktrees ? <WorktreeSectionContent projectRef={projectRef} /> : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user