added upload and download flows on zustand and utils
This commit is contained in:
parent
d44648d6c1
commit
616a4f0031
15 changed files with 114 additions and 28 deletions
|
|
@ -5,7 +5,6 @@ import { useSSE } from "../../../contexts/SSEContext";
|
||||||
import { postBuildInit } from "../../../controllers/API";
|
import { postBuildInit } from "../../../controllers/API";
|
||||||
import { FlowType } from "../../../types/flow";
|
import { FlowType } from "../../../types/flow";
|
||||||
|
|
||||||
import { FlowsContext } from "../../../contexts/flowsContext";
|
|
||||||
import useAlertStore from "../../../stores/alertStore";
|
import useAlertStore from "../../../stores/alertStore";
|
||||||
import useFlowStore from "../../../stores/flowStore";
|
import useFlowStore from "../../../stores/flowStore";
|
||||||
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import AlertDropdown from "../../alerts/alertDropDown";
|
||||||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
|
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
import { useStoreStore } from "../../stores/storeStore";
|
import { useStoreStore } from "../../stores/storeStore";
|
||||||
|
|
@ -22,7 +21,6 @@ import {
|
||||||
} from "../ui/dropdown-menu";
|
} from "../ui/dropdown-menu";
|
||||||
import { Separator } from "../ui/separator";
|
import { Separator } from "../ui/separator";
|
||||||
import MenuBar from "./components/menuBar";
|
import MenuBar from "./components/menuBar";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
|
||||||
|
|
||||||
export default function Header(): JSX.Element {
|
export default function Header(): JSX.Element {
|
||||||
const notificationCenter = useAlertStore((state) => state.notificationCenter);
|
const notificationCenter = useAlertStore((state) => state.notificationCenter);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import { uploadFile } from "../../controllers/API";
|
import { uploadFile } from "../../controllers/API";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import { FileComponentType } from "../../types/components";
|
import { FileComponentType } from "../../types/components";
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,14 @@ import IconComponent from "../../components/genericIconComponent";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { Checkbox } from "../../components/ui/checkbox";
|
import { Checkbox } from "../../components/ui/checkbox";
|
||||||
import { EXPORT_DIALOG_SUBTITLE } from "../../constants/constants";
|
import { EXPORT_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import { removeApiKeys } from "../../utils/reactflowUtils";
|
import { downloadFlow, removeApiKeys } from "../../utils/reactflowUtils";
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
|
|
||||||
const ExportModal = forwardRef(
|
const ExportModal = forwardRef(
|
||||||
(props: { children: ReactNode }, ref): JSX.Element => {
|
(props: { children: ReactNode }, ref): JSX.Element => {
|
||||||
const { downloadFlow } = useContext(FlowsContext);
|
|
||||||
const version = useDarkStore((state) => state.version);
|
const version = useDarkStore((state) => state.version);
|
||||||
const setNoticeData = useAlertStore((state) => state.setNoticeData);
|
const setNoticeData = useAlertStore((state) => state.setNoticeData);
|
||||||
const [checked, setChecked] = useState(true);
|
const [checked, setChecked] = useState(true);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import EditFlowSettings from "../../components/EditFlowSettingsComponent";
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants/constants";
|
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import { FlowSettingsPropsType } from "../../types/components";
|
import { FlowSettingsPropsType } from "../../types/components";
|
||||||
import { FlowType } from "../../types/flow";
|
import { FlowType } from "../../types/flow";
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import IconComponent from "../../components/genericIconComponent";
|
||||||
import { TagsSelector } from "../../components/tagsSelectorComponent";
|
import { TagsSelector } from "../../components/tagsSelectorComponent";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { Checkbox } from "../../components/ui/checkbox";
|
import { Checkbox } from "../../components/ui/checkbox";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import {
|
import {
|
||||||
getStoreComponents,
|
getStoreComponents,
|
||||||
getStoreTags,
|
getStoreTags,
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ import ReactFlow, {
|
||||||
SelectionDragHandler,
|
SelectionDragHandler,
|
||||||
addEdge,
|
addEdge,
|
||||||
updateEdge,
|
updateEdge,
|
||||||
useEdgesState,
|
|
||||||
useNodesState,
|
|
||||||
} from "reactflow";
|
} from "reactflow";
|
||||||
import GenericNode from "../../../../CustomNodes/GenericNode";
|
import GenericNode from "../../../../CustomNodes/GenericNode";
|
||||||
import Chat from "../../../../components/chatComponent";
|
import Chat from "../../../../components/chatComponent";
|
||||||
|
|
@ -28,6 +26,8 @@ import { locationContext } from "../../../../contexts/locationContext";
|
||||||
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||||
import useAlertStore from "../../../../stores/alertStore";
|
import useAlertStore from "../../../../stores/alertStore";
|
||||||
import useFlowStore from "../../../../stores/flowStore";
|
import useFlowStore from "../../../../stores/flowStore";
|
||||||
|
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
||||||
|
import { useTypesStore } from "../../../../stores/typesStore";
|
||||||
import { APIClassType } from "../../../../types/api";
|
import { APIClassType } from "../../../../types/api";
|
||||||
import { FlowType, NodeType } from "../../../../types/flow";
|
import { FlowType, NodeType } from "../../../../types/flow";
|
||||||
import {
|
import {
|
||||||
|
|
@ -41,8 +41,6 @@ import { cn, getRandomName, isWrappedWithClass } from "../../../../utils/utils";
|
||||||
import ConnectionLineComponent from "../ConnectionLineComponent";
|
import ConnectionLineComponent from "../ConnectionLineComponent";
|
||||||
import SelectionMenu from "../SelectionMenuComponent";
|
import SelectionMenu from "../SelectionMenuComponent";
|
||||||
import ExtraSidebar from "../extraSidebarComponent";
|
import ExtraSidebar from "../extraSidebarComponent";
|
||||||
import { useTypesStore } from "../../../../stores/typesStore";
|
|
||||||
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
genericNode: GenericNode,
|
genericNode: GenericNode,
|
||||||
|
|
@ -56,7 +54,9 @@ export default function Page({
|
||||||
view?: boolean;
|
view?: boolean;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
let { uploadFlow } = useContext(FlowsContext);
|
let { uploadFlow } = useContext(FlowsContext);
|
||||||
const autoSaveCurrentFlow = useFlowsManagerStore((state) => state.autoSaveCurrentFlow);
|
const autoSaveCurrentFlow = useFlowsManagerStore(
|
||||||
|
(state) => state.autoSaveCurrentFlow
|
||||||
|
);
|
||||||
const types = useTypesStore((state) => state.types);
|
const types = useTypesStore((state) => state.types);
|
||||||
const templates = useTypesStore((state) => state.templates);
|
const templates = useTypesStore((state) => state.templates);
|
||||||
const setFilterEdge = useTypesStore((state) => state.setFilterEdge);
|
const setFilterEdge = useTypesStore((state) => state.setFilterEdge);
|
||||||
|
|
@ -160,13 +160,17 @@ export default function Page({
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||||
|
|
||||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
if (reactFlowInstance) {
|
if (reactFlowInstance) {
|
||||||
reactFlowInstance.setNodes(flow?.data?.nodes ?? []);
|
useFlowStore.setState({
|
||||||
reactFlowInstance.setEdges(flow?.data?.edges ?? []);
|
nodes: flow?.data?.nodes ?? [],
|
||||||
|
edges: flow?.data?.edges ?? [],
|
||||||
|
});
|
||||||
reactFlowInstance.setViewport(
|
reactFlowInstance.setViewport(
|
||||||
flow?.data?.viewport ?? { zoom: 1, x: 0, y: 0 }
|
flow?.data?.viewport ?? { zoom: 1, x: 0, y: 0 }
|
||||||
);
|
);
|
||||||
|
|
@ -186,7 +190,7 @@ export default function Page({
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timeoutRef.current);
|
clearTimeout(timeoutRef.current);
|
||||||
};
|
};
|
||||||
}, [flow, reactFlowInstance]);
|
}, [currentFlowId, reactFlowInstance]);
|
||||||
|
|
||||||
const onConnectMod = useCallback(
|
const onConnectMod = useCallback(
|
||||||
(params: Connection) => {
|
(params: Connection) => {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
const { uploadFlow } = useContext(FlowsContext);
|
const { uploadFlow } = useContext(FlowsContext);
|
||||||
const saveFlow = useFlowsManagerStore((state) => state.saveFlow);
|
const saveFlow = useFlowsManagerStore((state) => state.saveFlow);
|
||||||
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
||||||
|
const nodes = useFlowStore((state) => state.nodes);
|
||||||
|
const edges = useFlowStore((state) => state.edges);
|
||||||
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
||||||
const hasStore = useStoreStore((state) => state.hasStore);
|
const hasStore = useStoreStore((state) => state.hasStore);
|
||||||
const hasApiKey = useStoreStore((state) => state.hasApiKey);
|
const hasApiKey = useStoreStore((state) => state.hasApiKey);
|
||||||
|
|
@ -304,7 +306,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
(isPending ? "" : "button-disable")
|
(isPending ? "" : "button-disable")
|
||||||
}
|
}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
saveFlow({...currentFlow, data: {...currentFlow.data!, viewport: reactFlowInstance?.getViewport()!} }, true);
|
saveFlow({...currentFlow, data: {nodes, edges, viewport: reactFlowInstance?.getViewport()!} }, true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,9 @@ export default function ComponentsComponent({
|
||||||
}: {
|
}: {
|
||||||
is_component?: boolean;
|
is_component?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { removeFlow, uploadFlow, addFlow, isLoading } =
|
const { removeFlow, uploadFlow, addFlow } =
|
||||||
useContext(FlowsContext);
|
useContext(FlowsContext);
|
||||||
|
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
||||||
const flows = useFlowsManagerStore((state) => state.flows);
|
const flows = useFlowsManagerStore((state) => state.flows);
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
|
@ -51,7 +52,7 @@ export default function ComponentsComponent({
|
||||||
const start = (pageIndex - 1) * pageSize;
|
const start = (pageIndex - 1) * pageSize;
|
||||||
const end = start + pageSize;
|
const end = start + pageSize;
|
||||||
setData(all.slice(start, end));
|
setData(all.slice(start, end));
|
||||||
}, [flows, pageIndex, pageSize]);
|
}, [flows, isLoading, pageIndex, pageSize]);
|
||||||
|
|
||||||
const [data, setData] = useState<FlowType[]>([]);
|
const [data, setData] = useState<FlowType[]>([]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,16 @@ import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
import { FlowsContext } from "../../contexts/flowsContext";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
|
import { downloadFlows } from "../../utils/reactflowUtils";
|
||||||
export default function HomePage(): JSX.Element {
|
export default function HomePage(): JSX.Element {
|
||||||
const { downloadFlows, uploadFlows, addFlow, uploadFlow } =
|
const { addFlow, uploadFlow } =
|
||||||
useContext(FlowsContext);
|
useContext(FlowsContext);
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
(state) => state.setCurrentFlowId
|
(state) => state.setCurrentFlowId
|
||||||
);
|
);
|
||||||
|
const uploadFlows = useFlowsManagerStore(
|
||||||
|
(state) => state.uploadFlows
|
||||||
|
);
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import InputComponent from "../../components/inputComponent";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { CONTROL_PATCH_USER_STATE } from "../../constants/constants";
|
import { CONTROL_PATCH_USER_STATE } from "../../constants/constants";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import { resetPassword, updateUser } from "../../controllers/API";
|
import { resetPassword, updateUser } from "../../controllers/API";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "../../components/ui/select";
|
} from "../../components/ui/select";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
|
||||||
import {
|
import {
|
||||||
checkHasApiKey,
|
checkHasApiKey,
|
||||||
getStoreComponents,
|
getStoreComponents,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { create } from "zustand";
|
||||||
import {
|
import {
|
||||||
readFlowsFromDatabase,
|
readFlowsFromDatabase,
|
||||||
updateFlowInDatabase,
|
updateFlowInDatabase,
|
||||||
|
uploadFlowsToDatabase,
|
||||||
} from "../controllers/API";
|
} from "../controllers/API";
|
||||||
import { FlowType } from "../types/flow";
|
import { FlowType } from "../types/flow";
|
||||||
import { FlowState } from "../types/tabs";
|
import { FlowState } from "../types/tabs";
|
||||||
|
|
@ -25,6 +26,12 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
flows: [],
|
flows: [],
|
||||||
|
setFlows: (flows: FlowType[]) => {
|
||||||
|
set({
|
||||||
|
flows,
|
||||||
|
currentFlow: flows.find((flow) => flow.id === get().currentFlowId),
|
||||||
|
});
|
||||||
|
},
|
||||||
currentFlow: undefined,
|
currentFlow: undefined,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
setIsLoading: (isLoading: boolean) => set({ isLoading }),
|
setIsLoading: (isLoading: boolean) => set({ isLoading }),
|
||||||
|
|
@ -52,7 +59,8 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
|
||||||
.then((dbData) => {
|
.then((dbData) => {
|
||||||
if (dbData) {
|
if (dbData) {
|
||||||
const { data, flows } = processFlows(dbData, false);
|
const { data, flows } = processFlows(dbData, false);
|
||||||
set({ flows, isLoading: false });
|
get().setFlows(flows);
|
||||||
|
set({ isLoading: false });
|
||||||
useTypesStore.setState((state) => ({
|
useTypesStore.setState((state) => ({
|
||||||
data: { ...state.data, ["saved_components"]: data },
|
data: { ...state.data, ["saved_components"]: data },
|
||||||
}));
|
}));
|
||||||
|
|
@ -94,14 +102,14 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
|
||||||
.getState()
|
.getState()
|
||||||
.setSuccessData({ title: "Changes saved successfully" });
|
.setSuccessData({ title: "Changes saved successfully" });
|
||||||
}
|
}
|
||||||
set((oldState) => ({
|
get().setFlows(
|
||||||
flows: oldState.flows.map((flow) => {
|
get().flows.map((flow) => {
|
||||||
if (flow.id === updatedFlow.id) {
|
if (flow.id === updatedFlow.id) {
|
||||||
return updatedFlow;
|
return updatedFlow;
|
||||||
}
|
}
|
||||||
return flow;
|
return flow;
|
||||||
}),
|
})
|
||||||
}));
|
);
|
||||||
//update tabs state
|
//update tabs state
|
||||||
|
|
||||||
useFlowStore.setState({ isPending: false });
|
useFlowStore.setState({ isPending: false });
|
||||||
|
|
@ -117,6 +125,35 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
uploadFlows: () => {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "file";
|
||||||
|
// add a change event listener to the file input
|
||||||
|
input.onchange = (event: Event) => {
|
||||||
|
// check if the file type is application/json
|
||||||
|
if (
|
||||||
|
(event.target as HTMLInputElement).files![0].type ===
|
||||||
|
"application/json"
|
||||||
|
) {
|
||||||
|
// get the file from the file input
|
||||||
|
const file = (event.target as HTMLInputElement).files![0];
|
||||||
|
// read the file as text
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
uploadFlowsToDatabase(formData).then(() => {
|
||||||
|
get()
|
||||||
|
.refreshFlows()
|
||||||
|
.then(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// trigger the file input click event to open the file dialog
|
||||||
|
input.click();
|
||||||
|
});
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useFlowsManagerStore;
|
export default useFlowsManagerStore;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { FlowState, FlowsState } from "../../tabs";
|
||||||
|
|
||||||
export type FlowsManagerStoreType = {
|
export type FlowsManagerStoreType = {
|
||||||
flows: Array<FlowType>;
|
flows: Array<FlowType>;
|
||||||
|
setFlows: (flows: FlowType[]) => void;
|
||||||
currentFlow: FlowType | undefined;
|
currentFlow: FlowType | undefined;
|
||||||
currentFlowId: string;
|
currentFlowId: string;
|
||||||
setCurrentFlowId: (currentFlowId: string) => void;
|
setCurrentFlowId: (currentFlowId: string) => void;
|
||||||
|
|
@ -15,4 +16,5 @@ export type FlowsManagerStoreType = {
|
||||||
refreshFlows: () => Promise<void>;
|
refreshFlows: () => Promise<void>;
|
||||||
saveFlow: (flow: FlowType, silent?: boolean) => Promise<void>;
|
saveFlow: (flow: FlowType, silent?: boolean) => Promise<void>;
|
||||||
autoSaveCurrentFlow: (nodes: Node[], edges: Edge[], viewport: Viewport) => void;
|
autoSaveCurrentFlow: (nodes: Node[], edges: Edge[], viewport: Viewport) => void;
|
||||||
|
uploadFlows: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import {
|
||||||
updateEdgesHandleIdsType,
|
updateEdgesHandleIdsType,
|
||||||
} from "../types/utils/reactflowUtils";
|
} from "../types/utils/reactflowUtils";
|
||||||
import { createRandomKey, getFieldTitle, toTitleCase } from "./utils";
|
import { createRandomKey, getFieldTitle, toTitleCase } from "./utils";
|
||||||
|
import { downloadFlowsFromDatabase } from "../controllers/API";
|
||||||
const uid = new ShortUniqueId({ length: 5 });
|
const uid = new ShortUniqueId({ length: 5 });
|
||||||
|
|
||||||
export function cleanEdges(nodes: Node[], edges: Edge[]) {
|
export function cleanEdges(nodes: Node[], edges: Edge[]) {
|
||||||
|
|
@ -1205,3 +1206,48 @@ export function templatesGenerator(data: APIObjectType) {
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function downloadFlow(
|
||||||
|
flow: FlowType,
|
||||||
|
flowName: string,
|
||||||
|
flowDescription?: string
|
||||||
|
) {
|
||||||
|
let clonedFlow = cloneDeep(flow);
|
||||||
|
removeFileNameFromComponents(clonedFlow);
|
||||||
|
// create a data URI with the current flow data
|
||||||
|
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
||||||
|
JSON.stringify({
|
||||||
|
...clonedFlow,
|
||||||
|
name: flowName,
|
||||||
|
description: flowDescription,
|
||||||
|
})
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
// create a link element and set its properties
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = jsonString;
|
||||||
|
link.download = `${
|
||||||
|
flowName && flowName != ""
|
||||||
|
? flowName
|
||||||
|
: flow.name
|
||||||
|
}.json`;
|
||||||
|
|
||||||
|
// simulate a click on the link element to trigger the download
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadFlows() {
|
||||||
|
downloadFlowsFromDatabase().then((flows) => {
|
||||||
|
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
||||||
|
JSON.stringify(flows)
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
// create a link element and set its properties
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = jsonString;
|
||||||
|
link.download = `flows.json`;
|
||||||
|
|
||||||
|
// simulate a click on the link element to trigger the download
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue