aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-09-27 09:17:51 +0000
committerMohamedBassem <me@mbassem.com>2024-09-27 09:17:51 +0000
commitbadf697d0b83ef4d093e781f04ed73d3901e6a9f (patch)
treec9dc70fe8c751695df3c50bc82ccf142bf237a6b
parentee0aad531b0106d25fa91a044d00cb95f79e3b5b (diff)
downloadkarakeep-badf697d0b83ef4d093e781f04ed73d3901e6a9f.tar.zst
feature(web): Add a select all button to bulk actions
-rw-r--r--apps/web/components/dashboard/BulkBookmarksAction.tsx24
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx11
-rw-r--r--apps/web/lib/bulkActions.ts23
3 files changed, 52 insertions, 6 deletions
diff --git a/apps/web/components/dashboard/BulkBookmarksAction.tsx b/apps/web/components/dashboard/BulkBookmarksAction.tsx
index 9e831e80..a3f0ea55 100644
--- a/apps/web/components/dashboard/BulkBookmarksAction.tsx
+++ b/apps/web/components/dashboard/BulkBookmarksAction.tsx
@@ -25,6 +25,13 @@ export default function BulkBookmarksAction() {
const setIsBulkEditEnabled = useBulkActionsStore(
(state) => state.setIsBulkEditEnabled,
);
+ const selectAllBookmarks = useBulkActionsStore((state) => state.selectAll);
+ const unSelectAllBookmarks = useBulkActionsStore(
+ (state) => state.unSelectAll,
+ );
+ const isEverythingSelected = useBulkActionsStore(
+ (state) => state.isEverythingSelected,
+ );
const { toast } = useToast();
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [manageListsModal, setManageListsModalOpen] = useState(false);
@@ -169,6 +176,18 @@ export default function BulkBookmarksAction() {
hidden: !isBulkEditEnabled,
},
{
+ name: isEverythingSelected() ? "Unselect All" : "Select All",
+ icon: (
+ <p className="flex items-center gap-2">
+ ( <CheckCheck size={18} /> {selectedBookmarks.length} )
+ </p>
+ ),
+ action: () =>
+ isEverythingSelected() ? unSelectAllBookmarks() : selectAllBookmarks(),
+ alwaysEnable: true,
+ hidden: !isBulkEditEnabled,
+ },
+ {
name: "Close bulk edit",
icon: <X size={18} />,
action: () => setIsBulkEditEnabled(false),
@@ -213,11 +232,6 @@ export default function BulkBookmarksAction() {
setOpen={setBulkTagModalOpen}
/>
<div className="flex items-center">
- {isBulkEditEnabled && (
- <p className="flex items-center gap-2">
- ( <CheckCheck size={18} /> {selectedBookmarks.length} )
- </p>
- )}
{actionList.map(
({ name, icon: Icon, action, isPending, hidden, alwaysEnable }) => (
<ActionButtonWithTooltip
diff --git a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
index 16c25850..89791846 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
@@ -1,5 +1,6 @@
-import { useMemo } from "react";
+import { useEffect, useMemo } from "react";
import { ActionButton } from "@/components/ui/action-button";
+import useBulkActionsStore from "@/lib/bulkActions";
import {
bookmarkLayoutSwitch,
useBookmarkLayout,
@@ -48,8 +49,16 @@ export default function BookmarksGrid({
fetchNextPage?: () => void;
}) {
const layout = useBookmarkLayout();
+ const bulkActionsStore = useBulkActionsStore();
const breakpointConfig = useMemo(() => getBreakpointConfig(), []);
+ useEffect(() => {
+ bulkActionsStore.setVisibleBookmarks(bookmarks);
+ return () => {
+ bulkActionsStore.setVisibleBookmarks([]);
+ };
+ }, [bookmarks]);
+
if (bookmarks.length == 0 && !showEditorCard) {
return <p>No bookmarks</p>;
}
diff --git a/apps/web/lib/bulkActions.ts b/apps/web/lib/bulkActions.ts
index 1e9dbbd7..a2ee6a29 100644
--- a/apps/web/lib/bulkActions.ts
+++ b/apps/web/lib/bulkActions.ts
@@ -5,13 +5,19 @@ import type { ZBookmark } from "@hoarder/shared/types/bookmarks";
interface BookmarkState {
selectedBookmarks: ZBookmark[];
+ visibleBookmarks: ZBookmark[];
isBulkEditEnabled: boolean;
setIsBulkEditEnabled: (isEnabled: boolean) => void;
toggleBookmark: (bookmark: ZBookmark) => void;
+ setVisibleBookmarks: (visibleBookmarks: ZBookmark[]) => void;
+ selectAll: () => void;
+ unSelectAll: () => void;
+ isEverythingSelected: () => boolean;
}
const useBulkActionsStore = create<BookmarkState>((set, get) => ({
selectedBookmarks: [],
+ visibleBookmarks: [],
isBulkEditEnabled: false,
toggleBookmark: (bookmark: ZBookmark) => {
@@ -30,10 +36,27 @@ const useBulkActionsStore = create<BookmarkState>((set, get) => ({
}
},
+ selectAll: () => {
+ set({ selectedBookmarks: get().visibleBookmarks });
+ },
+ unSelectAll: () => {
+ set({ selectedBookmarks: [] });
+ },
+
+ isEverythingSelected: () => {
+ return get().selectedBookmarks.length === get().visibleBookmarks.length;
+ },
+
setIsBulkEditEnabled: (isEnabled) => {
set({ isBulkEditEnabled: isEnabled });
set({ selectedBookmarks: [] });
},
+
+ setVisibleBookmarks: (visibleBookmarks: ZBookmark[]) => {
+ set({
+ visibleBookmarks,
+ });
+ },
}));
export default useBulkActionsStore;