fix: library multiselect not accounting for published state (#5132)
This commit is contained in:
parent
9e8e047aae
commit
65c32b3319
@ -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}
|
||||
/>
|
||||
|
@ -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,
|
||||
])}
|
||||
</>
|
||||
|
||||
<>
|
||||
|
Loading…
x
Reference in New Issue
Block a user