From 9f7f6c84aa0f5d4989fe1efb071a6545245ecd30 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 22 Sep 2023 15:18:52 -0300 Subject: [PATCH] feat(nodeToolbarComponent): add functionality to download node as JSON file feat(reactflowUtils): add functions to create a flow component and download a node as a JSON file The changes in `nodeToolbarComponent` include importing the `downloadNode` function from `reactflowUtils` and adding a case in the switch statement to call the `downloadNode` function when the action is "SaveAll". This allows the user to download the node as a JSON file. In `reactflowUtils`, two new functions are added. The `createFlowComponent` function takes in node data and creates a flow component with the necessary structure. The `downloadNode` function takes a flow component and converts it into a JSON file that can be downloaded by the user. --- .../components/nodeToolbarComponent/index.tsx | 7 +++- src/frontend/src/types/flow/index.ts | 1 + src/frontend/src/utils/reactflowUtils.ts | 34 ++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index ebc29643d..731835310 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -11,6 +11,10 @@ import { import { TabsContext } from "../../../../contexts/tabsContext"; import EditNodeModal from "../../../../modals/EditNodeModal"; import { nodeToolbarPropsType } from "../../../../types/components"; +import { + createFlowComponent, + downloadNode, +} from "../../../../utils/reactflowUtils"; import { classNames } from "../../../../utils/utils"; export default function NodeToolbarComponent({ @@ -62,7 +66,8 @@ export default function NodeToolbarComponent({ updateNodeInternals(data.id); break; case "SaveAll": - console.log("SaveAll"); + downloadNode(createFlowComponent(data)); + break; } }; diff --git a/src/frontend/src/types/flow/index.ts b/src/frontend/src/types/flow/index.ts index b64c09e86..91c462340 100644 --- a/src/frontend/src/types/flow/index.ts +++ b/src/frontend/src/types/flow/index.ts @@ -7,6 +7,7 @@ export type FlowType = { data: ReactFlowJsonObject | null; description: string; style?: FlowStyleType; + isNode?: boolean; }; export type NodeType = { id: string; diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index df8c784c4..0d2f10233 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -8,7 +8,7 @@ import { } from "reactflow"; import { specialCharsRegex } from "../constants/constants"; import { APITemplateType } from "../types/api"; -import { FlowType, NodeType } from "../types/flow"; +import { FlowType, NodeDataType, NodeType } from "../types/flow"; import { cleanEdgesType, unselectAllNodesType, @@ -365,3 +365,35 @@ export function convertValuesToNumbers(arr) { return newObj; }); } + +export function createFlowComponent(nodeData: NodeDataType): FlowType { + const flowNode: FlowType = { + data: { + edges: [], + nodes: [ + { + data: nodeData, + id: nodeData.id, + position: { x: 0, y: 0 }, + type: "genericNode", + }, + ], + viewport: { x: 1, y: 1, zoom: 1 }, + }, + description: nodeData.node?.description || "", + name: nodeData.node?.display_name || "", + id: nodeData.id || "", + isNode: true, + }; + 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}.json`; + element.click(); +}