diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 4bcdf2779..ddb007047 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -817,3 +817,46 @@ export async function getStoreTags() { export const postLikeComponent = (componentId: string) => { return api.post(`${BASE_URL_API}store/users/likes/${componentId}`); }; + +/** + * Updates an existing flow in the Store. + * + * @param {FlowType} updatedFlow - The updated flow data. + * @returns {Promise} The updated flow data. + * @throws Will throw an error if the update fails. + */ +export async function updateFlowStore( + newFlow: { + name?: string; + data: ReactFlowJsonObject | null; + description?: string; + style?: FlowStyleType; + is_component?: boolean; + parent?: string; + last_tested_version?: string; + }, + tags: string[], + publicFlow = false, + id: string +): Promise { + try { + const response = await api.patch(`${BASE_URL_API}store/components/${id}`, { + name: newFlow.name, + data: newFlow.data, + description: newFlow.description, + is_component: newFlow.is_component, + parent: newFlow.parent, + tags: tags, + private: !publicFlow, + last_tested_version: newFlow.last_tested_version, + }); + + if (response.status !== 201) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.data; + } catch (error) { + console.error(error); + throw error; + } +} diff --git a/src/frontend/src/modals/shareModal/index.tsx b/src/frontend/src/modals/shareModal/index.tsx index 9f27d82bc..90f05f1a0 100644 --- a/src/frontend/src/modals/shareModal/index.tsx +++ b/src/frontend/src/modals/shareModal/index.tsx @@ -1,3 +1,4 @@ +import { Loader2 } from "lucide-react"; import { ReactNode, useContext, useEffect, useMemo, useState } from "react"; import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import IconComponent from "../../components/genericIconComponent"; @@ -11,6 +12,7 @@ import { getStoreComponents, getStoreTags, saveFlowStore, + updateFlowStore, } from "../../controllers/API"; import { FlowType } from "../../types/flow"; import { @@ -50,7 +52,9 @@ export default function ShareModal({ const [loadingTags, setLoadingTags] = useState(false); const [sharePublic, setSharePublic] = useState(true); const [selectedTags, setSelectedTags] = useState([]); - const [unavaliableNames, setUnavaliableNames] = useState([]); + const [unavaliableNames, setUnavaliableNames] = useState< + { id: string; name: string }[] + >([]); const { saveFlow, flows, tabId } = useContext(FlowsContext); const [loadingNames, setLoadingNames] = useState(false); @@ -74,17 +78,18 @@ export default function ShareModal({ async function handleGetNames() { setLoadingNames(true); - const unavaliableNames: Array = []; - await getStoreComponents({ fields: ["name"], filterByUser: true }).then( - (res) => { - res?.results?.forEach((element: any) => { - if (element.is_component === is_component) - unavaliableNames.push(element.name); - }); - setUnavaliableNames(unavaliableNames); - setLoadingNames(false); - } - ); + const unavaliableNames: Array<{ id: string; name: string }> = []; + await getStoreComponents({ + fields: ["name", "id"], + filterByUser: true, + }).then((res) => { + res?.results?.forEach((element: any) => { + if (element.is_component === is_component) + unavaliableNames.push({ name: element.name, id: element.id }); + }); + setUnavaliableNames(unavaliableNames); + setLoadingNames(false); + }); } useEffect(() => { @@ -92,7 +97,7 @@ export default function ShareModal({ setDescription(component?.description ?? ""); }, [component, open, internalOpen]); - const handleShareComponent = async () => { + const handleShareComponent = async (update = false) => { //remove file names from flows before sharing removeFileNameFromComponents(component); const flow: FlowType = checked @@ -113,28 +118,42 @@ export default function ShareModal({ is_component: is_component, }); - await saveFlow(flows.find((flow) => flow.id === tabId)!, true); + function successShare() { + if (is_component) { + addFlow(true, flow); + } + setSuccessData({ + title: `${nameComponent} shared successfully`, + }); + } - saveFlowStore(flow!, getTagsIds(selectedTags, tags), sharePublic).then( - () => { - if (is_component) { - addFlow(true, flow); + await saveFlow(flows.find((flow) => flow.id === tabId)!, true); + if (!update) + saveFlowStore(flow!, getTagsIds(selectedTags, tags), sharePublic).then( + successShare, + (err) => { + setErrorData({ + title: "Error sharing " + is_component ? "component" : "flow", + list: [err["response"]["data"]["detail"]], + }); } - setSuccessData({ - title: `${nameComponent} shared successfully`, - }); - }, - (err) => { + ); + else + updateFlowStore( + flow!, + getTagsIds(selectedTags, tags), + sharePublic, + unavaliableNames.find((e) => e.name === name)!.id + ).then(successShare, (err) => { setErrorData({ title: "Error sharing " + is_component ? "component" : "flow", list: [err["response"]["data"]["detail"]], }); - } - ); + }); }; const handleUpdateComponent = () => { - handleShareComponent(); + handleShareComponent(true); if (setOpen) setOpen(false); else internalSetOpen(false); }; @@ -142,7 +161,7 @@ export default function ShareModal({ let modalConfirmationButton = useMemo(() => { return ( <> - {unavaliableNames.includes(name) ? ( + {unavaliableNames.find((element) => element.name === name) ? (
@@ -185,8 +214,18 @@ export default function ShareModal({ }} type="button" > - {is_component ? "Save and " : ""}Share{" "} - {!is_component ? "Flow" : ""} + {loadingNames ? ( + <> +
+ +
+ + ) : ( + <> + {is_component && !loadingNames ? "Save and " : ""}Share{" "} + {!is_component && !loadingNames ? "Flow" : ""} + + )} )} @@ -214,7 +253,7 @@ export default function ShareModal({ element.name)} description={description} setName={setName} setDescription={setDescription}