From f5024f544097f26f38b1be26897ada02f7605b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Tue, 21 Jul 2026 15:11:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(workflow):=20avoid=20false=20draft=20save?= =?UTF-8?q?=20error=20during=20Strict=20Mode=20initia=E2=80=A6=20(#39353)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow-app/components/workflow-main.tsx | 1 + .../__tests__/workflow-edge-events.spec.tsx | 26 ++++++++++++++++--- web/app/components/workflow/index.tsx | 6 ++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/web/app/components/workflow-app/components/workflow-main.tsx b/web/app/components/workflow-app/components/workflow-main.tsx index b891e9ecac2..449f4f66e27 100644 --- a/web/app/components/workflow-app/components/workflow-main.tsx +++ b/web/app/components/workflow-app/components/workflow-main.tsx @@ -421,6 +421,7 @@ const WorkflowMain = ({ nodes, edges, viewport }: WorkflowMainProps) => { viewport={viewport} onWorkflowDataUpdate={handleWorkflowDataUpdate} hooksStore={hooksStore as unknown as Partial} + isCollaborationEnabled={isCollaborationEnabled} cursors={filteredCursors} myUserId={myUserId} onlineUsers={onlineUsers} diff --git a/web/app/components/workflow/__tests__/workflow-edge-events.spec.tsx b/web/app/components/workflow/__tests__/workflow-edge-events.spec.tsx index 373c75daba8..44194d9d394 100644 --- a/web/app/components/workflow/__tests__/workflow-edge-events.spec.tsx +++ b/web/app/components/workflow/__tests__/workflow-edge-events.spec.tsx @@ -25,6 +25,7 @@ const reactFlowBridge = vi.hoisted(() => ({ })) const collaborationBridge = vi.hoisted(() => ({ + canPersistLocalGraph: vi.fn(), graphImportHandler: null as null | ((payload: { nodes: Node[]; edges: Edge[] }) => void), historyActionHandler: null as null | ((payload: unknown) => void), restoreIntentHandler: null as @@ -196,6 +197,7 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ vi.mock('../collaboration/core/collaboration-manager', () => ({ collaborationManager: { + canPersistLocalGraph: collaborationBridge.canPersistLocalGraph, onGraphImport: (handler: (payload: { nodes: Node[]; edges: Edge[] }) => void) => { collaborationBridge.graphImportHandler = handler return vi.fn() @@ -453,12 +455,18 @@ function renderSubject(options?: { nodes?: Node[] edges?: Edge[] initialStoreState?: Record + isCollaborationEnabled?: boolean }) { - const { nodes = baseNodes, edges = baseEdges, initialStoreState } = options ?? {} + const { + nodes = baseNodes, + edges = baseEdges, + initialStoreState, + isCollaborationEnabled, + } = options ?? {} return renderWorkflowComponent( - + , @@ -514,6 +522,7 @@ vi.mock('@/context/permission-state', async () => { describe('Workflow edge event wiring', () => { beforeEach(() => { vi.clearAllMocks() + collaborationBridge.canPersistLocalGraph.mockReturnValue(true) eventEmitterState.subscription = null reactFlowBridge.store = null collaborationBridge.graphImportHandler = null @@ -615,7 +624,7 @@ describe('Workflow edge event wiring', () => { }, ) - const { unmount } = renderSubject() + const { unmount } = renderSubject({ isCollaborationEnabled: true }) unmount() @@ -624,6 +633,17 @@ describe('Workflow edge event wiring', () => { }) }) + it('should skip the unmount save while the collaborative graph is not ready', () => { + collaborationBridge.canPersistLocalGraph.mockReturnValue(false) + + const { unmount } = renderSubject({ isCollaborationEnabled: true }) + + unmount() + + expect(workflowHookMocks.handleSyncWorkflowDraft).not.toHaveBeenCalled() + expect(toastErrorMock).not.toHaveBeenCalled() + }) + it('should render confirm description and clear showConfirm when cancelled', async () => { const onConfirm = vi.fn() const { store } = renderSubject({ diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index c097d003976..0b8b982d839 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -125,6 +125,7 @@ export type WorkflowProps = { viewport?: Viewport children?: React.ReactNode onWorkflowDataUpdate?: (v: WorkflowDataUpdatePayload) => void + isCollaborationEnabled?: boolean cursors?: Record myUserId?: string | null onlineUsers?: OnlineUser[] @@ -168,6 +169,7 @@ export const Workflow: FC = memo( viewport, children, onWorkflowDataUpdate, + isCollaborationEnabled = false, cursors, myUserId, onlineUsers, @@ -364,6 +366,8 @@ export const Workflow: FC = memo( useEffect(() => { return () => { + if (isCollaborationEnabled && !collaborationManager.canPersistLocalGraph()) return + handleSyncWorkflowDraft(true, true, { onError: () => { toast.error( @@ -375,7 +379,7 @@ export const Workflow: FC = memo( }, }) } - }, [handleSyncWorkflowDraft, t]) + }, [handleSyncWorkflowDraft, isCollaborationEnabled, t]) const handlePendingCommentPositionChange = useCallback( (position: NonNullable) => {