refactor(surface): drop the deprecated main-tab aliases and dead diagram surface

MainTab/activeMainTab/setActiveMainTab/setMainTabGuard were deprecated
mirrors of the surface names — every call site now uses
activeSurface/setActiveSurface/setSurfaceGuard directly and the aliases
are gone, including the persisted mirror field.

The 'diagram' surface had no way to open it (navigateToDiagram had no
callers except a .drawio attachment click that navigated to a surface
nothing rendered); the surface, DiagramView, and its store plumbing are
removed, and a .drawio attachment now opens in the file panel.

?tab= deep links map to the matching context-panel surface instead of
setting a main-area surface nothing renders, and a persisted non-chat
surface can no longer rehydrate into a blank main area.
This commit is contained in:
Bohdan Triapitsyn
2026-08-24 16:21:05 +03:00
parent 8b7d7803de
commit 4da7604d7d
28 changed files with 151 additions and 285 deletions
@@ -14,7 +14,7 @@ import { Button } from '@/components/ui/button';
import { Icon } from "@/components/icon/Icon";
import { cn } from '@/lib/utils';
import { sessionEvents } from '@/lib/sessionEvents';
import type { MainTab } from '@/stores/useUIStore';
import type { WorkspaceSurface } from '@/stores/useUIStore';
import { SessionFolderItem } from '../SessionFolderItem';
import type { SortableDragHandleProps } from './sortableItems';
import { DroppableFolderWrapper, SessionFolderDndScope } from './sessionFolderDnd';
@@ -84,7 +84,7 @@ type Props = {
alwaysShowActions: boolean;
activeProjectId: string | null;
setActiveProjectIdOnly: (id: string) => void;
setActiveMainTab: (tab: MainTab) => void;
setActiveSurface: (tab: WorkspaceSurface) => void;
setSessionSwitcherOpen: (open: boolean) => void;
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null; targetFolderId?: string; target?: 'chat' | 'project' }) => void;
addSessionToFolder: (scopeKey: string, folderId: string, sessionId: string) => void;
@@ -265,7 +265,7 @@ const areGroupPropsEqual = (prev: Props, next: Props): boolean => {
&& prev.alwaysShowActions === next.alwaysShowActions
&& prev.activeProjectId === next.activeProjectId
&& prev.setActiveProjectIdOnly === next.setActiveProjectIdOnly
&& prev.setActiveMainTab === next.setActiveMainTab
&& prev.setActiveSurface === next.setActiveSurface
&& prev.setSessionSwitcherOpen === next.setSessionSwitcherOpen
&& prev.openNewSessionDraft === next.openNewSessionDraft
&& prev.addSessionToFolder === next.addSessionToFolder
@@ -307,7 +307,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
alwaysShowActions,
activeProjectId,
setActiveProjectIdOnly,
setActiveMainTab,
setActiveSurface,
setSessionSwitcherOpen,
openNewSessionDraft,
addSessionToFolder,
@@ -880,7 +880,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
depth={0}
onNewSession={() => {
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
setActiveMainTab('chat');
setActiveSurface('chat');
if (mobileVariant) setSessionSwitcherOpen(false);
openNewSessionDraft({
selectedProjectId: projectId,
@@ -1248,7 +1248,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
onClick={(event) => {
event.stopPropagation();
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
setActiveMainTab('chat');
setActiveSurface('chat');
if (mobileVariant) setSessionSwitcherOpen(false);
openNewSessionDraft({ selectedProjectId: projectId, directoryOverride: group.directory });
}}
@@ -16,7 +16,7 @@ import type { SortableDragHandleProps } from './sortableItems';
import { ProjectHeaderIdentity, SortableGroupItem, SortableProjectItem } from './sortableItems';
import { formatProjectLabel } from './utils';
import { useI18n } from '@/lib/i18n';
import type { MainTab } from '@/stores/useUIStore';
import type { WorkspaceSurface } from '@/stores/useUIStore';
import type { ProjectSortOrder } from '@/stores/useSessionDisplayStore';
import { streamPerfCount } from '@/stores/utils/streamDebug';
import { Icon } from '@/components/icon/Icon';
@@ -91,7 +91,7 @@ type Props = {
alwaysShowActions: boolean;
toggleProject: (id: string) => void;
setActiveProjectIdOnly: (id: string) => void;
setActiveMainTab: (tab: MainTab) => void;
setActiveSurface: (tab: WorkspaceSurface) => void;
setSessionSwitcherOpen: (open: boolean) => void;
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null }) => void;
openNewWorktreeDialog: () => void;
@@ -362,7 +362,7 @@ function SidebarProjectsListComponent(props: Props): React.ReactNode {
}}
onNewSession={() => {
if (projectKey !== props.activeProjectId) props.setActiveProjectIdOnly(projectKey);
props.setActiveMainTab('chat');
props.setActiveSurface('chat');
if (props.mobileVariant) props.setSessionSwitcherOpen(false);
props.openNewSessionDraft({
selectedProjectId: projectKey,
@@ -371,7 +371,7 @@ function SidebarProjectsListComponent(props: Props): React.ReactNode {
}}
onNewWorktreeSession={() => {
if (projectKey !== props.activeProjectId) props.setActiveProjectIdOnly(projectKey);
props.setActiveMainTab('chat');
props.setActiveSurface('chat');
props.openNewWorktreeDialog();
}}
onManageWorktrees={() => props.openWorktreesPage(projectKey)}
@@ -2,7 +2,7 @@ import React from 'react';
import type { Session } from '@opencode-ai/sdk/v2';
import type { SessionGroup, SessionNode } from '../types';
import { normalizePath } from '../utils';
import type { MainTab } from '@/stores/useUIStore';
import type { WorkspaceSurface } from '@/stores/useUIStore';
import { useUIStore } from '@/stores/useUIStore';
import { useSessionUIStore } from '@/sync/session-ui-store';
@@ -22,7 +22,7 @@ type Args = {
newSessionDraftOpen: boolean;
mobileVariant: boolean;
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null }) => void;
setActiveMainTab: (tab: MainTab) => void;
setActiveSurface: (tab: WorkspaceSurface) => void;
setSessionSwitcherOpen: (open: boolean) => void;
};
@@ -101,7 +101,7 @@ export const useProjectSessionSelection = (args: Args): void => {
newSessionDraftOpen,
mobileVariant,
openNewSessionDraft,
setActiveMainTab,
setActiveSurface,
setSessionSwitcherOpen,
} = args;
@@ -205,7 +205,7 @@ export const useProjectSessionSelection = (args: Args): void => {
previousActiveProjectRef.current = activeProjectId;
if (selection.kind === 'open-draft') {
setActiveMainTab('chat');
setActiveSurface('chat');
if (mobileVariant) {
setSessionSwitcherOpen(false);
}
@@ -232,7 +232,7 @@ export const useProjectSessionSelection = (args: Args): void => {
openNewSessionDraft,
projectSections,
projectSessionMeta,
setActiveMainTab,
setActiveSurface,
setSessionSwitcherOpen,
setActiveSessionByProject,
]);
@@ -3,7 +3,7 @@ import type { Session } from '@opencode-ai/sdk/v2';
import { toast } from '@/components/ui';
import { copyTextToClipboard } from '@/lib/clipboard';
import { useI18n } from '@/lib/i18n';
import type { MainTab } from '@/stores/useUIStore';
import type { WorkspaceSurface } from '@/stores/useUIStore';
import { useUIStore } from '@/stores/useUIStore';
import { streamPerfMark } from '@/stores/utils/streamDebug';
import { useSessionUIStore } from '@/sync/session-ui-store';
@@ -30,7 +30,7 @@ type Args = {
sessionSearchQuery: string;
setSessionSearchQuery: (value: string) => void;
setIsSessionSearchOpen: (open: boolean) => void;
setActiveMainTab: (tab: MainTab) => void;
setActiveSurface: (tab: WorkspaceSurface) => void;
setSessionSwitcherOpen: (open: boolean) => void;
setCurrentSession: (sessionId: string | null, directoryHint?: string | null) => void;
updateSessionTitle: (id: string, title: string) => Promise<void>;
@@ -79,7 +79,7 @@ export const useSessionActions = (args: Args) => {
};
if (args.mobileVariant) {
args.setActiveMainTab('chat');
args.setActiveSurface('chat');
args.setSessionSwitcherOpen(false);
}