Fix editor showing unsaved changes when switching conditional branches (#4588)
This commit is contained in:
@@ -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" ||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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 });
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user