diff --git a/apps/sim/app/api/workspaces/route.ts b/apps/sim/app/api/workspaces/route.ts index e6aac33f5e..cb7db1ba04 100644 --- a/apps/sim/app/api/workspaces/route.ts +++ b/apps/sim/app/api/workspaces/route.ts @@ -104,7 +104,7 @@ async function createWorkspace(userId: string, name: string) { updatedAt: now, }) - // Create "Workflow 1" for the workspace with start block + // Create initial workflow for the workspace with start block const starterId = crypto.randomUUID() const initialState = { blocks: { @@ -170,7 +170,7 @@ async function createWorkspace(userId: string, name: string) { userId, workspaceId, folderId: null, - name: 'Workflow 1', + name: 'default-agent', description: 'Your first workflow - start building here!', state: initialState, color: '#3972F6', diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx index 9b9c58f6d1..65870360d8 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/schedule/schedule-config.tsx @@ -26,10 +26,10 @@ interface ScheduleConfigProps { export function ScheduleConfig({ blockId, - subBlockId, + subBlockId: _subBlockId, isConnecting, isPreview = false, - previewValue, + previewValue: _previewValue, disabled = false, }: ScheduleConfigProps) { const [error, setError] = useState(null) @@ -56,13 +56,7 @@ export function ScheduleConfig({ // Get the startWorkflow value to determine if scheduling is enabled // and expose the setter so we can update it - const [startWorkflow, setStartWorkflow] = useSubBlockValue(blockId, 'startWorkflow') - const isScheduleEnabled = startWorkflow === 'schedule' - - const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlockId) - - // Use preview value when in preview mode, otherwise use store value - const value = isPreview ? previewValue : storeValue + const [_startWorkflow, setStartWorkflow] = useSubBlockValue(blockId, 'startWorkflow') // Function to check if schedule exists in the database const checkSchedule = async () => { @@ -110,10 +104,17 @@ export function ScheduleConfig({ // Check for schedule on mount and when relevant dependencies change useEffect(() => { - // Always check for schedules regardless of the UI setting - // This ensures we detect schedules even when the UI is set to manual - checkSchedule() - }, [workflowId, scheduleType, isModalOpen, refreshCounter]) + // Only check for schedules when workflowId changes or modal opens + // Avoid checking on every scheduleType change to prevent excessive API calls + if (workflowId && (isModalOpen || refreshCounter > 0)) { + checkSchedule() + } + + // Cleanup function to reset loading state + return () => { + setIsLoading(false) + } + }, [workflowId, isModalOpen, refreshCounter]) // Format the schedule information for display const getScheduleInfo = () => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx index 01460ceef2..9812ed5b5d 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from 'react' import { BookOpen, Code, Info, RectangleHorizontal, RectangleVertical } from 'lucide-react' +import { useParams } from 'next/navigation' import { Handle, type NodeProps, Position, useUpdateNodeInternals } from 'reactflow' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -83,6 +84,11 @@ export function WorkflowBlock({ id, data }: NodeProps) { const isActiveBlock = useExecutionStore((state) => state.activeBlockIds.has(id)) const isActive = dataIsActive || isActiveBlock + // Get the current workflow ID from URL params instead of global state + // This prevents race conditions when switching workflows rapidly + const params = useParams() + const currentWorkflowId = params.workflowId as string + const reactivateSchedule = async (scheduleId: string) => { try { const response = await fetch(`/api/schedules/${scheduleId}`, { @@ -94,7 +100,10 @@ export function WorkflowBlock({ id, data }: NodeProps) { }) if (response.ok) { - fetchScheduleInfo() + // Use the current workflow ID from params instead of global state + if (currentWorkflowId) { + fetchScheduleInfo(currentWorkflowId) + } } else { console.error('Failed to reactivate schedule') } @@ -103,11 +112,11 @@ export function WorkflowBlock({ id, data }: NodeProps) { } } - const fetchScheduleInfo = async () => { + const fetchScheduleInfo = async (workflowId: string) => { + if (!workflowId) return + try { setIsLoadingScheduleInfo(true) - const workflowId = useWorkflowRegistry.getState().activeWorkflowId - if (!workflowId) return const response = await fetch(`/api/schedules?workflowId=${workflowId}&mode=schedule`, { cache: 'no-store', @@ -176,12 +185,18 @@ export function WorkflowBlock({ id, data }: NodeProps) { } useEffect(() => { - if (type === 'starter') { - fetchScheduleInfo() + if (type === 'starter' && currentWorkflowId) { + fetchScheduleInfo(currentWorkflowId) } else { setScheduleInfo(null) + setIsLoadingScheduleInfo(false) // Reset loading state when not a starter block + } + + // Cleanup function to reset loading state when component unmounts or workflow changes + return () => { + setIsLoadingScheduleInfo(false) } - }, [type]) + }, [type, currentWorkflowId]) // Get webhook information for the tooltip useEffect(() => { diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx index 188ee91ea8..1ccb647469 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx @@ -15,9 +15,14 @@ import { useFolderStore } from '@/stores/folders/store' interface CreateMenuProps { onCreateWorkflow: (folderId?: string) => void isCollapsed?: boolean + isCreatingWorkflow?: boolean } -export function CreateMenu({ onCreateWorkflow, isCollapsed }: CreateMenuProps) { +export function CreateMenu({ + onCreateWorkflow, + isCollapsed, + isCreatingWorkflow = false, +}: CreateMenuProps) { const [showFolderDialog, setShowFolderDialog] = useState(false) const [folderName, setFolderName] = useState('') const [isCreating, setIsCreating] = useState(false) @@ -73,6 +78,7 @@ export function CreateMenu({ onCreateWorkflow, isCollapsed }: CreateMenuProps) { onClick={handleCreateWorkflow} onMouseEnter={() => setIsHoverOpen(true)} onMouseLeave={() => setIsHoverOpen(false)} + disabled={isCreatingWorkflow} > e.preventDefault()} >