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 LibraryMenuItems from "./LibraryMenuItems";
|
||||||
import { EVENT } from "../constants";
|
import { EVENT } from "../constants";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import { arrayToMap } from "../utils";
|
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { jotaiScope } from "../jotai";
|
import { jotaiScope } from "../jotai";
|
||||||
@ -225,10 +224,6 @@ export const LibraryMenu = ({
|
|||||||
[setShowPublishLibraryDialog, setPublishLibSuccess, selectedItems, library],
|
[setShowPublishLibraryDialog, setPublishLibSuccess, selectedItems, library],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [lastSelectedItem, setLastSelectedItem] = useState<
|
|
||||||
LibraryItem["id"] | null
|
|
||||||
>(null);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
libraryItemsData.status === "loading" &&
|
libraryItemsData.status === "loading" &&
|
||||||
!libraryItemsData.isInitialized
|
!libraryItemsData.isInitialized
|
||||||
@ -284,47 +279,7 @@ export const LibraryMenu = ({
|
|||||||
files={files}
|
files={files}
|
||||||
id={id}
|
id={id}
|
||||||
selectedItems={selectedItems}
|
selectedItems={selectedItems}
|
||||||
onToggle={(id, event) => {
|
onSelectItems={(ids) => setSelectedItems(ids)}
|
||||||
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));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPublish={() => setShowPublishLibraryDialog(true)}
|
onPublish={() => setShowPublishLibraryDialog(true)}
|
||||||
resetLibrary={resetLibrary}
|
resetLibrary={resetLibrary}
|
||||||
/>
|
/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { chunk } from "lodash";
|
import { chunk } from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import { importLibraryFromJSON, saveLibraryAsJSON } from "../data/json";
|
import { importLibraryFromJSON, saveLibraryAsJSON } from "../data/json";
|
||||||
import Library from "../data/library";
|
import Library from "../data/library";
|
||||||
import { ExcalidrawElement, NonDeleted } from "../element/types";
|
import { ExcalidrawElement, NonDeleted } from "../element/types";
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
LibraryItem,
|
LibraryItem,
|
||||||
LibraryItems,
|
LibraryItems,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import { muteFSAbortError } from "../utils";
|
import { arrayToMap, muteFSAbortError } from "../utils";
|
||||||
import { useDeviceType } from "./App";
|
import { useDeviceType } from "./App";
|
||||||
import ConfirmDialog from "./ConfirmDialog";
|
import ConfirmDialog from "./ConfirmDialog";
|
||||||
import { exportToFileIcon, load, publishIcon, trash } from "./icons";
|
import { exportToFileIcon, load, publishIcon, trash } from "./icons";
|
||||||
@ -38,7 +38,7 @@ const LibraryMenuItems = ({
|
|||||||
files,
|
files,
|
||||||
id,
|
id,
|
||||||
selectedItems,
|
selectedItems,
|
||||||
onToggle,
|
onSelectItems,
|
||||||
onPublish,
|
onPublish,
|
||||||
resetLibrary,
|
resetLibrary,
|
||||||
}: {
|
}: {
|
||||||
@ -55,7 +55,7 @@ const LibraryMenuItems = ({
|
|||||||
library: Library;
|
library: Library;
|
||||||
id: string;
|
id: string;
|
||||||
selectedItems: LibraryItem["id"][];
|
selectedItems: LibraryItem["id"][];
|
||||||
onToggle: (id: LibraryItem["id"], event: React.MouseEvent) => void;
|
onSelectItems: (id: LibraryItem["id"][]) => void;
|
||||||
onPublish: () => void;
|
onPublish: () => void;
|
||||||
resetLibrary: () => void;
|
resetLibrary: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
@ -192,6 +192,55 @@ const LibraryMenuItems = ({
|
|||||||
(id) => libraryItems.find((item) => item.id === id)?.status === "published",
|
(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: {
|
const createLibraryItemCompo = (params: {
|
||||||
item:
|
item:
|
||||||
| LibraryItem
|
| LibraryItem
|
||||||
@ -212,9 +261,7 @@ const LibraryMenuItems = ({
|
|||||||
onClick={params.onClick || (() => {})}
|
onClick={params.onClick || (() => {})}
|
||||||
id={params.item?.id || null}
|
id={params.item?.id || null}
|
||||||
selected={!!params.item?.id && selectedItems.includes(params.item.id)}
|
selected={!!params.item?.id && selectedItems.includes(params.item.id)}
|
||||||
onToggle={(id, event) => {
|
onToggle={onItemSelectToggle}
|
||||||
onToggle(id, event);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Stack.Col>
|
</Stack.Col>
|
||||||
);
|
);
|
||||||
@ -272,16 +319,12 @@ const LibraryMenuItems = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unpublishedItems = libraryItems.filter(
|
||||||
|
(item) => item.status !== "published",
|
||||||
|
);
|
||||||
const publishedItems = libraryItems.filter(
|
const publishedItems = libraryItems.filter(
|
||||||
(item) => item.status === "published",
|
(item) => item.status === "published",
|
||||||
);
|
);
|
||||||
const unpublishedItems = [
|
|
||||||
// append pending library item
|
|
||||||
...(pendingElements.length
|
|
||||||
? [{ id: null, elements: pendingElements }]
|
|
||||||
: []),
|
|
||||||
...libraryItems.filter((item) => item.status !== "published"),
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="library-menu-items-container">
|
<div className="library-menu-items-container">
|
||||||
@ -310,7 +353,13 @@ const LibraryMenuItems = ({
|
|||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<div className="separator">{t("labels.personalLib")}</div>
|
<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