Parcourir la source

fix: library multiselect not accounting for published state (#5132)

David Luzar il y a 3 ans
Parent
commit
65c32b3319
2 fichiers modifiés avec 65 ajouts et 61 suppressions
  1. 1 46
      src/components/LibraryMenu.tsx
  2. 64 15
      src/components/LibraryMenuItems.tsx

+ 1 - 46
src/components/LibraryMenu.tsx

@@ -25,7 +25,6 @@ import "./LibraryMenu.scss";
 import LibraryMenuItems from "./LibraryMenuItems";
 import { EVENT } from "../constants";
 import { KEYS } from "../keys";
-import { arrayToMap } from "../utils";
 import { trackEvent } from "../analytics";
 import { useAtom } from "jotai";
 import { jotaiScope } from "../jotai";
@@ -225,10 +224,6 @@ export const LibraryMenu = ({
     [setShowPublishLibraryDialog, setPublishLibSuccess, selectedItems, library],
   );
 
-  const [lastSelectedItem, setLastSelectedItem] = useState<
-    LibraryItem["id"] | null
-  >(null);
-
   if (
     libraryItemsData.status === "loading" &&
     !libraryItemsData.isInitialized
@@ -284,47 +279,7 @@ export const LibraryMenu = ({
         files={files}
         id={id}
         selectedItems={selectedItems}
-        onToggle={(id, event) => {
-          const shouldSelect = !selectedItems.includes(id);
-
-          if (shouldSelect) {
-            if (event.shiftKey && lastSelectedItem) {
-              const rangeStart = libraryItemsData.libraryItems.findIndex(
-                (item) => item.id === lastSelectedItem,
-              );
-              const rangeEnd = libraryItemsData.libraryItems.findIndex(
-                (item) => item.id === id,
-              );
-
-              if (rangeStart === -1 || rangeEnd === -1) {
-                setSelectedItems([...selectedItems, id]);
-                return;
-              }
-
-              const selectedItemsMap = arrayToMap(selectedItems);
-              const nextSelectedIds = libraryItemsData.libraryItems.reduce(
-                (acc: LibraryItem["id"][], item, idx) => {
-                  if (
-                    (idx >= rangeStart && idx <= rangeEnd) ||
-                    selectedItemsMap.has(item.id)
-                  ) {
-                    acc.push(item.id);
-                  }
-                  return acc;
-                },
-                [],
-              );
-
-              setSelectedItems(nextSelectedIds);
-            } else {
-              setSelectedItems([...selectedItems, id]);
-            }
-            setLastSelectedItem(id);
-          } else {
-            setLastSelectedItem(null);
-            setSelectedItems(selectedItems.filter((_id) => _id !== id));
-          }
-        }}
+        onSelectItems={(ids) => setSelectedItems(ids)}
         onPublish={() => setShowPublishLibraryDialog(true)}
         resetLibrary={resetLibrary}
       />

+ 64 - 15
src/components/LibraryMenuItems.tsx

@@ -1,5 +1,5 @@
 import { chunk } from "lodash";
-import { useCallback, useState } from "react";
+import React, { useCallback, useState } from "react";
 import { importLibraryFromJSON, saveLibraryAsJSON } from "../data/json";
 import Library from "../data/library";
 import { ExcalidrawElement, NonDeleted } from "../element/types";
@@ -11,7 +11,7 @@ import {
   LibraryItem,
   LibraryItems,
 } from "../types";
-import { muteFSAbortError } from "../utils";
+import { arrayToMap, muteFSAbortError } from "../utils";
 import { useDeviceType } from "./App";
 import ConfirmDialog from "./ConfirmDialog";
 import { exportToFileIcon, load, publishIcon, trash } from "./icons";
@@ -38,7 +38,7 @@ const LibraryMenuItems = ({
   files,
   id,
   selectedItems,
-  onToggle,
+  onSelectItems,
   onPublish,
   resetLibrary,
 }: {
@@ -55,7 +55,7 @@ const LibraryMenuItems = ({
   library: Library;
   id: string;
   selectedItems: LibraryItem["id"][];
-  onToggle: (id: LibraryItem["id"], event: React.MouseEvent) => void;
+  onSelectItems: (id: LibraryItem["id"][]) => void;
   onPublish: () => void;
   resetLibrary: () => void;
 }) => {
@@ -192,6 +192,55 @@ const LibraryMenuItems = ({
     (id) => libraryItems.find((item) => item.id === id)?.status === "published",
   );
 
+  const [lastSelectedItem, setLastSelectedItem] = useState<
+    LibraryItem["id"] | null
+  >(null);
+
+  const onItemSelectToggle = (
+    id: LibraryItem["id"],
+    event: React.MouseEvent,
+  ) => {
+    const shouldSelect = !selectedItems.includes(id);
+
+    const orderedItems = [...unpublishedItems, ...publishedItems];
+
+    if (shouldSelect) {
+      if (event.shiftKey && lastSelectedItem) {
+        const rangeStart = orderedItems.findIndex(
+          (item) => item.id === lastSelectedItem,
+        );
+        const rangeEnd = orderedItems.findIndex((item) => item.id === id);
+
+        if (rangeStart === -1 || rangeEnd === -1) {
+          onSelectItems([...selectedItems, id]);
+          return;
+        }
+
+        const selectedItemsMap = arrayToMap(selectedItems);
+        const nextSelectedIds = orderedItems.reduce(
+          (acc: LibraryItem["id"][], item, idx) => {
+            if (
+              (idx >= rangeStart && idx <= rangeEnd) ||
+              selectedItemsMap.has(item.id)
+            ) {
+              acc.push(item.id);
+            }
+            return acc;
+          },
+          [],
+        );
+
+        onSelectItems(nextSelectedIds);
+      } else {
+        onSelectItems([...selectedItems, id]);
+      }
+      setLastSelectedItem(id);
+    } else {
+      setLastSelectedItem(null);
+      onSelectItems(selectedItems.filter((_id) => _id !== id));
+    }
+  };
+
   const createLibraryItemCompo = (params: {
     item:
       | LibraryItem
@@ -212,9 +261,7 @@ const LibraryMenuItems = ({
           onClick={params.onClick || (() => {})}
           id={params.item?.id || null}
           selected={!!params.item?.id && selectedItems.includes(params.item.id)}
-          onToggle={(id, event) => {
-            onToggle(id, event);
-          }}
+          onToggle={onItemSelectToggle}
         />
       </Stack.Col>
     );
@@ -272,16 +319,12 @@ const LibraryMenuItems = ({
     });
   };
 
+  const unpublishedItems = libraryItems.filter(
+    (item) => item.status !== "published",
+  );
   const publishedItems = libraryItems.filter(
     (item) => item.status === "published",
   );
-  const unpublishedItems = [
-    // append pending library item
-    ...(pendingElements.length
-      ? [{ id: null, elements: pendingElements }]
-      : []),
-    ...libraryItems.filter((item) => item.status !== "published"),
-  ];
 
   return (
     <div className="library-menu-items-container">
@@ -310,7 +353,13 @@ const LibraryMenuItems = ({
       >
         <>
           <div className="separator">{t("labels.personalLib")}</div>
-          {renderLibrarySection(unpublishedItems)}
+          {renderLibrarySection([
+            // append pending library item
+            ...(pendingElements.length
+              ? [{ id: null, elements: pendingElements }]
+              : []),
+            ...unpublishedItems,
+          ])}
         </>
 
         <>