You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.5 KiB
120 lines
3.5 KiB
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { App } from "antd";
|
|
import { useShallow } from "zustand/shallow";
|
|
import { useI18n } from "@/i18n";
|
|
import { updateCanvasWorkflow } from "@/lib/canvasWorkflowApi";
|
|
import { useCanvasWorkflowStore } from "@/store/canvasWorkflowStore";
|
|
import { useWorkflowStore } from "@/store/workflowStore";
|
|
import { buildSerializedWorkflow } from "@/store/utils/workflowSerialization";
|
|
import { pickCanvasWorkflowCoverImage } from "@/utils/canvasWorkflowCoverImage";
|
|
|
|
const CANVAS_WORKFLOW_AUTO_UPDATE_DELAY_MS = 5_000;
|
|
|
|
export function useCanvasWorkflowAutoUpdate() {
|
|
const { t } = useI18n();
|
|
const { message } = App.useApp();
|
|
const saveVersionRef = useRef(0);
|
|
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
|
|
const {
|
|
currentCanvasWorkflowId,
|
|
currentCanvasWorkflowTitle,
|
|
currentCanvasWorkflowDescription,
|
|
isLoadingCanvasWorkflow,
|
|
} = useCanvasWorkflowStore(useShallow((state) => ({
|
|
currentCanvasWorkflowId: state.currentCanvasWorkflowId,
|
|
currentCanvasWorkflowTitle: state.currentCanvasWorkflowTitle,
|
|
currentCanvasWorkflowDescription: state.currentCanvasWorkflowDescription,
|
|
isLoadingCanvasWorkflow: state.isLoadingCanvasWorkflow,
|
|
})));
|
|
|
|
const {
|
|
workflowId,
|
|
workflowName,
|
|
nodes,
|
|
edges,
|
|
edgeStyle,
|
|
groups,
|
|
hasUnsavedChanges,
|
|
markAsSaved,
|
|
} = useWorkflowStore(useShallow((state) => ({
|
|
workflowId: state.workflowId,
|
|
workflowName: state.workflowName,
|
|
nodes: state.nodes,
|
|
edges: state.edges,
|
|
edgeStyle: state.edgeStyle,
|
|
groups: state.groups,
|
|
hasUnsavedChanges: state.hasUnsavedChanges,
|
|
markAsSaved: state.markAsSaved,
|
|
})));
|
|
|
|
useEffect(() => {
|
|
if (timerRef.current) {
|
|
clearTimeout(timerRef.current);
|
|
timerRef.current = null;
|
|
}
|
|
|
|
if (!currentCanvasWorkflowId || !hasUnsavedChanges || isLoadingCanvasWorkflow) {
|
|
return;
|
|
}
|
|
|
|
saveVersionRef.current += 1;
|
|
const scheduledVersion = saveVersionRef.current;
|
|
|
|
timerRef.current = setTimeout(() => {
|
|
const workflow = buildSerializedWorkflow({
|
|
workflowId,
|
|
workflowName,
|
|
nameOverride: workflowName || currentCanvasWorkflowTitle || undefined,
|
|
nodes,
|
|
edges,
|
|
edgeStyle,
|
|
groups,
|
|
});
|
|
const title = workflowName?.trim() || currentCanvasWorkflowTitle || workflow.name;
|
|
const description = currentCanvasWorkflowDescription.trim();
|
|
const coverUrl = pickCanvasWorkflowCoverImage(nodes);
|
|
|
|
void updateCanvasWorkflow({
|
|
id: currentCanvasWorkflowId,
|
|
title,
|
|
...(description ? { desp: description } : {}),
|
|
properties: JSON.stringify(workflow),
|
|
...(coverUrl ? { coverUrl } : {}),
|
|
})
|
|
.then(() => {
|
|
if (saveVersionRef.current === scheduledVersion) {
|
|
markAsSaved();
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
const errorMessage = error instanceof Error ? error.message : t("workflowSave.failed");
|
|
void message.error(errorMessage);
|
|
});
|
|
}, CANVAS_WORKFLOW_AUTO_UPDATE_DELAY_MS);
|
|
|
|
return () => {
|
|
if (timerRef.current) {
|
|
clearTimeout(timerRef.current);
|
|
timerRef.current = null;
|
|
}
|
|
};
|
|
}, [
|
|
currentCanvasWorkflowId,
|
|
currentCanvasWorkflowTitle,
|
|
currentCanvasWorkflowDescription,
|
|
isLoadingCanvasWorkflow,
|
|
workflowId,
|
|
workflowName,
|
|
nodes,
|
|
edges,
|
|
edgeStyle,
|
|
groups,
|
|
hasUnsavedChanges,
|
|
markAsSaved,
|
|
message,
|
|
t,
|
|
]);
|
|
}
|
|
|