refactor: migrate flow handling hooks and clean up component code (#5024)

* ✨ (use-post-add-flow.ts): Add useGetRefreshFlows hook to refresh flows after adding a new flow
♻️ (use-add-flow.ts): Remove unnecessary refreshFlows hook and refactor code to use useGetRefreshFlows hook instead
📝 (dropdown/index.tsx): Update import paths for useDuplicateFlows and useSelectOptionsChange hooks
📝 (grid/index.tsx): Update import path for useDescriptionModal hook and remove commented out code related to playground functionality

✨ (MainPage): Add new hooks for handling duplicate flows, selecting all flows, changing select options, and managing selected flows
📝 (MainPage): Update import path for useDescriptionModal hook to correct location
🔧 (MainPage): Remove unused code related to playground functionality in ListComponent

🔧 (use-handle-duplicate.tsx): Remove unused file use-handle-duplicate.tsx
🔧 (componentsComponent/index.tsx): Remove unused imports and function call for useDuplicateFlows
📝 (homePage/index.tsx): Add console log to log data.flows for debugging purposes

* 📝 (dropdown/index.tsx): refactor useDuplicateFlows hook to accept an object with named parameters for better readability and maintainability
📝 (use-handle-duplicate.tsx): update useDuplicateFlows hook to accept an object with named parameters for better readability and maintainability
📝 (componentsComponent/index.tsx): remove import of useDuplicateFlows hook as it is no longer used in the file
📝 (homePage/index.tsx): remove console.log statement for data.flows in the HomePage component

* ✨ (FlowMenu/index.tsx): Add useGetRefreshFlowsQuery to fetch and refresh flows data when folders are fetched
♻️ (use-get-flow.ts): Refactor useGetFlow to include queryClient for refetching queries on settled response
✨ (use-get-refresh-flows-query.ts): Introduce useGetRefreshFlowsQuery to fetch and process flows data with query options
🔧 (use-post-add-flow.ts): Update usePostAddFlow to use queryClient for refetching queries instead of refreshFlows
🔧 (use-get-folders.ts): Update useGetFoldersQuery to remove unnecessary refreshFlows call and use queryClient for refetching queries
🔧 (use-upload-flow.ts): Remove unnecessary refreshFlows call from useUploadFlow to improve flow data handling

🔧 (FlowPage/index.tsx): Remove unused imports and variables for better code cleanliness and maintainability
🔧 (ViewPage/index.tsx): Remove unused imports and variables for better code cleanliness and maintainability

* 🔧 (twoEdges.spec.ts): remove unnecessary click on "input-inspection-retriever" element to improve test clarity and efficiency
This commit is contained in:
Cristhian Zanforlin Lousa 2024-12-03 17:08:44 -03:00 • committed by GitHub
commit 3f027396d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 196 additions and 261 deletions

View file

@ -19,6 +19,7 @@ import {
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { UPLOAD_ERROR_ALERT } from "@/constants/alerts_constants"; import { UPLOAD_ERROR_ALERT } from "@/constants/alerts_constants";
import { SAVED_HOVER } from "@/constants/constants"; import { SAVED_HOVER } from "@/constants/constants";
import { useGetRefreshFlowsQuery } from "@/controllers/API/queries/flows/use-get-refresh-flows-query";
import { useGetFoldersQuery } from "@/controllers/API/queries/folders/use-get-folders"; import { useGetFoldersQuery } from "@/controllers/API/queries/folders/use-get-folders";
import ExportModal from "@/modals/exportModal"; import ExportModal from "@/modals/exportModal";
import FlowLogsModal from "@/modals/flowLogsModal"; import FlowLogsModal from "@/modals/flowLogsModal";
@ -53,7 +54,16 @@ export const MenuBar = ({}: {}): JSX.Element => {
const onFlowPage = useFlowStore((state) => state.onFlowPage); const onFlowPage = useFlowStore((state) => state.onFlowPage);
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow); const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
const stopBuilding = useFlowStore((state) => state.stopBuilding); const stopBuilding = useFlowStore((state) => state.stopBuilding);
const { data: folders } = useGetFoldersQuery();
const { data: folders, isFetched: isFoldersFetched } = useGetFoldersQuery();
useGetRefreshFlowsQuery(
{
get_all: true,
header_flows: true,
},
{ enabled: isFoldersFetched },
);
const currentFolder = useMemo( const currentFolder = useMemo(
() => folders?.find((f) => f.id === currentFlow?.folder_id), () => folders?.find((f) => f.id === currentFlow?.folder_id),

View file

@ -1,6 +1,7 @@
import { useMutationFunctionType } from "@/types/api"; import { useMutationFunctionType } from "@/types/api";
import { FlowType } from "@/types/flow"; import { FlowType } from "@/types/flow";
import { processFlows } from "@/utils/reactflowUtils"; import { processFlows } from "@/utils/reactflowUtils";
import { useQueryClient } from "@tanstack/react-query";
import { api } from "../../api"; import { api } from "../../api";
import { getURL } from "../../helpers/constants"; import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor"; import { UseRequestProcessor } from "../../services/request-processor";
@ -14,6 +15,7 @@ export const useGetFlow: useMutationFunctionType<undefined, IGetFlow> = (
options, options,
) => { ) => {
const { mutate } = UseRequestProcessor(); const { mutate } = UseRequestProcessor();
const queryClient = useQueryClient();
const getFlowFn = async (payload: IGetFlow): Promise<FlowType> => { const getFlowFn = async (payload: IGetFlow): Promise<FlowType> => {
const response = await api.get<FlowType>( const response = await api.get<FlowType>(
@ -25,7 +27,19 @@ export const useGetFlow: useMutationFunctionType<undefined, IGetFlow> = (
return flows[0]; return flows[0];
}; };
const mutation = mutate(["useGetFlow"], getFlowFn, options); const mutation = mutate(["useGetFlow"], getFlowFn, {
...options,
onSettled: (response) => {
if (response) {
queryClient.refetchQueries({
queryKey: [
"useGetRefreshFlowsQuery",
{ get_all: true, header_flows: true },
],
});
}
},
});
return mutation; return mutation;
}; };

View file

@ -0,0 +1,91 @@
import buildQueryStringUrl from "@/controllers/utils/create-query-param-string";
import useAlertStore from "@/stores/alertStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useTypesStore } from "@/stores/typesStore";
import { useQueryFunctionType } from "@/types/api";
import { FlowType, PaginatedFlowsType } from "@/types/flow";
import {
extractFieldsFromComponenents,
processFlows,
} from "@/utils/reactflowUtils";
import { UseQueryOptions } from "@tanstack/react-query";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface GetFlowsParams {
components_only?: boolean;
get_all?: boolean;
header_flows?: boolean;
folder_id?: string;
remove_example_flows?: boolean;
page?: number;
size?: number;
}
const addQueryParams = (url: string, params: GetFlowsParams): string => {
return buildQueryStringUrl(url, params);
};
export const useGetRefreshFlowsQuery: useQueryFunctionType<
GetFlowsParams,
FlowType[] | PaginatedFlowsType
> = (params, options) => {
const { query } = UseRequestProcessor();
const setFlows = useFlowsManagerStore((state) => state.setFlows);
const setErrorData = useAlertStore((state) => state.setErrorData);
const getFlowsFn = async (
params: GetFlowsParams,
): Promise<FlowType[] | PaginatedFlowsType> => {
try {
const url = addQueryParams(`${getURL("FLOWS")}/`, params);
const { data: dbDataFlows } = await api.get<FlowType[]>(url);
if (params.components_only) {
return dbDataFlows;
}
const { data: dbDataComponents } = await api.get<FlowType[]>(
addQueryParams(`${getURL("FLOWS")}/`, {
components_only: true,
get_all: true,
}),
);
if (dbDataComponents) {
const { data } = processFlows(dbDataComponents);
useTypesStore.setState((state) => ({
data: { ...state.data, ["saved_components"]: data },
ComponentFields: extractFieldsFromComponenents({
...state.data,
["saved_components"]: data,
}),
}));
}
if (dbDataFlows) {
const flows = Array.isArray(dbDataFlows)
? dbDataFlows
: (dbDataFlows as { items: FlowType[] }).items;
setFlows(flows);
return flows;
}
return [];
} catch (e) {
setErrorData({
title: "Could not load flows from database",
});
throw e;
}
};
const queryResult = query(
["useGetRefreshFlowsQuery", params],
() => getFlowsFn(params || {}),
options as UseQueryOptions,
);
return queryResult;
};

View file

@ -35,7 +35,6 @@ export const usePostAddFlow: useMutationFunctionType<
gradient: payload.gradient || null, gradient: payload.gradient || null,
endpoint_name: payload.endpoint_name || null, endpoint_name: payload.endpoint_name || null,
}); });
return response.data; return response.data;
}; };
@ -45,9 +44,18 @@ export const usePostAddFlow: useMutationFunctionType<
{ {
...options, ...options,
onSettled: (response) => { onSettled: (response) => {
queryClient.refetchQueries({ if (response) {
queryKey: ["useGetFolder", response.folder_id ?? myCollectionId], queryClient.refetchQueries({
}); queryKey: [
"useGetRefreshFlowsQuery",
{ get_all: true, header_flows: true },
],
});
queryClient.refetchQueries({
queryKey: ["useGetFolder", response.folder_id ?? myCollectionId],
});
}
}, },
}, },
); );

View file

@ -2,19 +2,16 @@ import { DEFAULT_FOLDER } from "@/constants/constants";
import { FolderType } from "@/pages/MainPage/entities"; import { FolderType } from "@/pages/MainPage/entities";
import useAuthStore from "@/stores/authStore"; import useAuthStore from "@/stores/authStore";
import { useFolderStore } from "@/stores/foldersStore"; import { useFolderStore } from "@/stores/foldersStore";
import { useTypesStore } from "@/stores/typesStore";
import { useQueryFunctionType } from "@/types/api"; import { useQueryFunctionType } from "@/types/api";
import { api } from "../../api"; import { api } from "../../api";
import { getURL } from "../../helpers/constants"; import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor"; import { UseRequestProcessor } from "../../services/request-processor";
import { useGetRefreshFlows } from "../flows/use-get-refresh-flows";
export const useGetFoldersQuery: useQueryFunctionType< export const useGetFoldersQuery: useQueryFunctionType<
undefined, undefined,
FolderType[] FolderType[]
> = (options) => { > = (options) => {
const { query } = UseRequestProcessor(); const { query } = UseRequestProcessor();
const { mutateAsync: refreshFlows } = useGetRefreshFlows();
const setMyCollectionId = useFolderStore((state) => state.setMyCollectionId); const setMyCollectionId = useFolderStore((state) => state.setMyCollectionId);
const setFolders = useFolderStore((state) => state.setFolders); const setFolders = useFolderStore((state) => state.setFolders);
@ -29,9 +26,6 @@ export const useGetFoldersQuery: useQueryFunctionType<
const myCollectionId = data?.find((f) => f.name === DEFAULT_FOLDER)?.id; const myCollectionId = data?.find((f) => f.name === DEFAULT_FOLDER)?.id;
setMyCollectionId(myCollectionId); setMyCollectionId(myCollectionId);
setFolders(data); setFolders(data);
const { types } = useTypesStore.getState();
await refreshFlows({ get_all: true, header_flows: true });
return data; return data;
}; };

View file

@ -36,7 +36,6 @@ const useAddFlow = () => {
const myCollectionId = useFolderStore((state) => state.myCollectionId); const myCollectionId = useFolderStore((state) => state.myCollectionId);
const { mutate: postAddFlow } = usePostAddFlow(); const { mutate: postAddFlow } = usePostAddFlow();
const { mutate: refreshFlows } = useGetRefreshFlows();
const addFlow = async (params?: { const addFlow = async (params?: {
flow?: FlowType; flow?: FlowType;
@ -57,8 +56,6 @@ const useAddFlow = () => {
); );
}); });
// Create a new flow with a default name if no flow is provided. // Create a new flow with a default name if no flow is provided.
const folder_id = folderId ?? myCollectionId ?? "";
if (params?.override && flow) { if (params?.override && flow) {
const flowId = flows?.find((f) => f.name === flow.name); const flowId = flows?.find((f) => f.name === flow.name);
if (flowId) { if (flowId) {
@ -66,12 +63,11 @@ const useAddFlow = () => {
} }
} }
const folder_id = folderId ?? myCollectionId ?? "";
const flowsToCheckNames = flows?.filter( const flowsToCheckNames = flows?.filter(
(f) => f.folder_id === myCollectionId, (f) => f.folder_id === myCollectionId,
); );
const newFlow = createNewFlow(flowData!, folder_id, flow); const newFlow = createNewFlow(flowData!, folder_id, flow);
const newName = addVersionToDuplicates(newFlow, flowsToCheckNames ?? []); const newName = addVersionToDuplicates(newFlow, flowsToCheckNames ?? []);
newFlow.name = newName; newFlow.name = newName;
newFlow.folder_id = folder_id; newFlow.folder_id = folder_id;
@ -92,11 +88,6 @@ const useAddFlow = () => {
}), }),
})); }));
refreshFlows({
get_all: true,
header_flows: true,
});
setFlowToCanvas(createdFlow); setFlowToCanvas(createdFlow);
resolve(createdFlow.id); resolve(createdFlow.id);
}, },

View file

@ -90,7 +90,6 @@ const useUploadFlow = () => {
throw new Error("Invalid flow data"); throw new Error("Invalid flow data");
} }
} }
await refreshFlows({ get_all: true, header_flows: true });
} }
} catch (e) { } catch (e) {
throw e; throw e;

View file

@ -1,16 +1,13 @@
import { SidebarProvider } from "@/components/ui/sidebar"; import { SidebarProvider } from "@/components/ui/sidebar";
import { useGetFlow } from "@/controllers/API/queries/flows/use-get-flow"; import { useGetFlow } from "@/controllers/API/queries/flows/use-get-flow";
import { useGetRefreshFlows } from "@/controllers/API/queries/flows/use-get-refresh-flows";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate"; import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import useSaveFlow from "@/hooks/flows/use-save-flow"; import useSaveFlow from "@/hooks/flows/use-save-flow";
import { useIsMobile } from "@/hooks/use-mobile"; import { useIsMobile } from "@/hooks/use-mobile";
import { SaveChangesModal } from "@/modals/saveChangesModal"; import { SaveChangesModal } from "@/modals/saveChangesModal";
import useAlertStore from "@/stores/alertStore"; import useAlertStore from "@/stores/alertStore";
import { useTypesStore } from "@/stores/typesStore";
import { customStringify } from "@/utils/reactflowUtils"; import { customStringify } from "@/utils/reactflowUtils";
import { useEffect } from "react"; import { useEffect } from "react";
import { useBlocker, useParams } from "react-router-dom"; import { useBlocker, useParams } from "react-router-dom";
import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore";
import Page from "./components/PageComponent"; import Page from "./components/PageComponent";
@ -29,7 +26,6 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
const isBuilding = useFlowStore((state) => state.isBuilding); const isBuilding = useFlowStore((state) => state.isBuilding);
const blocker = useBlocker(changesNotSaved || isBuilding); const blocker = useBlocker(changesNotSaved || isBuilding);
const version = useDarkStore((state) => state.version);
const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage); const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage);
const { id } = useParams(); const { id } = useParams();
const navigate = useCustomNavigate(); const navigate = useCustomNavigate();
@ -40,10 +36,6 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
const flowToCanvas = useFlowsManagerStore((state) => state.flowToCanvas); const flowToCanvas = useFlowsManagerStore((state) => state.flowToCanvas);
const { mutateAsync: refreshFlows } = useGetRefreshFlows();
const setIsLoading = useFlowsManagerStore((state) => state.setIsLoading);
const types = useTypesStore((state) => state.types);
const updatedAt = currentSavedFlow?.updated_at; const updatedAt = currentSavedFlow?.updated_at;
const autoSaving = useFlowsManagerStore((state) => state.autoSaving); const autoSaving = useFlowsManagerStore((state) => state.autoSaving);
const stopBuilding = useFlowStore((state) => state.stopBuilding); const stopBuilding = useFlowStore((state) => state.stopBuilding);
@ -114,10 +106,6 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
flowToCanvas flowToCanvas
? setCurrentFlow(flowToCanvas) ? setCurrentFlow(flowToCanvas)
: getFlowToAddToCanvas(isAnExistingFlowId); : getFlowToAddToCanvas(isAnExistingFlowId);
} else if (!flows) {
setIsLoading(true);
await refreshFlows({ get_all: true, header_flows: true });
setIsLoading(false);
} }
}; };
awaitgetTypes(); awaitgetTypes();

View file

@ -3,8 +3,8 @@ import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import useAlertStore from "@/stores/alertStore"; import useAlertStore from "@/stores/alertStore";
import { FlowType } from "@/types/flow"; import { FlowType } from "@/types/flow";
import { downloadFlow } from "@/utils/reactflowUtils"; import { downloadFlow } from "@/utils/reactflowUtils";
import useDuplicateFlows from "../../oldComponents/componentsComponent/hooks/use-handle-duplicate"; import useDuplicateFlows from "../../hooks/use-handle-duplicate";
import useSelectOptionsChange from "../../oldComponents/componentsComponent/hooks/use-select-options-change"; import useSelectOptionsChange from "../../hooks/use-select-options-change";
type DropdownComponentProps = { type DropdownComponentProps = {
flowData: FlowType; flowData: FlowType;
@ -15,20 +15,15 @@ type DropdownComponentProps = {
const DropdownComponent = ({ const DropdownComponent = ({
flowData, flowData,
setOpenDelete, setOpenDelete,
handlePlaygroundClick,
}: DropdownComponentProps) => { }: DropdownComponentProps) => {
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 { handleDuplicate } = useDuplicateFlows( const { handleDuplicate } = useDuplicateFlows({
[flowData.id], selectedFlowsComponentsCards: [flowData.id],
[flowData], allFlows: [flowData],
() => {},
setSuccessData, setSuccessData,
() => {}, });
() => {},
"flow",
);
const handleExport = () => { const handleExport = () => {
downloadFlow(flowData, flowData.name, flowData.description); downloadFlow(flowData, flowData.name, flowData.description);
@ -45,30 +40,6 @@ const DropdownComponent = ({
return ( return (
<> <>
{/* <DropdownMenuItem onClick={() => {}} className="cursor-pointer">
<ForwardedIconComponent
name="square-pen"
aria-hidden="true"
className="mr-2 h-4 w-4"
/>
Edit details
</DropdownMenuItem> */}
{/* {handlePlaygroundClick && (
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
handlePlaygroundClick();
}}
className="cursor-pointer sm:hidden"
>
<ForwardedIconComponent
name="play"
aria-hidden="true"
className="mr-2 h-4 w-4"
/>
Playground
</DropdownMenuItem>
)} */}
<DropdownMenuItem <DropdownMenuItem
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();

View file

@ -18,21 +18,19 @@ import { swatchColors } from "@/utils/styleUtils";
import { cn, getNumberFromString } from "@/utils/utils"; import { cn, getNumberFromString } from "@/utils/utils";
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import useDescriptionModal from "../../oldComponents/componentsComponent/hooks/use-description-modal"; import useDescriptionModal from "../../hooks/use-description-modal";
import { useGetTemplateStyle } from "../../utils/get-template-style"; import { useGetTemplateStyle } from "../../utils/get-template-style";
import { timeElapsed } from "../../utils/time-elapse"; import { timeElapsed } from "../../utils/time-elapse";
import DropdownComponent from "../dropdown"; import DropdownComponent from "../dropdown";
const GridComponent = ({ flowData }: { flowData: FlowType }) => { const GridComponent = ({ flowData }: { flowData: FlowType }) => {
const navigate = useCustomNavigate(); const navigate = useCustomNavigate();
/* const [openPlayground, setOpenPlayground] = useState(false);
const [loadingPlayground, setLoadingPlayground] = useState(false); */
const [openDelete, setOpenDelete] = useState(false); const [openDelete, setOpenDelete] = useState(false);
const setSuccessData = useAlertStore((state) => state.setSuccessData); const setSuccessData = useAlertStore((state) => state.setSuccessData);
const { deleteFlow } = useDeleteFlow(); const { deleteFlow } = useDeleteFlow();
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
/* const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow); */
const { folderId } = useParams(); const { folderId } = useParams();
const isComponent = flowData.is_component ?? false; const isComponent = flowData.is_component ?? false;
const setFlowToCanvas = useFlowsManagerStore( const setFlowToCanvas = useFlowsManagerStore(
@ -43,38 +41,6 @@ const GridComponent = ({ flowData }: { flowData: FlowType }) => {
const editFlowLink = `/flow/${flowData.id}${folderId ? `/folder/${folderId}` : ""}`; const editFlowLink = `/flow/${flowData.id}${folderId ? `/folder/${folderId}` : ""}`;
function hasPlayground(flow?: FlowType) {
if (!flow) {
return false;
}
const { inputs, outputs } = getInputsAndOutputs(flow?.data?.nodes ?? []);
return inputs.length > 0 || outputs.length > 0;
}
/* const handlePlaygroundClick = () => {
track("Playground Button Clicked", { flowId: flowData.id });
setLoadingPlayground(true);
if (flowData) {
if (!hasPlayground(flowData)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(flowData);
// setOpenPlayground(true);
setLoadingPlayground(false);
} else {
setErrorData({
title: "Error",
list: ["Error getting flow data."],
});
}
}; */
const handleClick = async () => { const handleClick = async () => {
if (!isComponent) { if (!isComponent) {
await setFlowToCanvas(flowData); await setFlowToCanvas(flowData);
@ -167,35 +133,8 @@ const GridComponent = ({ flowData }: { flowData: FlowType }) => {
<div className="line-clamp-2 h-full pt-5 text-sm text-primary"> <div className="line-clamp-2 h-full pt-5 text-sm text-primary">
{flowData.description} {flowData.description}
</div> </div>
{/* <div className="flex justify-end pt-[24px]">
{flowData.is_component ? (
<></>
) : (
<Button
disabled={loadingPlayground || !hasPlayground(flowData)}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handlePlaygroundClick();
}}
variant="outline"
>
Playground
</Button>
)}
</div> */}
</Card> </Card>
{/* {openPlayground && (
<IOModal
key={flowData.id}
cleanOnClose={true}
open={openPlayground}
setOpen={setOpenPlayground}
>
<></>
</IOModal>
)} */}
{openDelete && ( {openDelete && (
<DeleteConfirmationModal <DeleteConfirmationModal
open={openDelete} open={openDelete}

View file

@ -17,20 +17,18 @@ import { swatchColors } from "@/utils/styleUtils";
import { cn, getNumberFromString } from "@/utils/utils"; import { cn, getNumberFromString } from "@/utils/utils";
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import useDescriptionModal from "../../oldComponents/componentsComponent/hooks/use-description-modal"; import useDescriptionModal from "../../hooks/use-description-modal";
import { useGetTemplateStyle } from "../../utils/get-template-style"; import { useGetTemplateStyle } from "../../utils/get-template-style";
import { timeElapsed } from "../../utils/time-elapse"; import { timeElapsed } from "../../utils/time-elapse";
import DropdownComponent from "../dropdown"; import DropdownComponent from "../dropdown";
const ListComponent = ({ flowData }: { flowData: FlowType }) => { const ListComponent = ({ flowData }: { flowData: FlowType }) => {
const navigate = useCustomNavigate(); const navigate = useCustomNavigate();
/* const [openPlayground, setOpenPlayground] = useState(false);
const [loadingPlayground, setLoadingPlayground] = useState(false); */
const [openDelete, setOpenDelete] = useState(false); const [openDelete, setOpenDelete] = useState(false);
const setSuccessData = useAlertStore((state) => state.setSuccessData); const setSuccessData = useAlertStore((state) => state.setSuccessData);
const { deleteFlow } = useDeleteFlow(); const { deleteFlow } = useDeleteFlow();
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
/* const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow); */
const { folderId } = useParams(); const { folderId } = useParams();
const isComponent = flowData.is_component ?? false; const isComponent = flowData.is_component ?? false;
const setFlowToCanvas = useFlowsManagerStore( const setFlowToCanvas = useFlowsManagerStore(
@ -40,38 +38,6 @@ const ListComponent = ({ flowData }: { flowData: FlowType }) => {
const editFlowLink = `/flow/${flowData.id}${folderId ? `/folder/${folderId}` : ""}`; const editFlowLink = `/flow/${flowData.id}${folderId ? `/folder/${folderId}` : ""}`;
/* function hasPlayground(flow?: FlowType) {
if (!flow) {
return false;
}
const { inputs, outputs } = getInputsAndOutputs(flow?.data?.nodes ?? []);
return inputs.length > 0 || outputs.length > 0;
} */
/* const handlePlaygroundClick = () => {
track("Playground Button Clicked", { flowId: flowData.id });
setLoadingPlayground(true);
if (flowData) {
if (!hasPlayground(flowData)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(flowData);
setOpenPlayground(true);
setLoadingPlayground(false);
} else {
setErrorData({
title: "Error",
list: ["Error getting flow data."],
});
}
}; */
const handleClick = async () => { const handleClick = async () => {
if (!isComponent) { if (!isComponent) {
await setFlowToCanvas(flowData); await setFlowToCanvas(flowData);
@ -155,22 +121,6 @@ const ListComponent = ({ flowData }: { flowData: FlowType }) => {
{/* right side */} {/* right side */}
<div className="ml-5 flex items-center gap-2"> <div className="ml-5 flex items-center gap-2">
{/* {flowData.is_component ? (
<></>
) : (
<Button
variant="outline"
disabled={loadingPlayground || !hasPlayground(flowData)}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handlePlaygroundClick();
}}
className="hidden sm:block"
>
Playground
</Button>
)} */}
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button <Button
@ -202,16 +152,7 @@ const ListComponent = ({ flowData }: { flowData: FlowType }) => {
</DropdownMenu> </DropdownMenu>
</div> </div>
</Card> </Card>
{/* {openPlayground && (
<IOModal
key={flowData.id}
cleanOnClose={true}
open={openPlayground}
setOpen={setOpenPlayground}
>
<></>
</IOModal>
)} */}
{openDelete && ( {openDelete && (
<DeleteConfirmationModal <DeleteConfirmationModal
open={openDelete} open={openDelete}

View file

@ -1,6 +1,6 @@
import cloneDeep from "lodash/cloneDeep"; import cloneDeep from "lodash/cloneDeep";
import { useEffect } from "react"; import { useEffect } from "react";
import { FlowType } from "../../../../../types/flow"; import { FlowType } from "../../../types/flow";
const useFilteredFlows = ( const useFilteredFlows = (
flowsFromFolder: FlowType[], flowsFromFolder: FlowType[],

View file

@ -0,0 +1,46 @@
import { usePostAddFlow } from "@/controllers/API/queries/flows/use-post-add-flow";
import { useFolderStore } from "@/stores/foldersStore";
import { addVersionToDuplicates, createNewFlow } from "@/utils/reactflowUtils";
import { useParams } from "react-router-dom";
type UseDuplicateFlowsParams = {
selectedFlowsComponentsCards: string[];
allFlows: any[];
setSuccessData: (data: { title: string }) => void;
};
const useDuplicateFlows = ({
selectedFlowsComponentsCards,
allFlows,
setSuccessData,
}: UseDuplicateFlowsParams) => {
const { mutateAsync: postAddFlow } = usePostAddFlow();
const { folderId } = useParams();
const myCollectionId = useFolderStore((state) => state.myCollectionId);
const handleDuplicate = async () => {
selectedFlowsComponentsCards.map(async (selectedFlow) => {
const currentFlow = allFlows.find((flow) => flow.id === selectedFlow);
const folder_id = folderId ?? myCollectionId ?? "";
const flowsToCheckNames = allFlows?.filter(
(f) => f.folder_id === folder_id,
);
const newFlow = createNewFlow(currentFlow.data, folder_id, currentFlow);
const newName = addVersionToDuplicates(newFlow, flowsToCheckNames ?? []);
newFlow.name = newName;
newFlow.folder_id = folder_id;
await postAddFlow(newFlow);
setSuccessData({
title: `${newFlow.is_component ? "Component" : "Flow"} duplicated successfully`,
});
});
};
return { handleDuplicate };
};
export default useDuplicateFlows;

View file

@ -1,5 +1,5 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { FlowType } from "../../../../../types/flow"; import { FlowType } from "../../../types/flow";
const useSelectAll = ( const useSelectAll = (
flowsFromFolder: FlowType[], flowsFromFolder: FlowType[],

View file

@ -1,41 +0,0 @@
import useAddFlow from "@/hooks/flows/use-add-flow";
import { useCallback } from "react";
const useDuplicateFlows = (
selectedFlowsComponentsCards: string[],
allFlows: any[],
resetFilter: () => void,
setSuccessData: (data: { title: string }) => void,
setSelectedFlowsComponentsCards: (
selectedFlowsComponentsCards: string[],
) => void,
handleSelectAll: (select: boolean) => void,
cardTypes: string,
) => {
const addFlow = useAddFlow();
const handleDuplicate = useCallback(() => {
Promise.all(
selectedFlowsComponentsCards.map((selectedFlow) =>
addFlow({ flow: allFlows.find((flow) => flow.id === selectedFlow) }),
),
).then(() => {
resetFilter();
setSuccessData({ title: `${cardTypes} duplicated successfully` });
setSelectedFlowsComponentsCards([]);
handleSelectAll(false);
});
}, [
selectedFlowsComponentsCards,
addFlow,
allFlows,
resetFilter,
setSuccessData,
setSelectedFlowsComponentsCards,
handleSelectAll,
cardTypes,
]);
return { handleDuplicate };
};
export default useDuplicateFlows;

View file

@ -16,15 +16,14 @@ import { FlowType } from "../../../../types/flow";
import useFileDrop from "../../hooks/use-on-file-drop"; import useFileDrop from "../../hooks/use-on-file-drop";
import { getNameByType } from "../../utils/get-name-by-type"; import { getNameByType } from "../../utils/get-name-by-type";
import useDescriptionModal from "../../hooks/use-description-modal";
import useFilteredFlows from "../../hooks/use-filtered-flows";
import useSelectAll from "../../hooks/use-handle-select-all";
import useSelectOptionsChange from "../../hooks/use-select-options-change";
import useSelectedFlows from "../../hooks/use-selected-flows";
import EmptyComponent from "../emptyComponent"; import EmptyComponent from "../emptyComponent";
import HeaderComponent from "../headerComponent"; import HeaderComponent from "../headerComponent";
import CollectionCard from "./components/collectionCard"; import CollectionCard from "./components/collectionCard";
import useDescriptionModal from "./hooks/use-description-modal";
import useFilteredFlows from "./hooks/use-filtered-flows";
import useDuplicateFlows from "./hooks/use-handle-duplicate";
import useSelectAll from "./hooks/use-handle-select-all";
import useSelectOptionsChange from "./hooks/use-select-options-change";
import useSelectedFlows from "./hooks/use-selected-flows";
export default function ComponentsComponent({ export default function ComponentsComponent({
type = "all", type = "all",
@ -106,15 +105,7 @@ export default function ComponentsComponent({
setValue, setValue,
); );
const { handleDuplicate } = useDuplicateFlows( const handleDuplicate = () => {};
selectedFlowsComponentsCards,
flowsFromFolder,
resetFilter,
setSuccessData,
setSelectedFlowsComponentsCards,
handleSelectAll,
cardTypes,
);
const { mutate: mutateDownloadMultipleFlows } = const { mutate: mutateDownloadMultipleFlows } =
usePostDownloadMultipleFlows(); usePostDownloadMultipleFlows();

View file

@ -14,9 +14,6 @@ export default function ViewPage() {
const flows = useFlowsManagerStore((state) => state.flows); const flows = useFlowsManagerStore((state) => state.flows);
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
const { mutateAsync: refreshFlows } = useGetRefreshFlows();
const setIsLoading = useFlowsManagerStore((state) => state.setIsLoading);
const types = useTypesStore((state) => state.types);
// Set flow tab id // Set flow tab id
useEffect(() => { useEffect(() => {
@ -30,10 +27,6 @@ export default function ViewPage() {
} }
setCurrentFlow(isAnExistingFlow); setCurrentFlow(isAnExistingFlow);
} else if (!flows) {
setIsLoading(true);
await refreshFlows({ get_all: true, header_flows: true });
setIsLoading(false);
} }
}; };
awaitgetTypes(); awaitgetTypes();