Add ability to reordering workspaces (#3446)

* added reordering of workspaces

* smooth ui updates on dnd + ui bug fixes

* pin react-beautiful-dnd version

* Move to localstorage solution to support single and multi-user

---------

Co-authored-by: Ron Metzger <ron.metzger@korn-recycling.de>
Co-authored-by: shatfield4 <seanhatfield5@gmail.com>
Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
MrMarans 2025-03-18 16:00:51 +01:00 committed by GitHub
parent e01c0dff04
commit 5264baeac8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 297 additions and 100 deletions

View File

@ -29,6 +29,7 @@
"onnxruntime-web": "^1.18.0",
"pluralize": "^8.0.0",
"react": "^18.2.0",
"react-beautiful-dnd": "13.1.1",
"react-device-detect": "^2.2.2",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",

View File

@ -43,7 +43,7 @@ export default function ThreadItem({
isActive
? "border-l-2 border-b-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-b border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[50%] absolute top-0 left-2 rounded-bl-lg`}
} h-[50%] absolute top-0 left-3 rounded-bl-lg`}
></div>
{/* Downstroke border for next item */}
{hasNext && (
@ -53,7 +53,7 @@ export default function ThreadItem({
idx <= activeIdx && !isActive
? "border-l-2 border-white light:border-theme-sidebar-border z-[2]"
: "border-l border-[#6F6F71] light:border-theme-sidebar-border z-[1]"
} h-[100%] absolute top-0 left-2`}
} h-[100%] absolute top-0 left-3`}
></div>
)}

View File

@ -7,10 +7,17 @@ import ManageWorkspace, {
} from "../../Modals/ManageWorkspace";
import paths from "@/utils/paths";
import { useParams } from "react-router-dom";
import { GearSix, SquaresFour, UploadSimple } from "@phosphor-icons/react";
import {
GearSix,
SquaresFour,
UploadSimple,
DotsSixVertical,
} from "@phosphor-icons/react";
import useUser from "@/hooks/useUser";
import ThreadContainer from "./ThreadContainer";
import { Link, useMatch } from "react-router-dom";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import showToast from "@/utils/toast";
export default function ActiveWorkspaces() {
const { slug } = useParams();
@ -25,7 +32,7 @@ export default function ActiveWorkspaces() {
async function getWorkspaces() {
const workspaces = await Workspace.all();
setLoading(false);
setWorkspaces(workspaces);
setWorkspaces(Workspace.orderWorkspaces(workspaces));
}
getWorkspaces();
}, []);
@ -44,108 +51,167 @@ export default function ActiveWorkspaces() {
);
}
/**
* Reorders workspaces in the UI via localstorage on client side.
* @param {number} startIndex - the index of the workspace to move
* @param {number} endIndex - the index to move the workspace to
*/
function reorderWorkspaces(startIndex, endIndex) {
const reorderedWorkspaces = Array.from(workspaces);
const [removed] = reorderedWorkspaces.splice(startIndex, 1);
reorderedWorkspaces.splice(endIndex, 0, removed);
setWorkspaces(reorderedWorkspaces);
const success = Workspace.storeWorkspaceOrder(
reorderedWorkspaces.map((w) => w.id)
);
if (!success) {
showToast("Failed to reorder workspaces", "error");
Workspace.all().then((workspaces) => setWorkspaces(workspaces));
}
}
const onDragEnd = (result) => {
if (!result.destination) return;
reorderWorkspaces(result.source.index, result.destination.index);
};
return (
<div role="list" aria-label="Workspaces" className="flex flex-col gap-y-2">
{workspaces.map((workspace) => {
const isActive = workspace.slug === slug;
return (
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="workspaces">
{(provided) => (
<div
className="flex flex-col w-full group"
key={workspace.id}
role="listitem"
role="list"
aria-label="Workspaces"
className="flex flex-col gap-y-2"
ref={provided.innerRef}
{...provided.droppableProps}
>
<div className="flex gap-x-2 items-center justify-between">
<a
href={isActive ? null : paths.workspace.chat(workspace.slug)}
aria-current={isActive ? "page" : ""}
className={`
transition-all duration-[200ms]
flex flex-grow w-[75%] gap-x-2 py-[6px] px-[12px] rounded-[4px] text-white justify-start items-center
bg-theme-sidebar-item-default
hover:bg-theme-sidebar-subitem-hover hover:font-bold
${isActive ? "bg-theme-sidebar-item-selected font-bold border-solid border-2 border-transparent light:border-blue-400" : ""}
`}
>
<div className="flex flex-row justify-between w-full">
<div className="flex items-center space-x-2 overflow-hidden">
<SquaresFour
weight={isActive ? "fill" : "regular"}
className="flex-shrink-0"
color={
isActive
? "var(--theme-sidebar-item-workspace-active)"
: "var(--theme-sidebar-item-workspace-inactive)"
}
size={24}
/>
<div className="w-[130px] overflow-hidden">
<p
className={`
text-[14px] leading-loose whitespace-nowrap overflow-hidden text-white
${isActive ? "font-bold" : "font-medium"} truncate
w-full group-hover:w-[100px] group-hover:font-bold group-hover:duration-200
`}
>
{workspace.name}
</p>
</div>
</div>
{user?.role !== "default" && (
{workspaces.map((workspace, index) => {
const isActive = workspace.slug === slug;
return (
<Draggable
key={workspace.id}
draggableId={workspace.id.toString()}
index={index}
isDragDisabled={user?.role === "default"}
>
{(provided, snapshot) => (
<div
className={`flex items-center gap-x-[2px] transition-opacity duration-200 ${isActive ? "opacity-100" : "opacity-0 group-hover:opacity-100"}`}
ref={provided.innerRef}
{...provided.draggableProps}
className={`flex flex-col w-full group ${
snapshot.isDragging ? "opacity-50" : ""
}`}
role="listitem"
>
<button
type="button"
onClick={(e) => {
e.preventDefault();
setSelectedWs(workspace);
showModal();
}}
className="border-none rounded-md flex items-center justify-center ml-auto p-[2px] hover:bg-[#646768] text-[#A7A8A9] hover:text-white"
>
<UploadSimple
className="h-[20px] w-[20px]"
weight="bold"
/>
</button>
<Link
to={
isInWorkspaceSettings
? paths.workspace.chat(workspace.slug)
: paths.workspace.settings.generalAppearance(
workspace.slug
)
}
className="rounded-md flex items-center justify-center text-[#A7A8A9] hover:text-white ml-auto p-[2px] hover:bg-[#646768]"
aria-label="General appearance settings"
>
<GearSix
color={
isInWorkspaceSettings && workspace.slug === slug
? "#46C8FF"
: undefined
<div className="flex gap-x-2 items-center justify-between">
<a
href={
isActive
? null
: paths.workspace.chat(workspace.slug)
}
weight="bold"
className="h-[20px] w-[20px]"
aria-current={isActive ? "page" : ""}
className={`
transition-all duration-[200ms]
flex flex-grow w-[75%] gap-x-2 py-[6px] pl-[4px] pr-[6px] rounded-[4px] text-white justify-start items-center
bg-theme-sidebar-item-default
hover:bg-theme-sidebar-subitem-hover hover:font-bold
${isActive ? "bg-theme-sidebar-item-selected font-bold light:outline-2 light:outline light:outline-blue-400 light:outline-offset-[-2px]" : ""}
`}
>
<div className="flex flex-row justify-between w-full items-center">
{user?.role !== "default" && (
<div
{...provided.dragHandleProps}
className="cursor-grab mr-[3px]"
>
<DotsSixVertical
size={20}
color="var(--theme-sidebar-item-workspace-active)"
weight="bold"
/>
</div>
)}
<div className="flex items-center space-x-2 overflow-hidden flex-grow">
<div className="w-[130px] overflow-hidden">
<p
className={`
text-[14px] leading-loose whitespace-nowrap overflow-hidden text-white
${isActive ? "font-bold" : "font-medium"} truncate
w-full group-hover:w-[100px] group-hover:font-bold group-hover:duration-200
`}
>
{workspace.name}
</p>
</div>
</div>
{user?.role !== "default" && (
<div
className={`flex items-center gap-x-[2px] transition-opacity duration-200 ${isActive ? "opacity-100" : "opacity-0 group-hover:opacity-100"}`}
>
<button
type="button"
onClick={(e) => {
e.preventDefault();
setSelectedWs(workspace);
showModal();
}}
className="border-none rounded-md flex items-center justify-center ml-auto p-[2px] hover:bg-[#646768] text-[#A7A8A9] hover:text-white"
>
<UploadSimple
className="h-[20px] w-[20px]"
// weight="bold"
/>
</button>
<Link
to={
isInWorkspaceSettings
? paths.workspace.chat(workspace.slug)
: paths.workspace.settings.generalAppearance(
workspace.slug
)
}
className="rounded-md flex items-center justify-center text-[#A7A8A9] hover:text-white ml-auto p-[2px] hover:bg-[#646768]"
aria-label="General appearance settings"
>
<GearSix
color={
isInWorkspaceSettings &&
workspace.slug === slug
? "#46C8FF"
: undefined
}
// weight="bold"
className="h-[20px] w-[20px]"
/>
</Link>
</div>
)}
</div>
</a>
</div>
{isActive && (
<ThreadContainer
workspace={workspace}
isActive={isActive}
/>
</Link>
)}
</div>
)}
</div>
</a>
</div>
{isActive && (
<ThreadContainer workspace={workspace} isActive={isActive} />
</Draggable>
);
})}
{provided.placeholder}
{showing && (
<ManageWorkspace
hideModal={hideModal}
providedSlug={selectedWs ? selectedWs.slug : null}
/>
)}
</div>
);
})}
{showing && (
<ManageWorkspace
hideModal={hideModal}
providedSlug={selectedWs ? selectedWs.slug : null}
/>
)}
</div>
)}
</Droppable>
</DragDropContext>
);
}

View File

@ -1,11 +1,13 @@
import { API_BASE } from "@/utils/constants";
import { baseHeaders } from "@/utils/request";
import { baseHeaders, safeJsonParse } from "@/utils/request";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import WorkspaceThread from "@/models/workspaceThread";
import { v4 } from "uuid";
import { ABORT_STREAM_EVENT } from "@/utils/chat";
const Workspace = {
workspaceOrderStorageKey: "anythingllm-workspace-order",
new: async function (data = {}) {
const { workspace, message } = await fetch(`${API_BASE}/workspace/new`, {
method: "POST",
@ -469,6 +471,43 @@ const Workspace = {
);
return response.ok;
},
/**
* Reorders workspaces in the UI via localstorage on client side.
* @param {string[]} workspaceIds - array of workspace ids to reorder
* @returns {boolean}
*/
storeWorkspaceOrder: function (workspaceIds = []) {
try {
localStorage.setItem(
this.workspaceOrderStorageKey,
JSON.stringify(workspaceIds)
);
return true;
} catch (error) {
console.error("Error reordering workspaces:", error);
return false;
}
},
/**
* Orders workspaces based on the order preference stored in localstorage
* @param {Array} workspaces - array of workspace JSON objects
* @returns {Array} - ordered workspaces
*/
orderWorkspaces: function (workspaces = []) {
const workspaceOrderPreference =
safeJsonParse(localStorage.getItem(this.workspaceOrderStorageKey)) || [];
if (workspaceOrderPreference.length === 0) return workspaces;
const orderedWorkspaces = Array.from(workspaces);
orderedWorkspaces.sort(
(a, b) =>
workspaceOrderPreference.indexOf(a.id) -
workspaceOrderPreference.indexOf(b.id)
);
return orderedWorkspaces;
},
threads: WorkspaceThread,
};

View File

@ -183,6 +183,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.7"
"@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2":
version "7.26.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2"
integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
version "7.24.8"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.8.tgz#5d958c3827b13cc6d05e038c07fb2e5e3420d82e"
@ -702,6 +709,14 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz#6bba74383cdab98e8db4e20ce5b4a6b98caed010"
integrity sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/node@>=13.7.0":
version "22.1.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.1.0.tgz#6d6adc648b5e03f0e83c78dc788c2b037d0ad94b"
@ -721,6 +736,16 @@
dependencies:
"@types/react" "*"
"@types/react-redux@^7.1.20":
version "7.1.34"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e"
integrity sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react-router-dom@^5.3.3":
version "5.3.3"
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
@ -1163,6 +1188,13 @@ cross-spawn@^7.0.1:
shebang-command "^2.0.0"
which "^2.0.1"
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-line-break@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
@ -2049,6 +2081,13 @@ highlight.js@^11.9.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.10.0.tgz#6e3600dc4b33d6dc23d5bd94fbf72405f5892b92"
integrity sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^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"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"
html-parse-stringify@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
@ -2520,6 +2559,11 @@ mdurl@^1.0.1:
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
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==
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@ -2870,7 +2914,7 @@ prettier@^3.0.3:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
prop-types@^15.6.2, prop-types@^15.8.1:
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -2907,6 +2951,24 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
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==
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-day-picker@^8.10.1:
version "8.10.1"
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.10.1.tgz#4762ec298865919b93ec09ba69621580835b8e80"
@ -2944,16 +3006,33 @@ react-i18next@^14.1.1:
"@babel/runtime" "^7.23.9"
html-parse-stringify "^3.0.1"
react-is@^16.10.2, react-is@^16.13.1:
react-is@^16.10.2, react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
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-loading-skeleton@^3.1.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/react-loading-skeleton/-/react-loading-skeleton-3.4.0.tgz#c71a3a17259d08e4064974aa0b07f150a09dfd57"
integrity sha512-1oJEBc9+wn7BbkQQk7YodlYEIjgeR+GrRjD+QXkVjwZN7LGIcAFHrx4NhT7UHGBxNY1+zax3c+Fo6XQM4R7CgA==
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-refresh@^0.14.2:
version "0.14.2"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
@ -3072,6 +3151,13 @@ recharts@^2.12.5, recharts@^2.12.7:
tiny-invariant "^1.3.1"
victory-vendor "^36.6.8"
redux@^4.0.0, redux@^4.0.4:
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"
reflect.getprototypeof@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859"
@ -3599,7 +3685,7 @@ thenify-all@^1.0.0:
dependencies:
any-promise "^1.0.0"
tiny-invariant@^1.3.1:
tiny-invariant@^1.0.6, tiny-invariant@^1.3.1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
@ -3727,6 +3813,11 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
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==
util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"