Fix editor showing unsaved changes when switching conditional branches (#4588)

This commit is contained in:
Celal Zamanoglu
2026-01-31 00:26:15 +03:00
committed by GitHub
parent f25e6c40d9
commit a503a19146
3 changed files with 28 additions and 2 deletions

View File

@@ -857,9 +857,14 @@ function FlowRenderer({
doLayout(tempNodes, edges);
}
// Only track changes after initial load is complete
// Only track changes after initial load is complete and not during internal updates
// (e.g., switching conditional branches which is UI state, not workflow data)
// Use getState() to get real-time value (not stale closure from render time)
const isInternalUpdate =
useWorkflowHasChangesStore.getState().isInternalUpdate;
if (
!isInitialLoadRef.current &&
!isInternalUpdate &&
changes.some((change) => {
return (
change.type === "add" ||

View File

@@ -23,6 +23,7 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/util/utils";
import { useWorkflowHasChangesStore } from "@/store/WorkflowHasChangesStore";
import { useUpdate } from "../../useUpdate";
import { NodeHeader } from "../components/NodeHeader";
import { AppNode, isWorkflowBlockNode } from "..";
@@ -44,6 +45,7 @@ function ConditionalNodeComponent({ id, data }: NodeProps<ConditionalNode>) {
const nodes = useNodes<AppNode>();
const { setNodes, setEdges } = useReactFlow();
const node = nodes.find((n) => n.id === id);
const { setIsInternalUpdate } = useWorkflowHasChangesStore();
const update = useUpdate<ConditionalNodeData>({
id,
@@ -109,11 +111,17 @@ function ConditionalNodeComponent({ id, data }: NodeProps<ConditionalNode>) {
useEffect(() => {
if (!data.activeBranchId && orderedBranches.length > 0) {
// Mark as internal update to prevent triggering "unsaved changes" dialog
setIsInternalUpdate(true);
update({
activeBranchId: orderedBranches[0]?.id ?? null,
});
// Clear the flag after layout completes
setTimeout(() => {
setIsInternalUpdate(false);
}, 50);
}
}, [data.activeBranchId, orderedBranches, update]);
}, [data.activeBranchId, orderedBranches, update, setIsInternalUpdate]);
// Toggle visibility of branch nodes/edges when activeBranchId changes
useEffect(() => {
@@ -271,7 +279,14 @@ function ConditionalNodeComponent({ id, data }: NodeProps<ConditionalNode>) {
if (!data.editable) {
return;
}
// Mark as internal update to prevent triggering "unsaved changes" dialog
// Switching branches is UI state, not actual workflow data changes
setIsInternalUpdate(true);
update({ activeBranchId: branchId });
// Clear the flag after layout completes (layout uses setTimeout(10))
setTimeout(() => {
setIsInternalUpdate(false);
}, 50);
};
const handleRemoveBranch = (branchId: string) => {

View File

@@ -31,11 +31,13 @@ type WorkflowHasChangesStore = {
saveIsPending: boolean;
saidOkToCodeCacheDeletion: boolean;
showConfirmCodeCacheDeletion: boolean;
isInternalUpdate: boolean;
setGetSaveData: (getSaveData: () => SaveData) => void;
setHasChanges: (hasChanges: boolean) => void;
setSaveIsPending: (isPending: boolean) => void;
setSaidOkToCodeCacheDeletion: (saidOkToCodeCacheDeletion: boolean) => void;
setShowConfirmCodeCacheDeletion: (show: boolean) => void;
setIsInternalUpdate: (isInternalUpdate: boolean) => void;
};
interface WorkflowSaveOpts {
@@ -48,6 +50,7 @@ const useWorkflowHasChangesStore = create<WorkflowHasChangesStore>((set) => {
saveIsPending: false,
saidOkToCodeCacheDeletion: false,
showConfirmCodeCacheDeletion: false,
isInternalUpdate: false,
getSaveData: () => null,
setGetSaveData: (getSaveData: () => SaveData) => {
set({ getSaveData });
@@ -64,6 +67,9 @@ const useWorkflowHasChangesStore = create<WorkflowHasChangesStore>((set) => {
setShowConfirmCodeCacheDeletion: (show: boolean) => {
set({ showConfirmCodeCacheDeletion: show });
},
setIsInternalUpdate: (isInternalUpdate: boolean) => {
set({ isInternalUpdate });
},
};
});