diff --git a/apps/web/app/hooks/use-workspace-watcher.ts b/apps/web/app/hooks/use-workspace-watcher.ts index f5c8aa6b13e..5821e602c25 100644 --- a/apps/web/app/hooks/use-workspace-watcher.ts +++ b/apps/web/app/hooks/use-workspace-watcher.ts @@ -30,7 +30,7 @@ export function useWorkspaceWatcher() { const [parentDir, setParentDir] = useState(null); const [workspaceRoot, setWorkspaceRoot] = useState(null); const [openclawDir, setOpenclawDir] = useState(null); - const [activeProfile, setActiveProfile] = useState(null); + const [activeWorkspace, setActiveWorkspace] = useState(null); // Show hidden (dot) files/folders const [showHidden, setShowHidden] = useState(false); @@ -41,8 +41,7 @@ export function useWorkspaceWatcher() { // Each fetch increments the counter; only the latest version's response is applied. const fetchVersionRef = useRef(0); - // Bumping this key forces the SSE connection to tear down and reconnect - // (used after profile switches so the watcher targets the new workspace). + // Bumping this key forces the SSE connection to tear down and reconnect. const [sseReconnectKey, setSseReconnectKey] = useState(0); // Fetch the workspace tree from the tree API @@ -57,7 +56,7 @@ export function useWorkspaceWatcher() { setExists(data.exists ?? false); setWorkspaceRoot(data.workspaceRoot ?? null); setOpenclawDir(data.openclawDir ?? null); - setActiveProfile(data.profile ?? null); + setActiveWorkspace(data.workspace ?? data.profile ?? null); setLoading(false); } } catch { @@ -120,7 +119,7 @@ export function useWorkspaceWatcher() { void fetchTree(); }, [fetchTree]); - // Force SSE reconnection + tree refresh (e.g. after profile switch). + // Force SSE reconnection + tree refresh. const reconnect = useCallback(() => { setSseReconnectKey((k) => k + 1); void fetchTree(); @@ -218,5 +217,5 @@ export function useWorkspaceWatcher() { }; }, [browseDirRaw, fetchWorkspaceTree, sseReconnectKey]); - return { tree, loading, exists, refresh, reconnect, browseDir, setBrowseDir, parentDir, workspaceRoot, openclawDir, activeProfile, showHidden, setShowHidden }; + return { tree, loading, exists, refresh, reconnect, browseDir, setBrowseDir, parentDir, workspaceRoot, openclawDir, activeWorkspace, showHidden, setShowHidden }; } diff --git a/apps/web/app/workspace/page.tsx b/apps/web/app/workspace/page.tsx index 17f0a232e01..1ed1eebd561 100644 --- a/apps/web/app/workspace/page.tsx +++ b/apps/web/app/workspace/page.tsx @@ -31,6 +31,7 @@ import { ObjectFilterBar } from "../components/workspace/object-filter-bar"; import { type FilterGroup, type SortRule, type SavedView, emptyFilterGroup, serializeFilters } from "@/lib/object-filters"; import { UnicodeSpinner } from "../components/unicode-spinner"; import { resolveActiveViewSyncDecision } from "./object-view-active-view"; +import { resetWorkspaceStateOnSwitch } from "./workspace-switch"; // --- Types --- @@ -358,7 +359,7 @@ function WorkspacePageInner() { tree, loading: treeLoading, exists: workspaceExists, refresh: refreshTree, reconnect: reconnectWorkspaceWatcher, browseDir, setBrowseDir, parentDir: browseParentDir, workspaceRoot, openclawDir, - activeProfile: workspaceProfile, + activeWorkspace: workspaceName, showHidden, setShowHidden, } = useWorkspaceWatcher(); @@ -534,16 +535,28 @@ function WorkspacePageInner() { setSidebarRefreshKey((k) => k + 1); }, []); - const handleProfileChanged = useCallback(() => { - setBrowseDir(null); - setActivePath(null); - setContent({ kind: "none" }); - setChatSidebarPreview(null); - setShowChatSidebar(true); - reconnectWorkspaceWatcher(); - refreshSessions(); - void refreshContext(); - }, [reconnectWorkspaceWatcher, refreshContext, refreshSessions, setBrowseDir]); + const handleWorkspaceChanged = useCallback(() => { + resetWorkspaceStateOnSwitch({ + setBrowseDir, + setActivePath, + setContent, + setChatSidebarPreview, + setShowChatSidebar, + setActiveSessionId, + setActiveSubagentKey, + resetMainChat: () => { + void chatRef.current?.newSession(); + }, + replaceUrlToWorkspace: () => { + router.replace("/workspace", { scroll: false }); + }, + reconnectWorkspaceWatcher, + refreshSessions, + refreshContext: () => { + void refreshContext(); + }, + }); + }, [reconnectWorkspaceWatcher, refreshContext, refreshSessions, router, setBrowseDir]); const handleDeleteSession = useCallback( async (sessionId: string) => { @@ -1323,8 +1336,8 @@ function WorkspacePageInner() { onExternalDrop={handleSidebarExternalDrop} showHidden={showHidden} onToggleHidden={() => setShowHidden((v) => !v)} - activeProfile={workspaceProfile} - onProfileChanged={handleProfileChanged} + activeWorkspace={workspaceName} + onWorkspaceChanged={handleWorkspaceChanged} mobile onClose={() => setSidebarOpen(false)} /> @@ -1362,8 +1375,8 @@ function WorkspacePageInner() { onToggleHidden={() => setShowHidden((v) => !v)} width={leftSidebarWidth} onCollapse={() => setLeftSidebarCollapsed(true)} - activeProfile={workspaceProfile} - onProfileChanged={handleProfileChanged} + activeWorkspace={workspaceName} + onWorkspaceChanged={handleWorkspaceChanged} /> )}