From ac91d0df9a769ba692b377d4c78019feb73eda57 Mon Sep 17 00:00:00 2001 From: Sean Hatfield <seanhatfield5@gmail.com> Date: Mon, 23 Sep 2024 12:19:55 -0700 Subject: [PATCH] Add select/unselect all context menu to directory component (#2337) add select/unselect all context menu to directory component --- .../Documents/Directory/ContextMenu/index.jsx | 79 +++++++++++++++++++ .../Documents/Directory/index.jsx | 25 +++++- 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/Modals/ManageWorkspace/Documents/Directory/ContextMenu/index.jsx diff --git a/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/ContextMenu/index.jsx b/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/ContextMenu/index.jsx new file mode 100644 index 000000000..5515d8b46 --- /dev/null +++ b/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/ContextMenu/index.jsx @@ -0,0 +1,79 @@ +import { useRef, useEffect } from "react"; + +export default function ContextMenu({ + contextMenu, + closeContextMenu, + files, + selectedItems, + setSelectedItems, +}) { + const contextMenuRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event) => { + if ( + contextMenuRef.current && + !contextMenuRef.current.contains(event.target) + ) { + closeContextMenu(); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [closeContextMenu]); + + const isAllSelected = () => { + const allItems = files.items.flatMap((folder) => [ + folder.name, + ...folder.items.map((file) => file.id), + ]); + return allItems.every((item) => selectedItems[item]); + }; + + const toggleSelectAll = () => { + if (isAllSelected()) { + setSelectedItems({}); + } else { + const newSelectedItems = {}; + files.items.forEach((folder) => { + newSelectedItems[folder.name] = true; + folder.items.forEach((file) => { + newSelectedItems[file.id] = true; + }); + }); + setSelectedItems(newSelectedItems); + } + closeContextMenu(); + }; + + if (!contextMenu.visible) return null; + + return ( + <div + ref={contextMenuRef} + style={{ + position: "fixed", + top: `${contextMenu.y}px`, + left: `${contextMenu.x}px`, + zIndex: 1000, + }} + className="bg-zinc-800 border border-zinc-700 rounded-md shadow-lg" + > + <button + onClick={toggleSelectAll} + className="block w-full text-left px-4 py-2 text-sm text-white hover:bg-zinc-700" + > + {isAllSelected() ? "Unselect All" : "Select All"} + </button> + <button + onClick={closeContextMenu} + className="block w-full text-left px-4 py-2 text-sm text-white hover:bg-zinc-700" + > + Cancel + </button> + </div> + ); +} diff --git a/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx b/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx index 8ad2ed6a5..d1c5eba78 100644 --- a/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx +++ b/frontend/src/components/Modals/ManageWorkspace/Documents/Directory/index.jsx @@ -12,6 +12,7 @@ import { useModal } from "@/hooks/useModal"; import NewFolderModal from "./NewFolderModal"; import debounce from "lodash.debounce"; import { filterFileSearchResults } from "./utils"; +import ContextMenu from "./ContextMenu"; function Directory({ files, @@ -35,6 +36,11 @@ function Directory({ openModal: openFolderModal, closeModal: closeFolderModal, } = useModal(); + const [contextMenu, setContextMenu] = useState({ + visible: false, + x: 0, + y: 0, + }); useEffect(() => { setAmountSelected(Object.keys(selectedItems).length); @@ -171,8 +177,18 @@ function Directory({ }, 500); const filteredFiles = filterFileSearchResults(files, searchTerm); + + const handleContextMenu = (event) => { + event.preventDefault(); + setContextMenu({ visible: true, x: event.clientX, y: event.clientY }); + }; + + const closeContextMenu = () => { + setContextMenu({ visible: false, x: 0, y: 0 }); + }; + return ( - <div className="px-8 pb-8"> + <div className="px-8 pb-8" onContextMenu={handleContextMenu}> <div className="flex flex-col gap-y-6"> <div className="flex items-center justify-between w-[560px] px-5 relative"> <h3 className="text-white text-base font-bold">My Documents</h3> @@ -298,6 +314,13 @@ function Directory({ /> </div> )} + <ContextMenu + contextMenu={contextMenu} + closeContextMenu={closeContextMenu} + files={files} + selectedItems={selectedItems} + setSelectedItems={setSelectedItems} + /> </div> ); } -- GitLab