diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/add-folder-button.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/add-folder-button.tsx new file mode 100644 index 000000000..ac4de9567 --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/add-folder-button.tsx @@ -0,0 +1,27 @@ +import IconComponent from "@/components/common/genericIconComponent"; +import ShadTooltip from "@/components/common/shadTooltipComponent"; +import { Button } from "@/components/ui/button"; + +export const AddFolderButton = ({ + onClick, + disabled, + loading, +}: { + onClick: () => void; + disabled: boolean; + loading: boolean; +}) => ( + + + +); diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/folder-select-item.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/folder-select-item.tsx new file mode 100644 index 000000000..33afc8211 --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/folder-select-item.tsx @@ -0,0 +1,14 @@ +import IconComponent from "@/components/common/genericIconComponent"; +import { cn } from "@/utils/utils"; + +export const FolderSelectItem = ({ name, iconName }) => ( +
+ + {name} +
+); diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/header-buttons.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/header-buttons.tsx new file mode 100644 index 000000000..56c9b23bd --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/header-buttons.tsx @@ -0,0 +1,35 @@ +import IconComponent from "@/components/common/genericIconComponent"; +import { SidebarTrigger } from "@/components/ui/sidebar"; +import { AddFolderButton } from "./add-folder-button"; +import { UploadFolderButton } from "./upload-folder-button"; + +export const HeaderButtons = ({ + handleUploadFlowsToFolder, + isUpdatingFolder, + isPending, + addNewFolder, +}: { + handleUploadFlowsToFolder: () => void; + isUpdatingFolder: boolean; + isPending: boolean; + addNewFolder: () => void; +}) => ( +
+ + + + +
Folders
+
+ + +
+
+); diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/input-edit-folder-name.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/input-edit-folder-name.tsx new file mode 100644 index 000000000..86ed361c4 --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/input-edit-folder-name.tsx @@ -0,0 +1,67 @@ +import { Input } from "@/components/ui/input"; +import { FolderType } from "@/pages/MainPage/entities"; + +export const InputEditFolderName = ({ + handleEditFolderName, + item, + refInput, + handleKeyDownFn, + handleKeyDown, + handleEditNameFolder, + editFolderName, + foldersNames, +}: { + handleEditFolderName: ( + e: React.ChangeEvent, + folderName: string, + ) => void; + item: FolderType; + refInput: React.RefObject; + handleKeyDownFn: ( + e: React.KeyboardEvent, + folder: FolderType, + ) => void; + handleKeyDown: ( + e: React.KeyboardEvent, + key: string, + folderName: string, + ) => void; + handleEditNameFolder: (item: FolderType) => void; + editFolderName: { name: string; edit: boolean }; + foldersNames: Record; +}) => { + return ( + <> + { + handleEditFolderName(e, item.name); + }} + maxLength={38} + ref={refInput} + onKeyDown={(e) => { + handleKeyDownFn(e, item); + handleKeyDown(e, e.key, ""); + }} + autoFocus={true} + onBlur={(e) => { + // fixes autofocus problem where cursor isn't present + if (e.relatedTarget?.id === `options-trigger-${item.name}`) { + refInput.current?.focus(); + return; + } + + if (refInput.current?.value !== item.name) { + handleEditNameFolder(item); + } else { + editFolderName.edit = false; + } + refInput.current?.blur(); + }} + value={foldersNames[item.name]} + id={`input-folder-${item.name}`} + data-testid={`input-folder`} + /> + + ); +}; diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/select-options.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/select-options.tsx new file mode 100644 index 000000000..676576655 --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/select-options.tsx @@ -0,0 +1,80 @@ +import IconComponent from "@/components/common/genericIconComponent"; +import ShadTooltip from "@/components/common/shadTooltipComponent"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, +} from "@/components/ui/select-custom"; +import { FolderType } from "@/pages/MainPage/entities"; +import { cn } from "@/utils/utils"; +import { handleSelectChange } from "../helpers/handle-select-change"; +import { FolderSelectItem } from "./folder-select-item"; + +export const SelectOptions = ({ + item, + index, + handleDeleteFolder, + handleDownloadFolder, + handleSelectFolderToRename, + checkPathName, +}: { + item: FolderType; + index: number; + handleDeleteFolder: ((folder: FolderType) => void) | undefined; + handleDownloadFolder: (folderId: string) => void; + handleSelectFolderToRename: (folder: FolderType) => void; + checkPathName: (folderId: string) => boolean; +}) => { + return ( + <> + + + ); +}; diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/upload-folder-button.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/upload-folder-button.tsx new file mode 100644 index 000000000..61a1a354e --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/components/upload-folder-button.tsx @@ -0,0 +1,18 @@ +import IconComponent from "@/components/common/genericIconComponent"; +import ShadTooltip from "@/components/common/shadTooltipComponent"; +import { Button } from "@/components/ui/button"; + +export const UploadFolderButton = ({ onClick, disabled }) => ( + + + +); diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/helpers/handle-select-change.ts b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/helpers/handle-select-change.ts new file mode 100644 index 000000000..cbc06e781 --- /dev/null +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/helpers/handle-select-change.ts @@ -0,0 +1,21 @@ +import { FolderType } from "@/pages/MainPage/entities"; + +export const handleSelectChange = ( + option: string, + folder: FolderType, + handleDeleteFolder: ((folder: FolderType) => void) | undefined, + handleDownloadFolder: (folderId: string) => void, + handleSelectFolderToRename: (folder: FolderType) => void, +) => { + switch (option) { + case "delete": + handleDeleteFolder!(folder); + break; + case "download": + handleDownloadFolder(folder.id!); + break; + case "rename": + handleSelectFolderToRename(folder); + break; + } +}; diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx index 0fc2a2466..a863e70e2 100644 --- a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx @@ -1,10 +1,3 @@ -import ShadTooltip from "@/components/common/shadTooltipComponent"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, -} from "@/components/ui/select-custom"; import { Sidebar, SidebarContent, @@ -14,7 +7,6 @@ import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, - SidebarTrigger, } from "@/components/ui/sidebar"; import { usePatchFolders, @@ -37,11 +29,11 @@ import useFlowsManagerStore from "../../../../../stores/flowsManagerStore"; import { useFolderStore } from "../../../../../stores/foldersStore"; import { handleKeyDown } from "../../../../../utils/reactflowUtils"; import { cn } from "../../../../../utils/utils"; -import IconComponent from "../../../../common/genericIconComponent"; -import { Button } from "../../../../ui/button"; -import { Input } from "../../../../ui/input"; import useFileDrop from "../../hooks/use-on-file-drop"; import { SidebarFolderSkeleton } from "../sidebarFolderSkeleton"; +import { HeaderButtons } from "./components/header-buttons"; +import { InputEditFolderName } from "./components/input-edit-folder-name"; +import { SelectOptions } from "./components/select-options"; type SideBarFoldersButtonsComponentProps = { handleChangeFolder?: (id: string) => void; @@ -54,37 +46,68 @@ const SideBarFoldersButtonsComponent = ({ const location = useLocation(); const pathname = location.pathname; const folders = useFolderStore((state) => state.folders); - - const isFetchingFolders = !!useIsFetching({ - queryKey: ["useGetFolders"], - exact: false, - }); const loading = !folders; const refInput = useRef(null); - const [foldersNames, setFoldersNames] = useState({}); - const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); - const [editFolders, setEditFolderName] = useState( - folders.map((obj) => ({ name: obj.name, edit: false })) ?? [], - ); + const currentFolder = pathname.split("/"); const urlWithoutPath = pathname.split("/").length < (ENABLE_CUSTOM_PARAM ? 5 : 4); - const myCollectionId = useFolderStore((state) => state.myCollectionId); + const checkPathName = (itemId: string) => { if (urlWithoutPath && itemId === myCollectionId) { return true; } return currentFolder.includes(itemId); }; - const folderId = useParams().folderId ?? myCollectionId ?? ""; + const setErrorData = useAlertStore((state) => state.setErrorData); const setSuccessData = useAlertStore((state) => state.setSuccessData); - const uploadFlow = useUploadFlow(); + const isMobile = useIsMobile({ maxWidth: 1024 }); + const folderIdDragging = useFolderStore((state) => state.folderIdDragging); + const myCollectionId = useFolderStore((state) => state.myCollectionId); + const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); + + const folderId = useParams().folderId ?? myCollectionId ?? ""; const { dragOver, dragEnter, dragLeave, onDrop } = useFileDrop(folderId); + const uploadFlow = useUploadFlow(); + const [foldersNames, setFoldersNames] = useState({}); + const [editFolders, setEditFolderName] = useState( + folders.map((obj) => ({ name: obj.name, edit: false })) ?? [], + ); + const isFetchingFolders = !!useIsFetching({ + queryKey: ["useGetFolders"], + exact: false, + }); + + const { mutate: mutateDownloadFolder } = useGetDownloadFolders({}); + const { mutate: mutateAddFolder, isPending } = usePostFolders(); + const { mutate: mutateUpdateFolder } = usePatchFolders(); const { mutate } = usePostUploadFolders(); + const checkHoveringFolder = (folderId: string) => { + if (folderId === folderIdDragging) { + return "bg-accent text-accent-foreground"; + } + }; + + const isFetchingFolder = !!useIsFetching({ + queryKey: ["useGetFolder"], + exact: false, + }); + + const isDeletingFolder = !!useIsMutating({ + mutationKey: ["useDeleteFolders"], + }); + + const isUpdatingFolder = + isFetchingFolders || + isFetchingFolder || + isPending || + loading || + isDeletingFolder; + const handleUploadFlowsToFolder = () => { createFileUpload().then((files: File[]) => { if (files?.length === 0) { @@ -125,8 +148,6 @@ const SideBarFoldersButtonsComponent = ({ }); }; - const { mutate: mutateDownloadFolder } = useGetDownloadFolders({}); - const handleDownloadFolder = (id: string) => { mutateDownloadFolder( { @@ -166,9 +187,6 @@ const SideBarFoldersButtonsComponent = ({ ); }; - const { mutate: mutateAddFolder, isPending } = usePostFolders(); - const { mutate: mutateUpdateFolder } = usePatchFolders(); - function addNewFolder() { mutateAddFolder( { @@ -257,86 +275,6 @@ const SideBarFoldersButtonsComponent = ({ } }; - const isFetchingFolder = !!useIsFetching({ - queryKey: ["useGetFolder"], - exact: false, - }); - - const isDeletingFolder = !!useIsMutating({ - mutationKey: ["useDeleteFolders"], - }); - - const isUpdatingFolder = - isFetchingFolders || - isFetchingFolder || - isPending || - loading || - isDeletingFolder; - - const HeaderButtons = () => ( -
- - - - -
Folders
-
- - -
-
- ); - - const AddFolderButton = ({ onClick, disabled, loading }) => ( - - - - ); - - const UploadFolderButton = ({ onClick, disabled }) => ( - - - - ); - - const FolderSelectItem = ({ name, iconName }) => ( -
- - {name} -
- ); - const handleDoubleClick = (event, item) => { if (item.name === "My Projects") { return; @@ -395,29 +333,18 @@ const SideBarFoldersButtonsComponent = ({ } }; - const handleSelectChange = (option, folder) => { - switch (option) { - case "delete": - handleDeleteFolder!(folder); - break; - case "download": - handleDownloadFolder(folder.id!); - break; - case "rename": - handleSelectFolderToRename(folder); - break; - } - }; - - const isMobile = useIsMobile({ maxWidth: 1024 }); - return ( - + @@ -440,7 +367,10 @@ const SideBarFoldersButtonsComponent = ({ data-testid={`sidebar-nav-${item.name}`} isActive={checkPathName(item.id!)} onClick={() => handleChangeFolder!(item.id!)} - className="group/menu-button" + className={cn( + "group/menu-button", + checkHoveringFolder(item.id!), + )} >
{ @@ -450,38 +380,15 @@ const SideBarFoldersButtonsComponent = ({ >
{editFolderName?.edit && !isUpdatingFolder ? ( - { - handleEditFolderName(e, item.name); - }} - maxLength={38} - ref={refInput} - onKeyDown={(e) => { - handleKeyDownFn(e, item); - handleKeyDown(e, e.key, ""); - }} - autoFocus={true} - onBlur={(e) => { - // fixes autofocus problem where cursor isn't present - if ( - e.relatedTarget?.id === - `options-trigger-${item.name}` - ) { - refInput.current?.focus(); - return; - } - - if (refInput.current?.value !== item.name) { - handleEditNameFolder(item); - } else { - editFolderName.edit = false; - } - refInput.current?.blur(); - }} - value={foldersNames[item.name]} - id={`input-folder-${item.name}`} - data-testid={`input-folder`} + ) : ( @@ -489,69 +396,16 @@ const SideBarFoldersButtonsComponent = ({ )}
- + checkPathName={checkPathName} + />