mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(subblock-race-condition): check loading state correctly (#1141)
* fix(subblock-race-condition): check loading state correctly" ; * clean up * remove useless comments * fix date fallback
This commit is contained in:
@@ -39,7 +39,7 @@ import { useExecutionStore } from '@/stores/execution/store'
|
||||
import { useVariablesStore } from '@/stores/panel/variables/store'
|
||||
import { useGeneralStore } from '@/stores/settings/general/store'
|
||||
import { useWorkflowDiffStore } from '@/stores/workflow-diff/store'
|
||||
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { hasWorkflowsInitiallyLoaded, useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
||||
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
|
||||
|
||||
const logger = createLogger('Workflow')
|
||||
@@ -908,14 +908,21 @@ const WorkflowContent = React.memo(() => {
|
||||
const workflowIds = Object.keys(workflows)
|
||||
const currentId = params.workflowId as string
|
||||
|
||||
// Check if workflows have been initially loaded at least once
|
||||
// This prevents premature navigation decisions on page refresh
|
||||
if (!hasWorkflowsInitiallyLoaded()) {
|
||||
logger.info('Waiting for initial workflow load...')
|
||||
return
|
||||
}
|
||||
|
||||
// Wait for both initialization and workflow loading to complete
|
||||
if (isLoading) {
|
||||
logger.info('Workflows still loading, waiting...')
|
||||
return
|
||||
}
|
||||
|
||||
// If no workflows exist, redirect to workspace root to let server handle workflow creation
|
||||
if (workflowIds.length === 0 && !isLoading) {
|
||||
// If no workflows exist after loading, redirect to workspace root
|
||||
if (workflowIds.length === 0) {
|
||||
logger.info('No workflows found, redirecting to workspace root')
|
||||
router.replace(`/workspace/${workspaceId}/w`)
|
||||
return
|
||||
|
||||
@@ -164,6 +164,9 @@ async function fetchWorkflowsFromDB(workspaceId?: string): Promise<void> {
|
||||
error: null,
|
||||
})
|
||||
|
||||
// Mark that initial load has completed
|
||||
hasInitiallyLoaded = true
|
||||
|
||||
// Only set first workflow as active if no active workflow is set and we have workflows
|
||||
const currentState = useWorkflowRegistry.getState()
|
||||
if (!currentState.activeWorkflowId && Object.keys(registryWorkflows).length > 0) {
|
||||
@@ -177,6 +180,11 @@ async function fetchWorkflowsFromDB(workspaceId?: string): Promise<void> {
|
||||
)
|
||||
} catch (error) {
|
||||
logger.error('Error fetching workflows from DB:', error)
|
||||
|
||||
// Mark that initial load has completed even on error
|
||||
// This prevents indefinite waiting for workflows that failed to load
|
||||
hasInitiallyLoaded = true
|
||||
|
||||
useWorkflowRegistry.setState({
|
||||
isLoading: false,
|
||||
error: `Failed to load workflows: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
@@ -256,21 +264,28 @@ export function isWorkspaceInTransition(): boolean {
|
||||
return isWorkspaceTransitioning
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if workflows have been initially loaded
|
||||
* @returns True if the initial workflow load has completed at least once
|
||||
*/
|
||||
export function hasWorkflowsInitiallyLoaded(): boolean {
|
||||
return hasInitiallyLoaded
|
||||
}
|
||||
|
||||
// Track if initial load has happened to prevent premature navigation
|
||||
let hasInitiallyLoaded = false
|
||||
|
||||
export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
devtools(
|
||||
(set, get) => ({
|
||||
// Store state
|
||||
workflows: {},
|
||||
activeWorkflowId: null,
|
||||
isLoading: true,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
// Initialize deployment statuses
|
||||
deploymentStatuses: {},
|
||||
|
||||
// Set loading state
|
||||
setLoading: (loading: boolean) => {
|
||||
// Remove the broken logic that prevents loading when workflows exist
|
||||
// This was causing race conditions during deletion and sync operations
|
||||
set({ isLoading: loading })
|
||||
},
|
||||
|
||||
@@ -295,6 +310,9 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
try {
|
||||
logger.info(`Switching to workspace: ${workspaceId}`)
|
||||
|
||||
// Reset the initial load flag when switching workspaces
|
||||
hasInitiallyLoaded = false
|
||||
|
||||
// Clear current workspace state
|
||||
resetWorkflowStores()
|
||||
|
||||
@@ -500,7 +518,6 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
})
|
||||
})
|
||||
|
||||
// Update subblock store for this workflow
|
||||
useSubBlockStore.setState((state) => ({
|
||||
workflowValues: {
|
||||
...state.workflowValues,
|
||||
@@ -542,10 +559,6 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
)
|
||||
}
|
||||
|
||||
// Set the workflow state in the store
|
||||
useWorkflowStore.setState(workflowState)
|
||||
|
||||
// CRITICAL: Set deployment status in registry when switching to workflow
|
||||
if (workflowData?.isDeployed || workflowData?.deployedAt) {
|
||||
set((state) => ({
|
||||
deploymentStatuses: {
|
||||
@@ -560,11 +573,10 @@ export const useWorkflowRegistry = create<WorkflowRegistry>()(
|
||||
}))
|
||||
}
|
||||
|
||||
// Update the active workflow ID
|
||||
useWorkflowStore.setState(workflowState)
|
||||
|
||||
set({ activeWorkflowId: id, error: null })
|
||||
|
||||
// Emit a global event to notify that the active workflow has changed
|
||||
// This allows the workflow component to join the socket room
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('active-workflow-changed', {
|
||||
detail: { workflowId: id },
|
||||
|
||||
@@ -46,7 +46,7 @@ const initialState = {
|
||||
isDeployed: false,
|
||||
isPublished: false,
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
timestamp: 0,
|
||||
action: 'Initial state',
|
||||
subblockValues: {},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user