Skip to content

Commit 79476dd

Browse files
committed
make embedded view join room
1 parent 6255838 commit 79476dd

File tree

4 files changed

+89
-126
lines changed

4 files changed

+89
-126
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,22 @@ const WorkflowContent = React.memo(
265265
const { fitViewToBounds, getViewportCenter } = useCanvasViewport(reactFlowInstance, {
266266
embedded,
267267
})
268-
const { emitCursorUpdate } = useSocket()
268+
const { emitCursorUpdate, joinWorkflow, leaveWorkflow } = useSocket()
269269
useDynamicHandleRefresh()
270270

271271
const workspaceId = propWorkspaceId || (params.workspaceId as string)
272272
const workflowIdParam = propWorkflowId || (params.workflowId as string)
273273

274274
const addNotification = useNotificationStore((state) => state.addNotification)
275275

276+
useEffect(() => {
277+
if (!embedded || !workflowIdParam) return
278+
joinWorkflow(workflowIdParam)
279+
return () => {
280+
leaveWorkflow()
281+
}
282+
}, [embedded, workflowIdParam, joinWorkflow, leaveWorkflow])
283+
276284
useOAuthReturnForWorkflow(workflowIdParam)
277285

278286
const {

apps/sim/app/workspace/providers/socket-provider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
337337
socketInstance.on('join-workflow-success', ({ workflowId, presenceUsers }) => {
338338
isRejoiningRef.current = false
339339
// Ignore stale success responses from previous navigation
340-
if (workflowId !== urlWorkflowIdRef.current) {
340+
if (urlWorkflowIdRef.current && workflowId !== urlWorkflowIdRef.current) {
341341
logger.debug(`Ignoring stale join-workflow-success for ${workflowId}`)
342342
return
343343
}

apps/sim/hooks/use-collaborative-workflow.ts

Lines changed: 69 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -537,82 +537,81 @@ export function useCollaborativeWorkflow() {
537537
}
538538
}
539539

540-
const handleWorkflowReverted = async (data: any) => {
541-
const { workflowId } = data
542-
logger.info(`Workflow ${workflowId} has been reverted to deployed state`)
540+
const reloadWorkflowFromApi = async (workflowId: string, reason: string): Promise<boolean> => {
541+
const response = await fetch(`/api/workflows/${workflowId}`)
542+
if (!response.ok) {
543+
logger.error(`Failed to fetch workflow data after ${reason}: ${response.statusText}`)
544+
return false
545+
}
543546

544-
// If the reverted workflow is the currently active one, reload the workflow state
545-
if (activeWorkflowId === workflowId) {
546-
logger.info(`Currently active workflow ${workflowId} was reverted, reloading state`)
547-
548-
try {
549-
// Fetch the updated workflow state from the server (which loads from normalized tables)
550-
const response = await fetch(`/api/workflows/${workflowId}`)
551-
if (response.ok) {
552-
const responseData = await response.json()
553-
const workflowData = responseData.data
554-
555-
if (workflowData?.state) {
556-
// Update the workflow store with the reverted state
557-
isApplyingRemoteChange.current = true
558-
try {
559-
// Update the main workflow state using the API response
560-
useWorkflowStore.getState().replaceWorkflowState({
561-
blocks: workflowData.state.blocks || {},
562-
edges: workflowData.state.edges || [],
563-
loops: workflowData.state.loops || {},
564-
parallels: workflowData.state.parallels || {},
565-
lastSaved: workflowData.state.lastSaved || Date.now(),
566-
deploymentStatuses: workflowData.state.deploymentStatuses || {},
567-
})
547+
const responseData = await response.json()
548+
const workflowData = responseData.data
568549

569-
// Update subblock store with reverted values
570-
const subblockValues: Record<string, Record<string, any>> = {}
571-
Object.entries(workflowData.state.blocks || {}).forEach(([blockId, block]) => {
572-
const blockState = block as any
573-
subblockValues[blockId] = {}
574-
Object.entries(blockState.subBlocks || {}).forEach(([subblockId, subblock]) => {
575-
subblockValues[blockId][subblockId] = (subblock as any).value
576-
})
577-
})
550+
if (!workflowData?.state) {
551+
logger.error(`No state found in workflow data after ${reason}`, { workflowData })
552+
return false
553+
}
578554

579-
// Update subblock store for this workflow
580-
useSubBlockStore.setState((state: any) => ({
581-
workflowValues: {
582-
...state.workflowValues,
583-
[workflowId]: subblockValues,
584-
},
585-
}))
555+
isApplyingRemoteChange.current = true
556+
try {
557+
useWorkflowStore.getState().replaceWorkflowState({
558+
blocks: workflowData.state.blocks || {},
559+
edges: workflowData.state.edges || [],
560+
loops: workflowData.state.loops || {},
561+
parallels: workflowData.state.parallels || {},
562+
lastSaved: workflowData.state.lastSaved || Date.now(),
563+
deploymentStatuses: workflowData.state.deploymentStatuses || {},
564+
})
586565

587-
logger.info(`Successfully loaded reverted workflow state for ${workflowId}`)
566+
const subblockValues: Record<string, Record<string, any>> = {}
567+
Object.entries(workflowData.state.blocks || {}).forEach(([blockId, block]) => {
568+
const blockState = block as any
569+
subblockValues[blockId] = {}
570+
Object.entries(blockState.subBlocks || {}).forEach(([subblockId, subblock]) => {
571+
subblockValues[blockId][subblockId] = (subblock as any).value
572+
})
573+
})
588574

589-
const graph = {
590-
blocksById: workflowData.state.blocks || {},
591-
edgesById: Object.fromEntries(
592-
(workflowData.state.edges || []).map((e: any) => [e.id, e])
593-
),
594-
}
575+
useSubBlockStore.setState((state: any) => ({
576+
workflowValues: {
577+
...state.workflowValues,
578+
[workflowId]: subblockValues,
579+
},
580+
}))
595581

596-
const undoRedoStore = useUndoRedoStore.getState()
597-
const stackKeys = Object.keys(undoRedoStore.stacks)
598-
stackKeys.forEach((key) => {
599-
const [wfId, userId] = key.split(':')
600-
if (wfId === workflowId) {
601-
undoRedoStore.pruneInvalidEntries(wfId, userId, graph)
602-
}
603-
})
604-
} finally {
605-
isApplyingRemoteChange.current = false
606-
}
607-
} else {
608-
logger.error('No state found in workflow data after revert', { workflowData })
609-
}
610-
} else {
611-
logger.error(`Failed to fetch workflow data after revert: ${response.statusText}`)
612-
}
613-
} catch (error) {
614-
logger.error('Error reloading workflow state after revert:', error)
582+
const graph = {
583+
blocksById: workflowData.state.blocks || {},
584+
edgesById: Object.fromEntries(
585+
(workflowData.state.edges || []).map((e: any) => [e.id, e])
586+
),
615587
}
588+
589+
const undoRedoStore = useUndoRedoStore.getState()
590+
const stackKeys = Object.keys(undoRedoStore.stacks)
591+
stackKeys.forEach((key) => {
592+
const [wfId, userId] = key.split(':')
593+
if (wfId === workflowId) {
594+
undoRedoStore.pruneInvalidEntries(wfId, userId, graph)
595+
}
596+
})
597+
598+
logger.info(`Successfully reloaded workflow state after ${reason}`, { workflowId })
599+
return true
600+
} finally {
601+
isApplyingRemoteChange.current = false
602+
}
603+
}
604+
605+
const handleWorkflowReverted = async (data: any) => {
606+
const { workflowId } = data
607+
logger.info(`Workflow ${workflowId} has been reverted to deployed state`)
608+
609+
if (activeWorkflowId !== workflowId) return
610+
611+
try {
612+
await reloadWorkflowFromApi(workflowId, 'revert')
613+
} catch (error) {
614+
logger.error('Error reloading workflow state after revert:', error)
616615
}
617616
}
618617

@@ -629,49 +628,7 @@ export function useCollaborativeWorkflow() {
629628
}
630629

631630
try {
632-
const response = await fetch(`/api/workflows/${workflowId}`)
633-
if (response.ok) {
634-
const responseData = await response.json()
635-
const workflowData = responseData.data
636-
637-
if (workflowData?.state) {
638-
isApplyingRemoteChange.current = true
639-
try {
640-
useWorkflowStore.getState().replaceWorkflowState({
641-
blocks: workflowData.state.blocks || {},
642-
edges: workflowData.state.edges || [],
643-
loops: workflowData.state.loops || {},
644-
parallels: workflowData.state.parallels || {},
645-
lastSaved: workflowData.state.lastSaved || Date.now(),
646-
deploymentStatuses: workflowData.state.deploymentStatuses || {},
647-
})
648-
649-
const subblockValues: Record<string, Record<string, any>> = {}
650-
Object.entries(workflowData.state.blocks || {}).forEach(([blockId, block]) => {
651-
const blockState = block as any
652-
subblockValues[blockId] = {}
653-
Object.entries(blockState.subBlocks || {}).forEach(([subblockId, subblock]) => {
654-
subblockValues[blockId][subblockId] = (subblock as any).value
655-
})
656-
})
657-
658-
useSubBlockStore.setState((state: any) => ({
659-
workflowValues: {
660-
...state.workflowValues,
661-
[workflowId]: subblockValues,
662-
},
663-
}))
664-
665-
logger.info(`Successfully applied externally updated workflow state`, { workflowId })
666-
} finally {
667-
isApplyingRemoteChange.current = false
668-
}
669-
}
670-
} else {
671-
logger.error(
672-
`Failed to fetch workflow data after external update: ${response.statusText}`
673-
)
674-
}
631+
await reloadWorkflowFromApi(workflowId, 'external update')
675632
} catch (error) {
676633
logger.error('Error reloading workflow state after external update:', error)
677634
}

apps/sim/lib/copilot/tools/server/workflow/edit-workflow/index.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,19 +288,17 @@ export const editWorkflowServerTool: BaseServerTool<EditWorkflowParams, unknown>
288288

289289
logger.info('Workflow state persisted to database', { workflowId })
290290

291-
try {
292-
const socketUrl = env.SOCKET_SERVER_URL || 'http://localhost:3002'
293-
await fetch(`${socketUrl}/api/workflow-updated`, {
294-
method: 'POST',
295-
headers: {
296-
'Content-Type': 'application/json',
297-
'x-api-key': env.INTERNAL_API_SECRET,
298-
},
299-
body: JSON.stringify({ workflowId }),
300-
})
301-
} catch (error) {
291+
const socketUrl = env.SOCKET_SERVER_URL || 'http://localhost:3002'
292+
fetch(`${socketUrl}/api/workflow-updated`, {
293+
method: 'POST',
294+
headers: {
295+
'Content-Type': 'application/json',
296+
'x-api-key': env.INTERNAL_API_SECRET,
297+
},
298+
body: JSON.stringify({ workflowId }),
299+
}).catch((error) => {
302300
logger.warn('Failed to notify socket server of workflow update', { workflowId, error })
303-
}
301+
})
304302

305303
const sanitizationWarnings = validation.warnings.length > 0 ? validation.warnings : undefined
306304

0 commit comments

Comments
 (0)