refactor: change post/patch folders requests to use UseQuery (#2917)
* ✨ (sidebarComponent): Add usePostFolders hook to handle adding new folders in the sidebar 📝 (folders): Add use-post-folders and use-patch-folders hooks for handling post and patch requests for folders 🔧 (BundleModal): Remove useFolderSubmit hook and directly use usePostFolders hook for adding and updating folders in the modal * ✨ (sidebarComponent): Add usePatchFolders hook to handle updating folders in the sidebar component 🔧 (use-patch-folders): Refactor IPatchAddFolders interface to IPatchPatchFolders for better naming consistency 🔧 (use-patch-folders): Refactor addFoldersFn to patchFoldersFn for better function naming 🔧 (use-patch-folders): Update patchFoldersFn to send patch request to specific folder endpoint 🔧 (use-patch-folders): Update patchFoldersFn to handle updating folders and return updated data 🔧 (use-patch-folders): Update usePatchFolders hook to use patchFoldersFn for mutation 🔧 (use-post-folders): Remove unnecessary call to getFoldersApi after posting folders 🔧 (BundleModal): Remove BundleModal component and entities as they are no longer needed 🔧 (BundleModal/index.tsx): Remove unused imports and clean up code 🔧 (foldersModal/component/index.tsx): Remove unused imports and clean up code 🔧 (foldersModal/entities/index.ts): Remove unused zod schema and clean up code 🔧 (foldersModal/hooks/submit-folder.tsx): Remove unused imports and clean up code ✨ (foldersModal/index.tsx): Remove unused FoldersModal component from modalsComponent to optimize code and improve maintainability. * 📝 (index.tsx): Remove unused openFolderModal and setOpenFolderModal props from ModalsComponent ♻️ (services/index.ts): Remove addFolder, updateFolder, and deleteFolder functions as they are not used in the application ♻️ (foldersStore.tsx): Remove unused import statements for uploadFlowsFromFolders from services and related functions * 📝 (index.tsx): replace async/await with synchronous function call to refresh folders after successful operation
This commit is contained in:
parent
8f678de217
commit
6c5b487e47
16 changed files with 119 additions and 655 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
import { usePostUploadFolders } from "@/controllers/API/queries/folders";
|
import {
|
||||||
|
usePatchFolders,
|
||||||
|
usePostUploadFolders,
|
||||||
|
} from "@/controllers/API/queries/folders";
|
||||||
|
import { usePostFolders } from "@/controllers/API/queries/folders/use-post-folders";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { FolderType } from "../../../../pages/MainPage/entities";
|
import { FolderType } from "../../../../pages/MainPage/entities";
|
||||||
import { addFolder, updateFolder } from "../../../../pages/MainPage/services";
|
|
||||||
import { handleDownloadFolderFn } from "../../../../pages/MainPage/utils/handle-download-folder";
|
import { handleDownloadFolderFn } from "../../../../pages/MainPage/utils/handle-download-folder";
|
||||||
import useAlertStore from "../../../../stores/alertStore";
|
import useAlertStore from "../../../../stores/alertStore";
|
||||||
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
||||||
|
|
@ -51,6 +54,7 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
const getFolderById = useFolderStore((state) => state.getFolderById);
|
const getFolderById = useFolderStore((state) => state.getFolderById);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
|
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
||||||
|
|
||||||
const handleFolderChange = () => {
|
const handleFolderChange = () => {
|
||||||
getFolderById(folderId);
|
getFolderById(folderId);
|
||||||
|
|
@ -110,10 +114,22 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
handleDownloadFolderFn(id);
|
handleDownloadFolderFn(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { mutate: mutateAddFolder } = usePostFolders();
|
||||||
|
const { mutate: mutateUpdateFolder } = usePatchFolders();
|
||||||
|
|
||||||
function addNewFolder() {
|
function addNewFolder() {
|
||||||
addFolder({ name: "New Folder", parent_id: null, description: "" }).then(
|
mutateAddFolder(
|
||||||
(res) => {
|
{
|
||||||
refreshFolders();
|
data: {
|
||||||
|
name: "New Folder",
|
||||||
|
parent_id: null,
|
||||||
|
description: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
refreshFolders();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -151,22 +167,31 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
flows: item.flows?.length > 0 ? item.flows : [],
|
flows: item.flows?.length > 0 ? item.flows : [],
|
||||||
components: item.components?.length > 0 ? item.components : [],
|
components: item.components?.length > 0 ? item.components : [],
|
||||||
};
|
};
|
||||||
const updatedFolder = await updateFolder(body, item.id!);
|
|
||||||
|
|
||||||
const updatedFolderIndex = folders.findIndex(
|
mutateUpdateFolder(
|
||||||
(f) => f.id === updatedFolder.id,
|
{
|
||||||
);
|
data: body,
|
||||||
|
folderId: item.id!,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (updatedFolder) => {
|
||||||
|
const updatedFolderIndex = folders.findIndex(
|
||||||
|
(f) => f.id === updatedFolder.id,
|
||||||
|
);
|
||||||
|
|
||||||
const updateFolders = [...folders];
|
const updateFolders = [...folders];
|
||||||
updateFolders[updatedFolderIndex] = updatedFolder;
|
updateFolders[updatedFolderIndex] = updatedFolder;
|
||||||
|
|
||||||
setFolders(updateFolders);
|
setFolders(updateFolders);
|
||||||
setFoldersNames({});
|
setFoldersNames({});
|
||||||
setEditFolderName(
|
setEditFolderName(
|
||||||
folders.map((obj) => ({
|
folders.map((obj) => ({
|
||||||
name: obj.name,
|
name: obj.name,
|
||||||
edit: false,
|
edit: false,
|
||||||
})),
|
})),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
setFoldersNames((old) => ({
|
setFoldersNames((old) => ({
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
export * from "./use-delete-folders";
|
export * from "./use-delete-folders";
|
||||||
|
export * from "./use-patch-folders";
|
||||||
|
export * from "./use-post-folders";
|
||||||
export * from "./use-post-upload-folders";
|
export * from "./use-post-upload-folders";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { AddFolderType } from "@/pages/MainPage/entities";
|
||||||
|
import { useFolderStore } from "@/stores/foldersStore";
|
||||||
|
import { useMutationFunctionType } from "@/types/api";
|
||||||
|
import { api } from "../../api";
|
||||||
|
import { getURL } from "../../helpers/constants";
|
||||||
|
import { UseRequestProcessor } from "../../services/request-processor";
|
||||||
|
|
||||||
|
interface IPatchPatchFolders {
|
||||||
|
data: AddFolderType;
|
||||||
|
folderId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const usePatchFolders: useMutationFunctionType<
|
||||||
|
undefined,
|
||||||
|
IPatchPatchFolders
|
||||||
|
> = (options?) => {
|
||||||
|
const { mutate } = UseRequestProcessor();
|
||||||
|
|
||||||
|
const patchFoldersFn = async (
|
||||||
|
newFolder: IPatchPatchFolders,
|
||||||
|
): Promise<void> => {
|
||||||
|
const payload = {
|
||||||
|
name: newFolder.data.name,
|
||||||
|
description: newFolder.data.description,
|
||||||
|
flows_list: newFolder.data.flows ?? [],
|
||||||
|
components_list: newFolder.data.components ?? [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await api.patch(
|
||||||
|
`${getURL("FOLDERS")}/${newFolder.folderId}`,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
return res.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutation = mutate(["usePatchFolders"], patchFoldersFn, options);
|
||||||
|
|
||||||
|
return mutation;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { AddFolderType } from "@/pages/MainPage/entities";
|
||||||
|
import useFlowsManagerStore from "@/stores/flowsManagerStore";
|
||||||
|
import { useFolderStore } from "@/stores/foldersStore";
|
||||||
|
import { Users, useMutationFunctionType } from "@/types/api";
|
||||||
|
import { api } from "../../api";
|
||||||
|
import { getURL } from "../../helpers/constants";
|
||||||
|
import { UseRequestProcessor } from "../../services/request-processor";
|
||||||
|
|
||||||
|
interface IPostAddFolders {
|
||||||
|
data: AddFolderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const usePostFolders: useMutationFunctionType<
|
||||||
|
undefined,
|
||||||
|
IPostAddFolders
|
||||||
|
> = (options?) => {
|
||||||
|
const { mutate } = UseRequestProcessor();
|
||||||
|
|
||||||
|
const addFoldersFn = async (newFolder: IPostAddFolders): Promise<void> => {
|
||||||
|
const payload = {
|
||||||
|
name: newFolder.data.name,
|
||||||
|
description: newFolder.data.description,
|
||||||
|
flows_list: newFolder.data.flows ?? [],
|
||||||
|
components_list: newFolder.data.components ?? [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await api.post(`${getURL("FOLDERS")}/`, payload);
|
||||||
|
return res.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutation = mutate(["usePostFolders"], addFoldersFn, options);
|
||||||
|
|
||||||
|
return mutation;
|
||||||
|
};
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import InputComponent from "../../../components/inputComponent";
|
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormMessage,
|
|
||||||
} from "../../../components/ui/form";
|
|
||||||
import { Input } from "../../../components/ui/input";
|
|
||||||
import { Label } from "../../../components/ui/label";
|
|
||||||
import { Textarea } from "../../../components/ui/textarea";
|
|
||||||
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
|
|
||||||
|
|
||||||
type FolderFormsProps = {
|
|
||||||
control: any;
|
|
||||||
setValue: any;
|
|
||||||
folderToEdit: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FolderForms = ({
|
|
||||||
control,
|
|
||||||
setValue,
|
|
||||||
folderToEdit,
|
|
||||||
}: FolderFormsProps): JSX.Element => {
|
|
||||||
const flows = useFlowsManagerStore((state) => state.flows);
|
|
||||||
const [selectedComponents, setSelectedComponents] = useState<string[]>([]);
|
|
||||||
const [selectedFlows, setSelectedFlows] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const componentsList = flows
|
|
||||||
.filter((flow) => flow.is_component && flow.folder_id !== null)
|
|
||||||
.map((flow) => ({ id: flow.id, name: flow.name }));
|
|
||||||
|
|
||||||
const flowsList = flows
|
|
||||||
.filter((flow) => !flow.is_component && flow.folder_id !== null)
|
|
||||||
.map((flow) => ({ id: flow.id, name: flow.name }));
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValue("components", selectedComponents);
|
|
||||||
setValue("flows", selectedFlows);
|
|
||||||
}, [selectedComponents, selectedFlows]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (folderToEdit) {
|
|
||||||
setValue("name", folderToEdit.name);
|
|
||||||
setValue("description", folderToEdit.description);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setValue("name", "");
|
|
||||||
setValue("description", "");
|
|
||||||
setSelectedComponents([]);
|
|
||||||
setSelectedFlows([]);
|
|
||||||
}, [folderToEdit]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex h-full w-full flex-col gap-4 align-middle">
|
|
||||||
<Label>Folder Name</Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormControl>
|
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={field.onChange}
|
|
||||||
placeholder="Insert a name for the folder..."
|
|
||||||
></Input>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Label>Description (optional) </Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="description"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl>
|
|
||||||
<Textarea
|
|
||||||
value={field.value}
|
|
||||||
onChange={field.onChange}
|
|
||||||
placeholder="Insert a description for the folder..."
|
|
||||||
></Textarea>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Label>Add Flows</Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="flows"
|
|
||||||
render={() => (
|
|
||||||
<FormControl>
|
|
||||||
<InputComponent
|
|
||||||
isObjectOption
|
|
||||||
password={false}
|
|
||||||
objectOptions={flowsList}
|
|
||||||
placeholder="Choose a flow to add..."
|
|
||||||
id="input-flow"
|
|
||||||
setSelectedOptions={(value: any) => setSelectedFlows(value)}
|
|
||||||
selectedOptions={selectedFlows}
|
|
||||||
></InputComponent>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Label>Add Components</Label>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="components"
|
|
||||||
render={() => (
|
|
||||||
<FormControl>
|
|
||||||
<InputComponent
|
|
||||||
isObjectOption
|
|
||||||
password={false}
|
|
||||||
objectOptions={componentsList}
|
|
||||||
placeholder="Choose a component to add..."
|
|
||||||
id="input-component"
|
|
||||||
setSelectedOptions={(value) => setSelectedComponents(value)}
|
|
||||||
selectedOptions={selectedComponents}
|
|
||||||
></InputComponent>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FolderForms;
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
export const FolderFormsSchema = z.object({
|
|
||||||
name: z.string().min(1, {
|
|
||||||
message: "Name must be at least 1 characters.",
|
|
||||||
}),
|
|
||||||
description: z.string().optional(),
|
|
||||||
components: z.array(z.string()),
|
|
||||||
flows: z.array(z.string()),
|
|
||||||
});
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
import { FolderType } from "../../../pages/MainPage/entities";
|
|
||||||
import { addFolder, updateFolder } from "../../../pages/MainPage/services";
|
|
||||||
import useAlertStore from "../../../stores/alertStore";
|
|
||||||
import { useFolderStore } from "../../../stores/foldersStore";
|
|
||||||
|
|
||||||
const useFolderSubmit = (
|
|
||||||
setOpen: (a: boolean) => void,
|
|
||||||
folderToEdit: FolderType | null,
|
|
||||||
) => {
|
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
if (folderToEdit) {
|
|
||||||
updateFolder(data, folderToEdit?.id!).then(
|
|
||||||
() => {
|
|
||||||
setSuccessData({
|
|
||||||
title: "Folder updated successfully.",
|
|
||||||
});
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
if (reason) {
|
|
||||||
setErrorData({
|
|
||||||
title: `Error updating folder.`,
|
|
||||||
});
|
|
||||||
console.error(reason);
|
|
||||||
} else {
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
addFolder(data).then(
|
|
||||||
() => {
|
|
||||||
setSuccessData({
|
|
||||||
title: "Folder created successfully.",
|
|
||||||
});
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
setErrorData({
|
|
||||||
title: `Error creating folder.`,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return { onSubmit, open, setOpen };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useFolderSubmit;
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { z } from "zod";
|
|
||||||
import ForwardedIconComponent from "../../components/genericIconComponent";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
import { Form } from "../../components/ui/form";
|
|
||||||
import { useFolderStore } from "../../stores/foldersStore";
|
|
||||||
import BaseModal from "../baseModal";
|
|
||||||
import FolderForms from "./component";
|
|
||||||
import { FolderFormsSchema } from "./entities";
|
|
||||||
import useFolderSubmit from "./hooks/submit-folder";
|
|
||||||
|
|
||||||
type FoldersModalProps = {
|
|
||||||
open: boolean;
|
|
||||||
setOpen: (open: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function FoldersModal({
|
|
||||||
open,
|
|
||||||
setOpen,
|
|
||||||
}: FoldersModalProps): JSX.Element {
|
|
||||||
const form = useForm<z.infer<typeof FolderFormsSchema>>({
|
|
||||||
resolver: zodResolver(FolderFormsSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
components: [],
|
|
||||||
flows: [],
|
|
||||||
},
|
|
||||||
mode: "all",
|
|
||||||
});
|
|
||||||
|
|
||||||
const folderToEdit = useFolderStore((state) => state.folderToEdit);
|
|
||||||
const { onSubmit: onSubmitFolder } = useFolderSubmit(setOpen, folderToEdit);
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
onSubmitFolder(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<BaseModal size="x-small" open={open} setOpen={setOpen}>
|
|
||||||
<BaseModal.Header
|
|
||||||
description={`${folderToEdit ? "Edit a folder" : "Add a new folder"}`}
|
|
||||||
>
|
|
||||||
<span className="pr-2" data-testid="modal-title">
|
|
||||||
{folderToEdit ? "Edit" : "New"} Folder
|
|
||||||
</span>
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="Plus"
|
|
||||||
className="h-6 w-6 pl-1 text-primary"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</BaseModal.Header>
|
|
||||||
<BaseModal.Content>
|
|
||||||
<div>
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
||||||
<FolderForms
|
|
||||||
folderToEdit={folderToEdit}
|
|
||||||
control={form.control}
|
|
||||||
setValue={form.setValue}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
className="float-right mt-6"
|
|
||||||
type="submit"
|
|
||||||
disabled={!form.formState.isValid}
|
|
||||||
>
|
|
||||||
{folderToEdit ? "Edit" : "Save"} Folder
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</div>
|
|
||||||
</BaseModal.Content>
|
|
||||||
</BaseModal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormMessage,
|
|
||||||
} from "../../../components/ui/form";
|
|
||||||
import { Input } from "../../../components/ui/input";
|
|
||||||
import { Label } from "../../../components/ui/label";
|
|
||||||
import { Textarea } from "../../../components/ui/textarea";
|
|
||||||
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
|
|
||||||
|
|
||||||
type FolderFormsProps = {
|
|
||||||
control: any;
|
|
||||||
setValue: any;
|
|
||||||
folderToEdit: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FolderForms = ({
|
|
||||||
control,
|
|
||||||
setValue,
|
|
||||||
folderToEdit,
|
|
||||||
}: FolderFormsProps): JSX.Element => {
|
|
||||||
const flows = useFlowsManagerStore((state) => state.flows);
|
|
||||||
const [selectedComponents, setSelectedComponents] = useState<string[]>([]);
|
|
||||||
const [selectedFlows, setSelectedFlows] = useState<string[]>([]);
|
|
||||||
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
|
||||||
|
|
||||||
const componentsList = flows
|
|
||||||
.filter((flow) => flow.is_component && flow.folder_id !== null)
|
|
||||||
.map((flow) => ({ id: flow.id, name: flow.name }));
|
|
||||||
|
|
||||||
const flowsList = flows
|
|
||||||
.filter((flow) => !flow.is_component && flow.folder_id !== null)
|
|
||||||
.map((flow) => ({ id: flow.id, name: flow.name }));
|
|
||||||
|
|
||||||
const componentsOnFolder = allFlows
|
|
||||||
.filter((flow) => flow.is_component && flow.folder_id === folderToEdit?.id)
|
|
||||||
.map((flow) => flow.id);
|
|
||||||
|
|
||||||
const flowsOnFolder = allFlows
|
|
||||||
.filter((flow) => !flow.is_component && flow.folder_id === folderToEdit?.id)
|
|
||||||
.map((flow) => flow.id);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValue("components", selectedComponents);
|
|
||||||
setValue("flows", selectedFlows);
|
|
||||||
}, [selectedComponents, selectedFlows]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (folderToEdit) {
|
|
||||||
setValue("name", folderToEdit.name);
|
|
||||||
setValue("description", folderToEdit.description);
|
|
||||||
|
|
||||||
setSelectedComponents(componentsOnFolder);
|
|
||||||
setSelectedFlows(flowsOnFolder);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setValue("name", "");
|
|
||||||
setValue("description", "");
|
|
||||||
setSelectedComponents([]);
|
|
||||||
setSelectedFlows([]);
|
|
||||||
}, [folderToEdit]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex h-full w-full flex-col gap-4 align-middle">
|
|
||||||
<Label>Folder Name</Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormControl>
|
|
||||||
<Input
|
|
||||||
value={field.value}
|
|
||||||
onChange={field.onChange}
|
|
||||||
placeholder="Insert a name for the folder..."
|
|
||||||
></Input>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Label>Description (optional) </Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="description"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl>
|
|
||||||
<Textarea
|
|
||||||
value={field.value}
|
|
||||||
onChange={field.onChange}
|
|
||||||
placeholder="Insert a description for the folder..."
|
|
||||||
></Textarea>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{/*
|
|
||||||
<Label>Add Flows</Label>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="flows"
|
|
||||||
render={() => (
|
|
||||||
<FormControl>
|
|
||||||
<InputComponent
|
|
||||||
isObjectOption
|
|
||||||
password={false}
|
|
||||||
objectOptions={flowsList}
|
|
||||||
placeholder="Choose a flow to add..."
|
|
||||||
id="input-flow"
|
|
||||||
setSelectedOptions={(value: any) => setSelectedFlows(value)}
|
|
||||||
selectedOptions={selectedFlows}
|
|
||||||
></InputComponent>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Label>Add Components</Label>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name="components"
|
|
||||||
render={() => (
|
|
||||||
<FormControl>
|
|
||||||
<InputComponent
|
|
||||||
isObjectOption
|
|
||||||
password={false}
|
|
||||||
objectOptions={componentsList}
|
|
||||||
placeholder="Choose a component to add..."
|
|
||||||
id="input-component"
|
|
||||||
setSelectedOptions={(value) => setSelectedComponents(value)}
|
|
||||||
selectedOptions={selectedComponents}
|
|
||||||
></InputComponent>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/> */}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FolderForms;
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
export const FolderFormsSchema = z.object({
|
|
||||||
name: z.string().min(1, {
|
|
||||||
message: "Name must be at least 1 characters.",
|
|
||||||
}),
|
|
||||||
description: z.string().optional(),
|
|
||||||
components: z.array(z.string()),
|
|
||||||
flows: z.array(z.string()),
|
|
||||||
});
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { FolderType } from "../../../pages/MainPage/entities";
|
|
||||||
import { addFolder, updateFolder } from "../../../pages/MainPage/services";
|
|
||||||
import useAlertStore from "../../../stores/alertStore";
|
|
||||||
import { useFolderStore } from "../../../stores/foldersStore";
|
|
||||||
|
|
||||||
const useFolderSubmit = (
|
|
||||||
setOpen: (a: boolean) => void,
|
|
||||||
folderToEdit: FolderType | null,
|
|
||||||
) => {
|
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
|
||||||
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
if (folderToEdit) {
|
|
||||||
updateFolder(data, folderToEdit?.id!).then(
|
|
||||||
() => {
|
|
||||||
setSuccessData({
|
|
||||||
title: "Folder updated successfully.",
|
|
||||||
});
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
navigate(`all/folder/${folderToEdit.id}`, {
|
|
||||||
state: { folderId: folderToEdit.id },
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//TODO: LOOK THIS ERRO MORE CAREFULLY
|
|
||||||
(reason) => {
|
|
||||||
if (reason) {
|
|
||||||
setErrorData({
|
|
||||||
title: `Error updating folder.`,
|
|
||||||
});
|
|
||||||
console.error(reason);
|
|
||||||
} else {
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
addFolder(data).then(
|
|
||||||
(res) => {
|
|
||||||
setSuccessData({
|
|
||||||
title: "Folder created successfully.",
|
|
||||||
});
|
|
||||||
getFoldersApi(true);
|
|
||||||
setOpen(false);
|
|
||||||
navigate(`all/folder/${res.id}`, { state: { folderId: res.id } });
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
setErrorData({
|
|
||||||
title: `Error creating folder.`,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return { onSubmit, open, setOpen };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useFolderSubmit;
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { z } from "zod";
|
|
||||||
import ForwardedIconComponent from "../../components/genericIconComponent";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
import { Form } from "../../components/ui/form";
|
|
||||||
import { useFolderStore } from "../../stores/foldersStore";
|
|
||||||
import BaseModal from "../baseModal";
|
|
||||||
import FolderForms from "./component";
|
|
||||||
import { FolderFormsSchema } from "./entities";
|
|
||||||
import useFolderSubmit from "./hooks/submit-folder";
|
|
||||||
|
|
||||||
type FoldersModalProps = {
|
|
||||||
open: boolean;
|
|
||||||
setOpen: (open: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function FoldersModal({
|
|
||||||
open,
|
|
||||||
setOpen,
|
|
||||||
}: FoldersModalProps): JSX.Element {
|
|
||||||
const form = useForm<z.infer<typeof FolderFormsSchema>>({
|
|
||||||
resolver: zodResolver(FolderFormsSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
components: [],
|
|
||||||
flows: [],
|
|
||||||
},
|
|
||||||
mode: "all",
|
|
||||||
});
|
|
||||||
|
|
||||||
const folderToEdit = useFolderStore((state) => state.folderToEdit);
|
|
||||||
const { onSubmit: onSubmitFolder } = useFolderSubmit(setOpen, folderToEdit);
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
onSubmitFolder(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<BaseModal size="x-small" open={open} setOpen={setOpen}>
|
|
||||||
<BaseModal.Header
|
|
||||||
description={`${folderToEdit ? "Edit a folder" : "Add a new folder"}`}
|
|
||||||
>
|
|
||||||
<span className="pr-2" data-testid="modal-title">
|
|
||||||
{folderToEdit ? "Edit" : "New"} Folder
|
|
||||||
</span>
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name={folderToEdit ? "Pencil" : "Plus"}
|
|
||||||
className="h-6 w-6 pl-1 text-primary"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</BaseModal.Header>
|
|
||||||
<BaseModal.Content>
|
|
||||||
<div>
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
||||||
<FolderForms
|
|
||||||
folderToEdit={folderToEdit}
|
|
||||||
control={form.control}
|
|
||||||
setValue={form.setValue}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
className="float-right mt-6"
|
|
||||||
type="submit"
|
|
||||||
disabled={!form.formState.isValid}
|
|
||||||
>
|
|
||||||
{folderToEdit ? "Edit" : "Save"} Folder
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</div>
|
|
||||||
</BaseModal.Content>
|
|
||||||
</BaseModal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -2,15 +2,12 @@
|
||||||
import IconComponent from "../../../../components/genericIconComponent";
|
import IconComponent from "../../../../components/genericIconComponent";
|
||||||
import { Button } from "../../../../components/ui/button";
|
import { Button } from "../../../../components/ui/button";
|
||||||
import DeleteConfirmationModal from "../../../../modals/deleteConfirmationModal";
|
import DeleteConfirmationModal from "../../../../modals/deleteConfirmationModal";
|
||||||
import FoldersModal from "../../../../modals/foldersModal";
|
|
||||||
import NewFlowModal from "../../../../modals/newFlowModal";
|
import NewFlowModal from "../../../../modals/newFlowModal";
|
||||||
import { cn } from "../../../../utils/utils";
|
import { cn } from "../../../../utils/utils";
|
||||||
|
|
||||||
interface ModalsProps {
|
interface ModalsProps {
|
||||||
openModal: boolean;
|
openModal: boolean;
|
||||||
setOpenModal: (value: boolean) => void;
|
setOpenModal: (value: boolean) => void;
|
||||||
openFolderModal: boolean;
|
|
||||||
setOpenFolderModal: (value: boolean) => void;
|
|
||||||
openDeleteFolderModal: boolean;
|
openDeleteFolderModal: boolean;
|
||||||
setOpenDeleteFolderModal: (value: boolean) => void;
|
setOpenDeleteFolderModal: (value: boolean) => void;
|
||||||
handleDeleteFolder: () => void;
|
handleDeleteFolder: () => void;
|
||||||
|
|
@ -19,17 +16,12 @@ interface ModalsProps {
|
||||||
const ModalsComponent = ({
|
const ModalsComponent = ({
|
||||||
openModal,
|
openModal,
|
||||||
setOpenModal,
|
setOpenModal,
|
||||||
openFolderModal,
|
|
||||||
setOpenFolderModal,
|
|
||||||
openDeleteFolderModal,
|
openDeleteFolderModal,
|
||||||
setOpenDeleteFolderModal,
|
setOpenDeleteFolderModal,
|
||||||
handleDeleteFolder,
|
handleDeleteFolder,
|
||||||
}: ModalsProps) => (
|
}: ModalsProps) => (
|
||||||
<>
|
<>
|
||||||
{openModal && <NewFlowModal open={openModal} setOpen={setOpenModal} />}
|
{openModal && <NewFlowModal open={openModal} setOpen={setOpenModal} />}
|
||||||
{openFolderModal && (
|
|
||||||
<FoldersModal open={openFolderModal} setOpen={setOpenFolderModal} />
|
|
||||||
)}
|
|
||||||
{openDeleteFolderModal && (
|
{openDeleteFolderModal && (
|
||||||
<DeleteConfirmationModal
|
<DeleteConfirmationModal
|
||||||
open={openDeleteFolderModal}
|
open={openDeleteFolderModal}
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,6 @@ export default function HomePage(): JSX.Element {
|
||||||
<ModalsComponent
|
<ModalsComponent
|
||||||
openModal={openModal}
|
openModal={openModal}
|
||||||
setOpenModal={setOpenModal}
|
setOpenModal={setOpenModal}
|
||||||
openFolderModal={openFolderModal}
|
|
||||||
setOpenFolderModal={setOpenFolderModal}
|
|
||||||
openDeleteFolderModal={openDeleteFolderModal}
|
openDeleteFolderModal={openDeleteFolderModal}
|
||||||
setOpenDeleteFolderModal={setOpenDeleteFolderModal}
|
setOpenDeleteFolderModal={setOpenDeleteFolderModal}
|
||||||
handleDeleteFolder={handleDeleteFolder}
|
handleDeleteFolder={handleDeleteFolder}
|
||||||
|
|
|
||||||
|
|
@ -12,46 +12,6 @@ export async function getFolders(): Promise<FolderType[]> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addFolder(data: AddFolderType): Promise<FolderType> {
|
|
||||||
const body = {
|
|
||||||
name: data.name,
|
|
||||||
description: data.description,
|
|
||||||
flows_list: data.flows ?? [],
|
|
||||||
components_list: data.components ?? [],
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await api.post(`${BASE_URL_API}folders/`, body);
|
|
||||||
return response?.data;
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateFolder(
|
|
||||||
body: FolderType,
|
|
||||||
folderId: string,
|
|
||||||
): Promise<FolderType> {
|
|
||||||
try {
|
|
||||||
const response = await api.patch(
|
|
||||||
`${BASE_URL_API}folders/${folderId}`,
|
|
||||||
body,
|
|
||||||
);
|
|
||||||
return response?.data;
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteFolder(folderId: string) {
|
|
||||||
try {
|
|
||||||
const response = await api.delete(`${BASE_URL_API}folders/${folderId}`);
|
|
||||||
return response?.data;
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getFolderById(folderId: string): Promise<FolderType> {
|
export async function getFolderById(folderId: string): Promise<FolderType> {
|
||||||
try {
|
try {
|
||||||
const response = await api.get(`${BASE_URL_API}folders/${folderId}`);
|
const response = await api.get(`${BASE_URL_API}folders/${folderId}`);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { DEFAULT_FOLDER, STARTER_FOLDER_NAME } from "../constants/constants";
|
import { DEFAULT_FOLDER, STARTER_FOLDER_NAME } from "../constants/constants";
|
||||||
import {
|
import { getFolderById, getFolders } from "../pages/MainPage/services";
|
||||||
getFolderById,
|
|
||||||
getFolders,
|
|
||||||
uploadFlowsFromFolders,
|
|
||||||
} from "../pages/MainPage/services";
|
|
||||||
import { FoldersStoreType } from "../types/zustand/folders";
|
import { FoldersStoreType } from "../types/zustand/folders";
|
||||||
import useFlowsManagerStore from "./flowsManagerStore";
|
import useFlowsManagerStore from "./flowsManagerStore";
|
||||||
import { useTypesStore } from "./typesStore";
|
import { useTypesStore } from "./typesStore";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue