From 99105841b1191091e8aecc15f95b452c814049ef Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Thu, 26 Jun 2025 19:28:36 -0700 Subject: [PATCH] fix(workspaces init): fix switch workspace fully + first workflow should be selected when you enter app (#561) * add target workspace id for switch workspace" * fix lint * workspace initialization bug fixes * fix lint --------- Co-authored-by: Vikhyath Mondreti --- .../w/components/sidebar/sidebar.tsx | 14 ++++++-- .../app/workspace/[workspaceId]/w/page.tsx | 36 +++++++++++++++---- apps/sim/stores/workflows/registry/store.ts | 20 +++++++++-- apps/sim/stores/workflows/registry/types.ts | 1 + 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx index ace5b0b0c3..2fda0a0a10 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx @@ -32,7 +32,12 @@ const IS_DEV = process.env.NODE_ENV === 'development' export function Sidebar() { useGlobalShortcuts() - const { workflows, createWorkflow, isLoading: workflowsLoading } = useWorkflowRegistry() + const { + workflows, + createWorkflow, + isLoading: workflowsLoading, + targetWorkspaceId, + } = useWorkflowRegistry() const { isPending: sessionLoading } = useSession() const userPermissions = useUserPermissionsContext() const isLoading = workflowsLoading || sessionLoading @@ -62,9 +67,12 @@ export function Sidebar() { const regular: WorkflowMetadata[] = [] const temp: WorkflowMetadata[] = [] + // Use targetWorkspaceId during transitions to prevent empty sidebar + const effectiveWorkspaceId = targetWorkspaceId || workspaceId + if (!isLoading) { Object.values(workflows).forEach((workflow) => { - if (workflow.workspaceId === workspaceId || !workflow.workspaceId) { + if (workflow.workspaceId === effectiveWorkspaceId || !workflow.workspaceId) { if (workflow.marketplaceData?.status === 'temp') { temp.push(workflow) } else { @@ -91,7 +99,7 @@ export function Sidebar() { } return { regularWorkflows: regular, tempWorkflows: temp } - }, [workflows, isLoading, workspaceId]) + }, [workflows, isLoading, workspaceId, targetWorkspaceId]) // Create workflow handler const handleCreateWorkflow = async (folderId?: string) => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/page.tsx b/apps/sim/app/workspace/[workspaceId]/w/page.tsx index 8792827f07..e78ae9f0fe 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/page.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/page.tsx @@ -7,20 +7,44 @@ import { useWorkflowRegistry } from '@/stores/workflows/registry/store' export default function WorkflowsPage() { const router = useRouter() - const { workflows, isLoading } = useWorkflowRegistry() + const { workflows, isLoading, loadWorkflows } = useWorkflowRegistry() const params = useParams() - const workspaceId = params.workspaceId + const workspaceId = params.workspaceId as string + + // Always load workflows for the current workspace to ensure we have the correct ones + useEffect(() => { + if (!isLoading) { + loadWorkflows(workspaceId) + } + }, [workspaceId, loadWorkflows, isLoading]) useEffect(() => { // Wait for workflows to load if (isLoading) return - const workflowIds = Object.keys(workflows) + // Filter workflows for this workspace only + const workspaceWorkflows = Object.values(workflows).filter( + (workflow) => workflow.workspaceId === workspaceId + ) - // If we have workflows, redirect to the first one - if (workflowIds.length > 0) { - router.replace(`/workspace/${workspaceId}/w/${workflowIds[0]}`) + // If we have workflows for this workspace, redirect to the first one + if (workspaceWorkflows.length > 0) { + // Sort by last modified date (newest first) - same logic as sidebar + const sortedWorkflows = workspaceWorkflows.sort((a, b) => { + const dateA = + a.lastModified instanceof Date + ? a.lastModified.getTime() + : new Date(a.lastModified).getTime() + const dateB = + b.lastModified instanceof Date + ? b.lastModified.getTime() + : new Date(b.lastModified).getTime() + return dateB - dateA + }) + + const firstWorkflowId = sortedWorkflows[0].id + router.replace(`/workspace/${workspaceId}/w/${firstWorkflowId}`) return } diff --git a/apps/sim/stores/workflows/registry/store.ts b/apps/sim/stores/workflows/registry/store.ts index 4968c2dac2..7270d2f039 100644 --- a/apps/sim/stores/workflows/registry/store.ts +++ b/apps/sim/stores/workflows/registry/store.ts @@ -155,7 +155,17 @@ async function fetchWorkflowsFromDB(workspaceId?: string): Promise { if (!currentState.activeWorkflowId && Object.keys(registryWorkflows).length > 0) { const firstWorkflowId = Object.keys(registryWorkflows)[0] useWorkflowRegistry.setState({ activeWorkflowId: firstWorkflowId }) - logger.info(`Set first workflow as active: ${firstWorkflowId}`) + logger.info(`Set first workflow as active: ${firstWorkflowId}`, { + workspaceId, + totalWorkflows: Object.keys(registryWorkflows).length, + workflowIds: Object.keys(registryWorkflows), + }) + } else { + logger.info(`Not setting active workflow`, { + currentActiveWorkflowId: currentState.activeWorkflowId, + workflowCount: Object.keys(registryWorkflows).length, + workspaceId, + }) } logger.info( @@ -254,6 +264,8 @@ export const useWorkflowRegistry = create()( error: null, // Initialize deployment statuses deploymentStatuses: {}, + // Track target workspace during transitions to prevent empty sidebar + targetWorkspaceId: null, // Set loading state setLoading: (loading: boolean) => { @@ -321,12 +333,13 @@ export const useWorkflowRegistry = create()( // Clear current workspace state resetWorkflowStores() - // Update state + // Update state with target workspace ID for sidebar filtering set({ activeWorkflowId: null, workflows: {}, isLoading: true, error: null, + targetWorkspaceId: workspaceId, }) // Fetch workflows for the new workspace @@ -338,9 +351,12 @@ export const useWorkflowRegistry = create()( set({ error: `Failed to switch workspace: ${error instanceof Error ? error.message : 'Unknown error'}`, isLoading: false, + targetWorkspaceId: null, }) } finally { setWorkspaceTransitioning(false) + // Clear target workspace ID after transition completes + set({ targetWorkspaceId: null }) } }, diff --git a/apps/sim/stores/workflows/registry/types.ts b/apps/sim/stores/workflows/registry/types.ts index 5e9234b28b..3fc215c31d 100644 --- a/apps/sim/stores/workflows/registry/types.ts +++ b/apps/sim/stores/workflows/registry/types.ts @@ -27,6 +27,7 @@ export interface WorkflowRegistryState { isLoading: boolean error: string | null deploymentStatuses: Record + targetWorkspaceId: string | null } export interface WorkflowRegistryActions {