From 2a1c5ff57b3264184f4c4f702527c9b8b3f51b5d Mon Sep 17 00:00:00 2001 From: lyzno1 Date: Fri, 26 Sep 2025 13:54:52 +0800 Subject: [PATCH] feat(workflow): Enable entry node deletion and fix draft sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete workflow liberalization following PR #24627: 1. Remove Start node deletion restriction by removing isUndeletable property 2. Fix draft sync blocking when no Start node exists 3. Restore isWorkflowDataLoaded protection to prevent race conditions 4. Ensure all entry nodes (Start + 3 trigger types) have equal deletion rights This allows workflows with only trigger nodes and fixes the issue where added nodes would disappear after page refresh due to sync API blocking. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../workflow-app/hooks/use-nodes-sync-draft.ts | 9 +++------ .../workflow-app/hooks/use-workflow-refresh-draft.ts | 1 + web/app/components/workflow/nodes/start/default.ts | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts b/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts index f387647c43..bd1fa0a19f 100644 --- a/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts +++ b/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts @@ -5,7 +5,6 @@ import { useParams } from 'next/navigation' import { useWorkflowStore, } from '@/app/components/workflow/store' -import { BlockEnum } from '@/app/components/workflow/types' import { useNodesReadOnly, } from '@/app/components/workflow/hooks/use-workflow' @@ -35,13 +34,11 @@ export const useNodesSyncDraft = () => { conversationVariables, environmentVariables, syncWorkflowDraftHash, - // isWorkflowDataLoaded, + isWorkflowDataLoaded, } = workflowStore.getState() - if (appId && !!nodes.length) { - const hasStartNode = nodes.find(node => node.data.type === BlockEnum.Start) - - if (!hasStartNode) + if (appId) { + if (!isWorkflowDataLoaded) return null const features = featuresStore!.getState().features diff --git a/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts b/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts index b45ab16c14..a4c36de814 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts @@ -33,6 +33,7 @@ export const useWorkflowRefreshDraft = () => { }, {} as Record)) setEnvironmentVariables(response.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || []) setConversationVariables(response.conversation_variables || []) + workflowStore.setState({ isWorkflowDataLoaded: true }) }).finally(() => setIsSyncingWorkflowDraft(false)) }, [handleUpdateWorkflowCanvas, workflowStore]) diff --git a/web/app/components/workflow/nodes/start/default.ts b/web/app/components/workflow/nodes/start/default.ts index 3b98b57a73..d4f3557264 100644 --- a/web/app/components/workflow/nodes/start/default.ts +++ b/web/app/components/workflow/nodes/start/default.ts @@ -8,7 +8,6 @@ const metaData = genNodeMetaData({ type: BlockEnum.Start, isStart: true, isRequired: true, - isUndeletable: true, isSingleton: true, isTypeFixed: true, })