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

This commit is contained in:
David Luzar 2022-05-07 19:13:10 +02:00 committed by GitHub
parent 9e8e047aae
commit 65c32b3319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 61 deletions

View File

@ -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}
/>

View File

@ -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,
])}
</>
<>