Skip to content

Commit e452396

Browse files
Revert "fix(workspace url id bug): switch workspace bug (#564)" (#567)
This reverts commit 0049644.
1 parent 02cecd5 commit e452396

6 files changed

Lines changed: 56 additions & 94 deletions

File tree

apps/sim/app/api/workflows/sync/route.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import crypto from 'crypto'
2-
import { and, desc, eq, isNull } from 'drizzle-orm'
2+
import { and, eq, isNull } from 'drizzle-orm'
33
import { NextResponse } from 'next/server'
44
import { getSession } from '@/lib/auth'
55
import { createLogger } from '@/lib/logs/console-logger'
@@ -155,22 +155,14 @@ export async function GET(request: Request) {
155155
if (workspaceId) {
156156
// Filter by workspace ID only, not user ID
157157
// This allows sharing workflows across workspace members
158-
// Order by createdAt desc to match frontend sorting by lastModified
159-
workflows = await db
160-
.select()
161-
.from(workflow)
162-
.where(eq(workflow.workspaceId, workspaceId))
163-
.orderBy(desc(workflow.createdAt))
158+
workflows = await db.select().from(workflow).where(eq(workflow.workspaceId, workspaceId))
164159
} else {
165160
// Filter by user ID only, including workflows without workspace IDs
166-
// Order by createdAt desc to match frontend sorting by lastModified
167-
workflows = await db
168-
.select()
169-
.from(workflow)
170-
.where(eq(workflow.userId, userId))
171-
.orderBy(desc(workflow.createdAt))
161+
workflows = await db.select().from(workflow).where(eq(workflow.userId, userId))
172162
}
173163

164+
const elapsed = Date.now() - startTime
165+
174166
// Return the workflows
175167
return NextResponse.json({ data: workflows }, { status: 200 })
176168
} catch (error: any) {

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -333,45 +333,23 @@ export const WorkspaceHeader = React.memo<WorkspaceHeaderProps>(
333333
}, [sessionData?.user?.id, fetchSubscriptionStatus, fetchWorkspaces])
334334

335335
const switchWorkspace = useCallback(
336-
async (workspace: Workspace) => {
336+
(workspace: Workspace) => {
337337
// If already on this workspace, close dropdown and do nothing else
338338
if (activeWorkspace?.id === workspace.id) {
339339
setWorkspaceDropdownOpen(false)
340340
return
341341
}
342342

343-
// Close dropdown immediately for responsive feel
343+
setActiveWorkspace(workspace)
344344
setWorkspaceDropdownOpen(false)
345345

346-
try {
347-
// Update UI state optimistically
348-
setActiveWorkspace(workspace)
349-
350-
// Switch workspace data first with the explicit workspace ID
351-
// This ensures the data switch happens with the correct ID regardless of URL timing
352-
await switchToWorkspace(workspace.id)
353-
354-
// Then update URL - this will trigger useParams updates in other components
355-
router.push(`/workspace/${workspace.id}/w`)
356-
} catch (error) {
357-
// If workspace switch fails, revert the optimistic UI update
358-
logger.error('Failed to switch workspace:', error)
359-
// Revert to previous workspace if we can identify it
360-
const currentWorkspaces = workspaces
361-
const fallbackWorkspace = currentWorkspaces.find((w) => w.id === currentWorkspaceId)
362-
if (fallbackWorkspace) {
363-
setActiveWorkspace(fallbackWorkspace)
364-
}
365-
}
346+
// Use full workspace switch which now handles localStorage automatically
347+
switchToWorkspace(workspace.id)
348+
349+
// Update URL to include workspace ID
350+
router.push(`/workspace/${workspace.id}/w`)
366351
},
367-
[
368-
activeWorkspace?.id,
369-
switchToWorkspace,
370-
router,
371-
setWorkspaceDropdownOpen,
372-
workspaces,
373-
currentWorkspaceId,
374-
]
352+
[activeWorkspace?.id, switchToWorkspace, router, setWorkspaceDropdownOpen]
375353
)
376354

377355
const handleCreateWorkspace = useCallback(
@@ -394,11 +372,11 @@ export const WorkspaceHeader = React.memo<WorkspaceHeaderProps>(
394372
setWorkspaces((prev) => [...prev, newWorkspace])
395373
setActiveWorkspace(newWorkspace)
396374

397-
// Switch workspace data first with the explicit workspace ID
375+
// Use switchToWorkspace to properly load workflows for the new workspace
398376
// This will clear existing workflows, set loading state, and fetch workflows from DB
399377
switchToWorkspace(newWorkspace.id)
400378

401-
// Then update URL to include new workspace ID
379+
// Update URL to include new workspace ID
402380
router.push(`/workspace/${newWorkspace.id}/w`)
403381
}
404382
} catch (err) {
@@ -487,14 +465,10 @@ export const WorkspaceHeader = React.memo<WorkspaceHeaderProps>(
487465

488466
// If deleted workspace was active, switch to another workspace
489467
if (activeWorkspace?.id === id && updatedWorkspaces.length > 0) {
490-
const newWorkspace = updatedWorkspaces[0]
491-
setActiveWorkspace(newWorkspace)
492-
493-
// Use the specialized method for handling workspace deletion with explicit workspace ID
494-
useWorkflowRegistry.getState().handleWorkspaceDeletion(newWorkspace.id)
495-
496-
// Update URL to the new workspace
497-
router.push(`/workspace/${newWorkspace.id}/w`)
468+
// Use the specialized method for handling workspace deletion
469+
const newWorkspaceId = updatedWorkspaces[0].id
470+
useWorkflowRegistry.getState().handleWorkspaceDeletion(newWorkspaceId)
471+
setActiveWorkspace(updatedWorkspaces[0])
498472
}
499473

500474
setWorkspaceDropdownOpen(false)
@@ -504,7 +478,7 @@ export const WorkspaceHeader = React.memo<WorkspaceHeaderProps>(
504478
setIsDeleting(false)
505479
}
506480
},
507-
[workspaces, activeWorkspace?.id, router]
481+
[workspaces, activeWorkspace?.id]
508482
)
509483

510484
const openEditModal = useCallback(

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
useGlobalShortcuts,
1414
} from '@/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts'
1515
import { useSidebarStore } from '@/stores/sidebar/store'
16-
import { isWorkspaceInTransition, useWorkflowRegistry } from '@/stores/workflows/registry/store'
16+
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
1717
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
1818
import { useUserPermissionsContext } from '../providers/workspace-permissions-provider'
1919
import { CreateMenu } from './components/create-menu/create-menu'
@@ -32,16 +32,13 @@ const IS_DEV = process.env.NODE_ENV === 'development'
3232
export function Sidebar() {
3333
useGlobalShortcuts()
3434

35-
const router = useRouter()
36-
const params = useParams()
37-
const workspaceId = params.workspaceId as string
38-
3935
const { workflows, createWorkflow, isLoading: workflowsLoading } = useWorkflowRegistry()
4036
const { isPending: sessionLoading } = useSession()
4137
const userPermissions = useUserPermissionsContext()
42-
43-
// Simple loading logic: wait for workflows and valid workspaceId, plus workspace transitions
44-
const isLoading = workflowsLoading || sessionLoading || !workspaceId || isWorkspaceInTransition()
38+
const isLoading = workflowsLoading || sessionLoading
39+
const router = useRouter()
40+
const params = useParams()
41+
const workspaceId = params.workspaceId as string
4542
const pathname = usePathname()
4643

4744
const [showSettings, setShowSettings] = useState(false)
@@ -60,25 +57,41 @@ export function Sidebar() {
6057
}
6158
}, [showSettings, showHelp, showInviteMembers, setAnyModalOpen])
6259

63-
// Filter workflows for current workspace (database already sorted)
60+
// Separate regular workflows from temporary marketplace workflows
6461
const { regularWorkflows, tempWorkflows } = useMemo(() => {
65-
if (isLoading) return { regularWorkflows: [], tempWorkflows: [] }
66-
6762
const regular: WorkflowMetadata[] = []
6863
const temp: WorkflowMetadata[] = []
6964

70-
Object.values(workflows).forEach((workflow) => {
71-
if (workflow.workspaceId === workspaceId || !workflow.workspaceId) {
72-
if (workflow.marketplaceData?.status === 'temp') {
73-
temp.push(workflow)
74-
} else {
75-
regular.push(workflow)
65+
if (!isLoading) {
66+
Object.values(workflows).forEach((workflow) => {
67+
if (workflow.workspaceId === workspaceId || !workflow.workspaceId) {
68+
if (workflow.marketplaceData?.status === 'temp') {
69+
temp.push(workflow)
70+
} else {
71+
regular.push(workflow)
72+
}
7673
}
74+
})
75+
76+
// Sort by last modified date (newest first)
77+
const sortByLastModified = (a: WorkflowMetadata, b: WorkflowMetadata) => {
78+
const dateA =
79+
a.lastModified instanceof Date
80+
? a.lastModified.getTime()
81+
: new Date(a.lastModified).getTime()
82+
const dateB =
83+
b.lastModified instanceof Date
84+
? b.lastModified.getTime()
85+
: new Date(b.lastModified).getTime()
86+
return dateB - dateA
7787
}
78-
})
88+
89+
regular.sort(sortByLastModified)
90+
temp.sort(sortByLastModified)
91+
}
7992

8093
return { regularWorkflows: regular, tempWorkflows: temp }
81-
}, [workflows, workspaceId, isLoading])
94+
}, [workflows, isLoading, workspaceId])
8295

8396
// Create workflow handler
8497
const handleCreateWorkflow = async (folderId?: string) => {

apps/sim/app/workspace/[workspaceId]/w/page.tsx

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,18 @@ import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
77

88
export default function WorkflowsPage() {
99
const router = useRouter()
10-
const { workflows, isLoading, loadWorkflows } = useWorkflowRegistry()
10+
const { workflows, isLoading } = useWorkflowRegistry()
1111

1212
const params = useParams()
13-
const workspaceId = params.workspaceId as string
14-
15-
// Load workflows for this specific workspace when component mounts or workspaceId changes
16-
// Only load if we don't already have workflows for this workspace (to prevent duplicate calls during workspace switches)
17-
useEffect(() => {
18-
if (workspaceId) {
19-
// Check if we already have workflows for this workspace
20-
const workflowIds = Object.keys(workflows)
21-
const hasWorkflowsForWorkspace =
22-
workflowIds.length > 0 &&
23-
Object.values(workflows).some((w) => w.workspaceId === workspaceId)
24-
25-
// Only load if we don't have workflows for this workspace and we're not loading
26-
if (!hasWorkflowsForWorkspace && !isLoading) {
27-
loadWorkflows(workspaceId)
28-
}
29-
}
30-
}, [workspaceId, loadWorkflows, isLoading, workflows])
13+
const workspaceId = params.workspaceId
3114

3215
useEffect(() => {
3316
// Wait for workflows to load
3417
if (isLoading) return
3518

3619
const workflowIds = Object.keys(workflows)
3720

38-
// If we have workflows, redirect to the first one (database already sorted by lastModified desc)
21+
// If we have workflows, redirect to the first one
3922
if (workflowIds.length > 0) {
4023
router.replace(`/workspace/${workspaceId}/w/${workflowIds[0]}`)
4124
return

apps/sim/contexts/socket-context.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
318318
})
319319

320320
socketInstance.on('workflow-state', (state) => {
321+
logger.info('Received workflow state from server:', state)
321322
// This will be used to sync initial state when joining a workflow
322323
})
323324

apps/sim/stores/workflows/registry/store.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ async function fetchWorkflowsFromDB(workspaceId?: string): Promise<void> {
151151
})
152152

153153
// Only set first workflow as active if no active workflow is set and we have workflows
154-
// Database already returns workflows sorted by lastModified desc
155154
const currentState = useWorkflowRegistry.getState()
156155
if (!currentState.activeWorkflowId && Object.keys(registryWorkflows).length > 0) {
157156
const firstWorkflowId = Object.keys(registryWorkflows)[0]

0 commit comments

Comments
 (0)