Make sidebar collections sortable

This commit is contained in:
Isaac Wise 2024-02-22 01:51:51 -06:00
parent 0dda77db1e
commit 44272540aa
9 changed files with 253 additions and 69 deletions

View File

@ -1,8 +1,10 @@
import useAccountStore from "@/store/account";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
type Props = { type Props = {
links: boolean; links: boolean;
@ -10,37 +12,76 @@ type Props = {
const CollectionSelection = ({ links }: Props) => { const CollectionSelection = ({ links }: Props) => {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { account, updateAccount } = useAccountStore();
const [active, setActive] = useState(""); const [active, setActive] = useState("");
const router = useRouter(); const router = useRouter();
useEffect(() => { useEffect(() => {
setActive(router.asPath); setActive(router.asPath);
if (account.collectionOrder?.length === 0) {
updateAccount({
...account,
collectionOrder: collections
.filter((e) => e.parentId === null) // Filter out collections with non-null parentId
.map((e) => e.id as number), // Use "as number" to assert that e.id is a number
});
}
}, [router, collections]); }, [router, collections]);
return ( return (
<div> <DragDropContext
{collections[0] ? ( onDragEnd={(result) => {
collections if (!result.destination) {
.sort((a, b) => a.name.localeCompare(b.name)) return; // Dragged outside the droppable area, do nothing
.filter((e) => e.parentId === null) }
.map((e, i) => (
const updatedCollectionOrder = [...account.collectionOrder];
const [movedCollectionId] = updatedCollectionOrder.splice(result.source.index, 1);
updatedCollectionOrder.splice(result.destination.index, 0, movedCollectionId);
// Update account with the new collection order
updateAccount({
...account,
collectionOrder: updatedCollectionOrder,
});
}}
>
<Droppable droppableId="collections">
{(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{account.collectionOrder?.map((collectionId, index) => {
const collection = collections.find((c) => c.id === collectionId);
if (collection) {
return (
<Draggable
key={collection.id}
draggableId={`collection-${collection.id}`}
index={index}
>
{(provided) => (
<CollectionItem <CollectionItem
key={i} innerRef={provided.innerRef}
collection={e} {...provided.draggableProps}
{...provided.dragHandleProps}
key={index}
collection={collection}
active={active} active={active}
collections={collections} collections={collections}
/> />
)) )}
) : ( </Draggable>
<div );
className={`duration-100 py-1 px-2 flex items-center gap-2 w-full rounded-md h-8 capitalize`} }
>
<p className="text-neutral text-xs font-semibold truncate w-full pr-7"> return null; // Collection not found
You Have No Collections... })}
</p> {provided.placeholder}
</div> </div>
)} )}
</div> </Droppable>
</DragDropContext>
); );
}; };
@ -50,15 +91,16 @@ const CollectionItem = ({
collection, collection,
active, active,
collections, collections,
innerRef,
...props
}: { }: {
collection: CollectionIncludingMembersAndLinkCount; collection: CollectionIncludingMembersAndLinkCount;
active: string; active: string;
collections: CollectionIncludingMembersAndLinkCount[]; collections: CollectionIncludingMembersAndLinkCount[];
innerRef?: any;
}) => { }) => {
const hasChildren = collections.some((e) => e.parentId === collection.id); const hasChildren = collections.some((e) => e.parentId === collection.id);
const router = useRouter();
// Check if the current collection or any of its subcollections is active // Check if the current collection or any of its subcollections is active
const isActiveOrParentOfActive = React.useMemo(() => { const isActiveOrParentOfActive = React.useMemo(() => {
const isActive = active === `/collections/${collection.id}`; const isActive = active === `/collections/${collection.id}`;
@ -86,8 +128,9 @@ const CollectionItem = ({
return hasChildren ? ( return hasChildren ? (
<> <>
<div <div
className={`${ ref={innerRef}
active === `/collections/${collection.id}` {...props}
className={`${active === `/collections/${collection.id}`
? "bg-primary/20" ? "bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
} duration-100 rounded-md flex w-full items-center cursor-pointer mb-1 px-2 gap-1`} } duration-100 rounded-md flex w-full items-center cursor-pointer mb-1 px-2 gap-1`}
@ -97,8 +140,7 @@ const CollectionItem = ({
className="flex items-center" className="flex items-center"
> >
<i <i
className={`bi-chevron-down ${ className={`bi-chevron-down ${isOpen ? "rotate-reverse" : "rotate"
isOpen ? "rotate-reverse" : "rotate"
}`} }`}
></i> ></i>
</button> </button>
@ -140,10 +182,9 @@ const CollectionItem = ({
)} )}
</> </>
) : ( ) : (
<Link href={`/collections/${collection.id}`} className="w-full"> <Link ref={innerRef} {...props} href={`/collections/${collection.id}`} className="w-full">
<div <div
className={`${ className={`${active === `/collections/${collection.id}`
active === `/collections/${collection.id}`
? "bg-primary/20" ? "bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize mb-1`} } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize mb-1`}

View File

@ -22,11 +22,10 @@ export default function Sidebar({ className }: { className?: string }) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { tags } = useTagStore(); const { tags } = useTagStore();
const [active, setActive] = useState("");
const router = useRouter(); const router = useRouter();
const [active, setActive] = useState("");
useEffect(() => { useEffect(() => {
localStorage.setItem("tagDisclosure", tagDisclosure ? "true" : "false"); localStorage.setItem("tagDisclosure", tagDisclosure ? "true" : "false");
}, [tagDisclosure]); }, [tagDisclosure]);
@ -42,11 +41,11 @@ export default function Sidebar({ className }: { className?: string }) {
setActive(router.asPath); setActive(router.asPath);
}, [router, collections]); }, [router, collections]);
return ( return (
<div <div
id="sidebar" id="sidebar"
className={`bg-base-200 h-full w-80 overflow-y-auto border-solid border border-base-200 border-r-neutral-content p-2 z-20 ${ className={`bg-base-200 h-full w-80 overflow-y-auto border-solid border border-base-200 border-r-neutral-content p-2 z-20 ${className || ""
className || ""
}`} }`}
> >
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
@ -85,8 +84,7 @@ export default function Sidebar({ className }: { className?: string }) {
> >
<p className="text-sm">Collections</p> <p className="text-sm">Collections</p>
<i <i
className={`bi-chevron-down ${ className={`bi-chevron-down ${collectionDisclosure ? "rotate-reverse" : "rotate"
collectionDisclosure ? "rotate-reverse" : "rotate"
}`} }`}
></i> ></i>
</Disclosure.Button> </Disclosure.Button>
@ -112,8 +110,7 @@ export default function Sidebar({ className }: { className?: string }) {
> >
<p className="text-sm">Tags</p> <p className="text-sm">Tags</p>
<i <i
className={`bi-chevron-down ${ className={`bi-chevron-down ${tagDisclosure ? "rotate-reverse" : "rotate"
tagDisclosure ? "rotate-reverse" : "rotate"
}`} }`}
></i> ></i>
</Disclosure.Button> </Disclosure.Button>
@ -133,8 +130,7 @@ export default function Sidebar({ className }: { className?: string }) {
return ( return (
<Link key={i} href={`/tags/${e.id}`}> <Link key={i} href={`/tags/${e.id}`}>
<div <div
className={`${ className={`${active === `/tags/${e.id}`
active === `/tags/${e.id}`
? "bg-primary/20" ? "bg-primary/20"
: "hover:bg-neutral/20" : "hover:bg-neutral/20"
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8`} } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8`}

View File

@ -183,6 +183,7 @@ export default async function updateUserById(
email: data.email?.toLowerCase().trim(), email: data.email?.toLowerCase().trim(),
isPrivate: data.isPrivate, isPrivate: data.isPrivate,
image: data.image ? `uploads/avatar/${userId}.jpg` : "", image: data.image ? `uploads/avatar/${userId}.jpg` : "",
collectionOrder: data.collectionOrder,
archiveAsScreenshot: data.archiveAsScreenshot, archiveAsScreenshot: data.archiveAsScreenshot,
archiveAsPDF: data.archiveAsPDF, archiveAsPDF: data.archiveAsPDF,
archiveAsWaybackMachine: data.archiveAsWaybackMachine, archiveAsWaybackMachine: data.archiveAsWaybackMachine,

View File

@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: false,
images: { images: {
domains: ["t2.gstatic.com"], domains: ["t2.gstatic.com"],
minimumCacheTTL: 10, minimumCacheTTL: 10,

View File

@ -30,6 +30,7 @@
"@types/node": "^20.10.4", "@types/node": "^20.10.4",
"@types/nodemailer": "^6.4.8", "@types/nodemailer": "^6.4.8",
"@types/react": "18.2.14", "@types/react": "18.2.14",
"@types/react-beautiful-dnd": "^13.1.8",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"axios": "^1.5.1", "axios": "^1.5.1",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
@ -55,7 +56,10 @@
"nodemailer": "^6.9.3", "nodemailer": "^6.9.3",
"playwright": "^1.35.1", "playwright": "^1.35.1",
"react": "18.2.0", "react": "18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-colorful": "^5.6.1", "react-colorful": "^5.6.1",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"react-image-file-resizer": "^0.4.8", "react-image-file-resizer": "^0.4.8",

View File

@ -54,6 +54,7 @@ export default function App({
<link rel="manifest" href="/site.webmanifest" /> <link rel="manifest" href="/site.webmanifest" />
</Head> </Head>
<AuthRedirect> <AuthRedirect>
<Toaster <Toaster
position="top-center" position="top-center"
reverseOrder={false} reverseOrder={false}

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "collectionOrder" INTEGER[] DEFAULT ARRAY[]::INTEGER[];

View File

@ -38,6 +38,7 @@ model User {
tags Tag[] tags Tag[]
pinnedLinks Link[] pinnedLinks Link[]
collectionsJoined UsersAndCollections[] collectionsJoined UsersAndCollections[]
collectionOrder Int[] @default([])
whitelistedUsers WhitelistedUser[] whitelistedUsers WhitelistedUser[]
accessTokens AccessToken[] accessTokens AccessToken[]
subscriptions Subscription? subscriptions Subscription?

142
yarn.lock
View File

@ -628,6 +628,13 @@
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.21.0": "@babel/runtime@^7.21.0":
version "7.23.6" version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
@ -1417,6 +1424,21 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@react-dnd/asap@^5.0.1":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-5.0.2.tgz#1f81f124c1cd6f39511c11a881cfb0f715343488"
integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==
"@react-dnd/invariant@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-4.0.2.tgz#b92edffca10a26466643349fac7cdfb8799769df"
integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==
"@react-dnd/shallowequal@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz#d1b4befa423f692fa4abf1c79209702e7d8ae4b4"
integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==
"@rushstack/eslint-patch@^1.1.3": "@rushstack/eslint-patch@^1.1.3":
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
@ -1925,6 +1947,14 @@
"@types/minimatch" "*" "@types/minimatch" "*"
"@types/node" "*" "@types/node" "*"
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.5"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/jsdom@^21.1.3": "@types/jsdom@^21.1.3":
version "21.1.3" version "21.1.3"
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.3.tgz#a88c5dc65703e1b10b2a7839c12db49662b43ff0" resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.3.tgz#a88c5dc65703e1b10b2a7839c12db49662b43ff0"
@ -1986,6 +2016,13 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/react-beautiful-dnd@^13.1.8":
version "13.1.8"
resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.8.tgz#f52d3ea07e1e19159d6c3c4a48c8da3d855e60b4"
integrity sha512-E3TyFsro9pQuK4r8S/OL6G99eq7p8v29sX0PM7oT8Z+PJfZvSQTx4zTQbUJ+QZXioAF0e7TGBEcA1XhYhCweyQ==
dependencies:
"@types/react" "*"
"@types/react-dom@18.2.7": "@types/react-dom@18.2.7":
version "18.2.7" version "18.2.7"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63"
@ -1993,6 +2030,16 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-redux@^7.1.20":
version "7.1.33"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15"
integrity sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react-transition-group@^4.4.0": "@types/react-transition-group@^4.4.0":
version "4.4.5" version "4.4.5"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416"
@ -2643,6 +2690,13 @@ crypto-js@^4.2.0:
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==
css-box-model@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1"
integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
dependencies:
tiny-invariant "^1.0.6"
css-selector-tokenizer@^0.8: css-selector-tokenizer@^0.8:
version "0.8.0" version "0.8.0"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd"
@ -2843,6 +2897,15 @@ dlv@^1.1.3:
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dnd-core@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-16.0.1.tgz#a1c213ed08961f6bd1959a28bb76f1a868360d19"
integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==
dependencies:
"@react-dnd/asap" "^5.0.1"
"@react-dnd/invariant" "^4.0.1"
redux "^4.2.0"
doctrine@^2.1.0: doctrine@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@ -3725,7 +3788,7 @@ himalaya@^1.1.0:
resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a" resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a"
integrity sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw== integrity sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw==
hoist-non-react-statics@^3.3.1: hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2" version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -4312,6 +4375,11 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
memoize-one@^5.1.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
memoize-one@^6.0.0: memoize-one@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
@ -4984,7 +5052,7 @@ process@^0.11.10:
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1" version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -5035,6 +5103,11 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
raf-schd@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
raw-body@2.4.1: raw-body@2.4.1:
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
@ -5045,11 +5118,42 @@ raw-body@2.4.1:
iconv-lite "0.4.24" iconv-lite "0.4.24"
unpipe "1.0.0" unpipe "1.0.0"
react-beautiful-dnd@^13.1.1:
version "13.1.1"
resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz#b0f3087a5840920abf8bb2325f1ffa46d8c4d0a2"
integrity sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==
dependencies:
"@babel/runtime" "^7.9.2"
css-box-model "^1.2.0"
memoize-one "^5.1.1"
raf-schd "^4.0.2"
react-redux "^7.2.0"
redux "^4.0.4"
use-memo-one "^1.1.1"
react-colorful@^5.6.1: react-colorful@^5.6.1:
version "5.6.1" version "5.6.1"
resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b"
integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==
react-dnd-html5-backend@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6"
integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==
dependencies:
dnd-core "^16.0.1"
react-dnd@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-16.0.1.tgz#2442a3ec67892c60d40a1559eef45498ba26fa37"
integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==
dependencies:
"@react-dnd/invariant" "^4.0.1"
"@react-dnd/shallowequal" "^4.0.1"
dnd-core "^16.0.1"
fast-deep-equal "^3.1.3"
hoist-non-react-statics "^3.3.2"
react-dom@18.2.0: react-dom@18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
@ -5075,6 +5179,23 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-redux@^7.2.0:
version "7.2.9"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"
integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==
dependencies:
"@babel/runtime" "^7.15.4"
"@types/react-redux" "^7.1.20"
hoist-non-react-statics "^3.3.2"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-is "^17.0.2"
react-remove-scroll-bar@^2.3.3: react-remove-scroll-bar@^2.3.3:
version "2.3.4" version "2.3.4"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9"
@ -5165,6 +5286,13 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
redux@^4.0.0, redux@^4.0.4, redux@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
dependencies:
"@babel/runtime" "^7.9.2"
regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.3: regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.3:
version "0.13.11" version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
@ -5688,6 +5816,11 @@ tiny-glob@^0.2.9:
globalyzer "0.1.0" globalyzer "0.1.0"
globrex "^0.1.2" globrex "^0.1.2"
tiny-invariant@^1.0.6:
version "1.3.1"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
tinycolor2@^1.6.0: tinycolor2@^1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e"
@ -5924,6 +6057,11 @@ use-isomorphic-layout-effect@^1.1.2:
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
use-memo-one@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
use-sidecar@^1.1.2: use-sidecar@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"