From 5f468cd95dbd0395151f4ce302dfc8eac0ffa2a1 Mon Sep 17 00:00:00 2001 From: Isaac Wise Date: Sun, 11 Feb 2024 01:06:46 -0600 Subject: [PATCH] Add bulk actions to pinned and all links pages --- pages/collections/[id].tsx | 1 - pages/links/index.tsx | 118 +++++++++++++++++++++++++++++++++++- pages/links/pinned.tsx | 119 ++++++++++++++++++++++++++++++++++++- 3 files changed, 233 insertions(+), 5 deletions(-) diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index 1b626e6..fb00433 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -374,7 +374,6 @@ export default function Index() { )} - {links.some((e) => e.collectionId === Number(router.query.id)) ? ( ( localStorage.getItem("viewMode") || ViewMode.Card ); const [sortBy, setSortBy] = useState(Sort.DateNewestFirst); + + const [bulkDeleteLinksModal, setBulkDeleteLinksModal] = useState(false); + const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false); + const [editMode, setEditMode] = useState(false); + const collectivePermissions = useCollectivePermissions(selectedLinks.map((link) => link.collectionId as number)); + useLinks({ sort: sortBy }); + const handleSelectAll = () => { + if (selectedLinks.length === links.length) { + setSelectedLinks([]); + } else { + setSelectedLinks(links.map((link) => link)); + } + }; + + const bulkDeleteLinks = async () => { + const load = toast.loading( + `Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" + }...` + ); + + const response = await deleteLinksById( + selectedLinks.map((link) => link.id as number) + ); + + toast.dismiss(load); + + response.ok && + toast.success( + `Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" + }!` + ); + }; + const linkView = { [ViewMode.Card]: CardView, // [ViewMode.Grid]: GridView, @@ -41,17 +78,94 @@ export default function Links() { />
+
{ + setEditMode(!editMode) + setSelectedLinks([]) + }} + className={`btn btn-square btn-sm btn-ghost ${editMode + ? "bg-primary/20 hover:bg-primary/20" + : "hover:bg-neutral/20" + }`} + > + +
+ {editMode && ( +
+ {links.length > 0 && ( +
+ handleSelectAll()} + checked={ + selectedLinks.length === links.length && links.length > 0 + } + /> + {selectedLinks.length > 0 ? ( + + {selectedLinks.length}{" "} + {selectedLinks.length === 1 ? "link" : "links"} selected + + ) : ( + Nothing selected + )} +
+ )} +
+ {selectedLinks.length > 0 && + (collectivePermissions === true || collectivePermissions?.canUpdate) && ( + + )} + {selectedLinks.length > 0 && + (collectivePermissions === true || collectivePermissions?.canDelete) && ( + + )} +
+
+ )} + {links[0] ? ( - + ) : ( )} + {bulkDeleteLinksModal && ( + { + setBulkDeleteLinksModal(false); + setEditMode(false); + }} + /> + )} + {bulkEditLinksModal && ( + { + setBulkEditLinksModal(false); + setEditMode(false); + }} /> + )} ); } diff --git a/pages/links/pinned.tsx b/pages/links/pinned.tsx index c6b5ee0..a9881b1 100644 --- a/pages/links/pinned.tsx +++ b/pages/links/pinned.tsx @@ -8,10 +8,14 @@ import { Sort, ViewMode } from "@/types/global"; import ViewDropdown from "@/components/ViewDropdown"; import CardView from "@/components/LinkViews/Layouts/CardView"; import ListView from "@/components/LinkViews/Layouts/ListView"; +import BulkDeleteLinksModal from "@/components/ModalContent/BulkDeleteLinksModal"; +import BulkEditLinksModal from "@/components/ModalContent/BulkEditLinksModal"; +import useCollectivePermissions from "@/hooks/useCollectivePermissions"; +import toast from "react-hot-toast"; // import GridView from "@/components/LinkViews/Layouts/GridView"; export default function PinnedLinks() { - const { links } = useLinkStore(); + const { links, selectedLinks, deleteLinksById, setSelectedLinks } = useLinkStore(); const [viewMode, setViewMode] = useState( localStorage.getItem("viewMode") || ViewMode.Card @@ -20,6 +24,40 @@ export default function PinnedLinks() { useLinks({ sort: sortBy, pinnedOnly: true }); + const [bulkDeleteLinksModal, setBulkDeleteLinksModal] = useState(false); + const [bulkEditLinksModal, setBulkEditLinksModal] = useState(false); + const [editMode, setEditMode] = useState(false); + const collectivePermissions = useCollectivePermissions(selectedLinks.map((link) => link.collectionId as number)); + + useLinks({ sort: sortBy }); + + const handleSelectAll = () => { + if (selectedLinks.length === links.length) { + setSelectedLinks([]); + } else { + setSelectedLinks(links.map((link) => link)); + } + }; + + const bulkDeleteLinks = async () => { + const load = toast.loading( + `Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" + }...` + ); + + const response = await deleteLinksById( + selectedLinks.map((link) => link.id as number) + ); + + toast.dismiss(load); + + response.ok && + toast.success( + `Deleted ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : "" + }!` + ); + }; + const linkView = { [ViewMode.Card]: CardView, // [ViewMode.Grid]: GridView, @@ -39,13 +77,76 @@ export default function PinnedLinks() { description={"Pinned Links from your Collections"} />
+
{ + setEditMode(!editMode) + setSelectedLinks([]) + }} + className={`btn btn-square btn-sm btn-ghost ${editMode + ? "bg-primary/20 hover:bg-primary/20" + : "hover:bg-neutral/20" + }`} + > + +
+ {editMode && ( +
+ {links.length > 0 && ( +
+ handleSelectAll()} + checked={ + selectedLinks.length === links.length && links.length > 0 + } + /> + {selectedLinks.length > 0 ? ( + + {selectedLinks.length}{" "} + {selectedLinks.length === 1 ? "link" : "links"} selected + + ) : ( + Nothing selected + )} +
+ )} +
+ {selectedLinks.length > 0 && + (collectivePermissions === true || collectivePermissions?.canUpdate) && ( + + )} + {selectedLinks.length > 0 && + (collectivePermissions === true || collectivePermissions?.canDelete) && ( + + )} +
+
+ )} + {links.some((e) => e.pinnedBy && e.pinnedBy[0]) ? ( - + ) : (
)}
+ {bulkDeleteLinksModal && ( + { + setBulkDeleteLinksModal(false); + setEditMode(false); + }} + /> + )} + {bulkEditLinksModal && ( + { + setBulkEditLinksModal(false); + setEditMode(false); + }} /> + )} ); }