diff --git a/src/frontend/src/customization/utils/custom-download-json.ts b/src/frontend/src/customization/utils/custom-download-json.ts new file mode 100644 index 0000000000..2f2a2eaa17 --- /dev/null +++ b/src/frontend/src/customization/utils/custom-download-json.ts @@ -0,0 +1,12 @@ +import { FlowType } from "@/types/flow"; + +export async function customDownloadNodeJson(NodeFLow: FlowType) { + // Fallback to browser download for web version + const element = document.createElement("a"); + const file = new Blob([JSON.stringify(NodeFLow)], { + type: "application/json", + }); + element.href = URL.createObjectURL(file); + element.download = `${NodeFLow?.name ?? "node"}.json`; + element.click(); +} diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index f8b9c04c38..837e1879f3 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -258,6 +258,21 @@ const NodeToolbarComponent = memo( }); }, [data.id, data.node?.documentation]); + const handleDownloadNode = useCallback(async () => { + try { + await downloadNode(flowComponent!); + setSuccessData({ + title: `${flowComponent?.name || "Node"} downloaded successfully`, + }); + } catch (error) { + console.error("Error downloading node:", error); + setErrorData({ + title: "Failed to download node", + list: [error instanceof Error ? error.message : "Unknown error"], + }); + } + }, [flowComponent]); + useShortcuts({ showOverrideModal, showModalAdvanced, @@ -349,7 +364,7 @@ const NodeToolbarComponent = memo( shareComponent(); break; case "Download": - downloadNode(flowComponent!); + handleDownloadNode(); break; case "SaveAll": addFlow({ diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 0a6dde5934..1f636a6d56 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -27,6 +27,7 @@ import { getRightHandleId, } from "@/CustomNodes/utils/get-handle-id"; import { INCOMPLETE_LOOP_ERROR_ALERT } from "@/constants/alerts_constants"; +import { customDownloadNodeJson } from "@/customization/utils/custom-download-json"; import { customDownloadFlow } from "@/customization/utils/custom-reactFlowUtils"; import useFlowStore from "@/stores/flowStore"; import getFieldTitle from "../CustomNodes/utils/get-field-title"; @@ -1767,14 +1768,8 @@ export function createFlowComponent( return flowNode; } -export function downloadNode(NodeFLow: FlowType) { - const element = document.createElement("a"); - const file = new Blob([JSON.stringify(NodeFLow)], { - type: "application/json", - }); - element.href = URL.createObjectURL(file); - element.download = `${NodeFLow?.name ?? "node"}.json`; - element.click(); +export async function downloadNode(NodeFLow: FlowType) { + await customDownloadNodeJson(NodeFLow); } export function updateComponentNameAndType(