Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Mike Cao 2022-08-03 20:32:34 -07:00
commit 62dce0a8d1
10 changed files with 238 additions and 19 deletions

View File

@ -1,3 +1,4 @@
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Link from 'components/common/Link'; import Link from 'components/common/Link';
import WebsiteChart from 'components/metrics/WebsiteChart'; import WebsiteChart from 'components/metrics/WebsiteChart';
@ -5,8 +6,38 @@ import Page from 'components/layout/Page';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import Arrow from 'assets/arrow-right.svg'; import Arrow from 'assets/arrow-right.svg';
import styles from './WebsiteList.module.css'; import styles from './WebsiteList.module.css';
import { orderByWebsiteMap } from 'lib/format';
import { useMemo } from 'react';
import useStore, { setDashboard } from 'store/app';
const selector = state => state.dashboard;
export default function WebsiteList({ websites, showCharts, limit }) { export default function WebsiteList({ websites, showCharts, limit }) {
const store = useStore(selector);
const { websiteOrdering, changeOrderMode } = store;
const ordered = useMemo(
() => orderByWebsiteMap(websites, websiteOrdering),
[websites, websiteOrdering],
);
const dragId = 'dashboard-website-ordering';
function handleWebsiteDrag({ destination, source }) {
if (!destination || destination.index === source.index) return;
const orderedWebsites = [...ordered];
const [removed] = orderedWebsites.splice(source.index, 1);
orderedWebsites.splice(destination.index, 0, removed);
setDashboard({
...store,
websiteOrdering: orderedWebsites
.map((i, k) => ({ [i.website_uuid]: k }))
.reduce((a, b) => ({ ...a, ...b })),
});
}
if (websites.length === 0) { if (websites.length === 0) {
return ( return (
<Page> <Page>
@ -27,19 +58,60 @@ export default function WebsiteList({ websites, showCharts, limit }) {
} }
return ( return (
<div> <div className={changeOrderMode && styles.websiteDragActive}>
{websites.map(({ website_id, name, domain }, index) => {changeOrderMode ? (
index < limit ? ( <DragDropContext onDragEnd={handleWebsiteDrag}>
<div key={website_id} className={styles.website}> <Droppable droppableId={dragId}>
<WebsiteChart {(provided, snapshot) => (
websiteId={website_id} <div
title={name} {...provided.droppableProps}
domain={domain} ref={provided.innerRef}
showChart={showCharts} style={{ marginBottom: snapshot.isDraggingOver ? 260 : null }}
showLink >
/> {ordered.map(({ website_id, name, domain }, index) =>
</div> index < limit ? (
) : null, <Draggable
key={website_id}
draggableId={`${dragId}-${website_id}`}
index={index}
>
{provided => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className={styles.website}
>
<WebsiteChart
websiteId={website_id}
title={name}
domain={domain}
showChart={changeOrderMode ? false : showCharts}
showLink
/>
</div>
)}
</Draggable>
) : null,
)}
</div>
)}
</Droppable>
</DragDropContext>
) : (
ordered.map(({ website_id, name, domain }, index) =>
index < limit ? (
<div key={website_id} className={styles.website}>
<WebsiteChart
websiteId={website_id}
title={name}
domain={domain}
showChart={showCharts}
showLink
/>
</div>
) : null,
)
)} )}
</div> </div>
); );

View File

@ -9,3 +9,12 @@
border-bottom: 0; border-bottom: 0;
margin-bottom: 20px; margin-bottom: 20px;
} }
.websiteDragActive {
opacity: 0.6;
cursor: grab;
}
.websiteDragActive:active {
cursor: grabbing;
}

View File

@ -2,7 +2,10 @@ import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import MenuButton from 'components/common/MenuButton'; import MenuButton from 'components/common/MenuButton';
import Gear from 'assets/gear.svg'; import Gear from 'assets/gear.svg';
import useStore, { setDashboard, defaultDashboardConfig } from 'store/app'; import useStore, { setDashboard } from 'store/app';
import Button from 'components/common/Button';
import Check from 'assets/check.svg';
import styles from './DashboardSettingsButton.module.css';
const selector = state => state.dashboard; const selector = state => state.dashboard;
@ -14,14 +17,41 @@ export default function DashboardSettingsButton() {
label: <FormattedMessage id="message.toggle-charts" defaultMessage="Toggle charts" />, label: <FormattedMessage id="message.toggle-charts" defaultMessage="Toggle charts" />,
value: 'charts', value: 'charts',
}, },
{
label: <FormattedMessage id="message.edit-dashboard" defaultMessage="Edit dashboard" />,
value: 'order',
},
]; ];
function handleSelect(value) { function handleSelect(value) {
if (value === 'charts') { if (value === 'charts') {
setDashboard({ ...defaultDashboardConfig, showCharts: !settings.showCharts }); setDashboard({ ...settings, showCharts: !settings.showCharts });
}
if (value === 'order') {
setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode });
} }
//setDashboard(value); //setDashboard(value);
} }
function handleExitChangeOrderMode() {
setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode });
}
function resetWebsiteOrder() {
setDashboard({ ...settings, websiteOrdering: {} });
}
if (settings.changeOrderMode)
return (
<div className={styles.buttonGroup}>
<Button onClick={resetWebsiteOrder} size="small">
<FormattedMessage id="label.reset-order" defaultMessage="Reset order" />
</Button>
<Button onClick={handleExitChangeOrderMode} size="small" icon={<Check />}>
<FormattedMessage id="label.done" defaultMessage="Done" />
</Button>
</div>
);
return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />; return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />;
} }

View File

@ -0,0 +1,5 @@
.buttonGroup {
display: flex;
place-items: center;
gap: 10px;
}

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useMemo, useState } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import Link from 'components/common/Link'; import Link from 'components/common/Link';
@ -24,8 +24,12 @@ import Code from 'assets/code.svg';
import LinkIcon from 'assets/link.svg'; import LinkIcon from 'assets/link.svg';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import useUser from 'hooks/useUser'; import useUser from 'hooks/useUser';
import { orderByWebsiteMap } from 'lib/format';
import useStore from 'store/app';
import styles from './WebsiteSettings.module.css'; import styles from './WebsiteSettings.module.css';
const selector = state => state.dashboard;
export default function WebsiteSettings() { export default function WebsiteSettings() {
const { user } = useUser(); const { user } = useUser();
const [editWebsite, setEditWebsite] = useState(); const [editWebsite, setEditWebsite] = useState();
@ -36,8 +40,14 @@ export default function WebsiteSettings() {
const [showUrl, setShowUrl] = useState(); const [showUrl, setShowUrl] = useState();
const [saved, setSaved] = useState(0); const [saved, setSaved] = useState(0);
const [message, setMessage] = useState(); const [message, setMessage] = useState();
const store = useStore(selector);
const { websiteOrdering } = store;
const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]); const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]);
const ordered = useMemo(() => orderByWebsiteMap(data, websiteOrdering), [data, websiteOrdering]);
const Buttons = row => ( const Buttons = row => (
<ButtonLayout align="right"> <ButtonLayout align="right">
{row.share_id && ( {row.share_id && (
@ -186,7 +196,7 @@ export default function WebsiteSettings() {
<FormattedMessage id="label.add-website" defaultMessage="Add website" /> <FormattedMessage id="label.add-website" defaultMessage="Add website" />
</Button> </Button>
</PageHeader> </PageHeader>
<Table columns={user.is_admin ? adminColumns : columns} rows={data} empty={empty} /> <Table columns={user.is_admin ? adminColumns : columns} rows={ordered} empty={empty} />
{editWebsite && ( {editWebsite && (
<Modal title={<FormattedMessage id="label.edit-website" defaultMessage="Edit website" />}> <Modal title={<FormattedMessage id="label.edit-website" defaultMessage="Edit website" />}>
<WebsiteEditForm values={editWebsite} onSave={handleSave} onClose={handleClose} /> <WebsiteEditForm values={editWebsite} onSave={handleSave} onClose={handleClose} />

View File

@ -22,8 +22,10 @@
"label.delete-website": "Delete website", "label.delete-website": "Delete website",
"label.dismiss": "Dismiss", "label.dismiss": "Dismiss",
"label.domain": "Domain", "label.domain": "Domain",
"label.done": "Done",
"label.edit": "Edit", "label.edit": "Edit",
"label.edit-account": "Edit account", "label.edit-account": "Edit account",
"label.edit-dashboard": "Edit dashboard",
"label.edit-website": "Edit website", "label.edit-website": "Edit website",
"label.enable-share-url": "Enable share URL", "label.enable-share-url": "Enable share URL",
"label.invalid": "Invalid", "label.invalid": "Invalid",
@ -47,6 +49,7 @@
"label.refresh": "Refresh", "label.refresh": "Refresh",
"label.required": "Required", "label.required": "Required",
"label.reset": "Reset", "label.reset": "Reset",
"label.reset-order": "Reset order",
"label.reset-website": "Reset statistics", "label.reset-website": "Reset statistics",
"label.save": "Save", "label.save": "Save",
"label.settings": "Settings", "label.settings": "Settings",

View File

@ -78,3 +78,14 @@ export function stringToColor(str) {
} }
return color; return color;
} }
export function orderByWebsiteMap(websites, orderMap) {
if (!websites) return [];
let ordered = [...websites];
for (let website of websites) {
ordered[orderMap[website.website_uuid]] = website;
}
return ordered;
}

View File

@ -85,6 +85,7 @@
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^17.0.0", "react": "^17.0.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.0", "react-dom": "^17.0.0",
"react-intl": "^5.24.7", "react-intl": "^5.24.7",
"react-simple-maps": "^2.3.0", "react-simple-maps": "^2.3.0",

View File

@ -12,6 +12,8 @@ import { getItem, setItem } from 'lib/web';
export const defaultDashboardConfig = { export const defaultDashboardConfig = {
showCharts: true, showCharts: true,
limit: DEFAULT_WEBSITE_LIMIT, limit: DEFAULT_WEBSITE_LIMIT,
websiteOrdering: {},
changeOrderMode: false,
}; };
const initialState = { const initialState = {

View File

@ -989,6 +989,13 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.8.4": "@babel/runtime@^7.8.4":
version "7.17.2" version "7.17.2"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz"
@ -1725,7 +1732,7 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/hoist-non-react-statics@^3.3.1": "@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1":
version "3.3.1" version "3.3.1"
resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
@ -1778,6 +1785,16 @@
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/react-redux@^7.1.20":
version "7.1.24"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.24.tgz#6caaff1603aba17b27d20f8ad073e4c077e975c0"
integrity sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react@*", "@types/react@16 || 17 || 18": "@types/react@*", "@types/react@16 || 17 || 18":
version "18.0.10" version "18.0.10"
resolved "https://registry.npmjs.org/@types/react/-/react-18.0.10.tgz" resolved "https://registry.npmjs.org/@types/react/-/react-18.0.10.tgz"
@ -2617,6 +2634,13 @@ css-blank-pseudo@^3.0.3:
dependencies: dependencies:
postcss-selector-parser "^6.0.9" postcss-selector-parser "^6.0.9"
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-functions-list@^3.1.0: css-functions-list@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b" resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b"
@ -4474,7 +4498,7 @@ mdn-data@2.0.14:
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
"memoize-one@>=3.1.1 <6": "memoize-one@>=3.1.1 <6", memoize-one@^5.1.1:
version "5.2.1" version "5.2.1"
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
@ -5400,6 +5424,11 @@ quick-lru@^4.0.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
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==
randombytes@^2.1.0: randombytes@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
@ -5407,6 +5436,19 @@ randombytes@^2.1.0:
dependencies: dependencies:
safe-buffer "^5.1.0" safe-buffer "^5.1.0"
react-beautiful-dnd@^13.1.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz#ec97c81093593526454b0de69852ae433783844d"
integrity sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA==
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-dom@^17.0.0: react-dom@^17.0.0:
version "17.0.2" version "17.0.2"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
@ -5442,6 +5484,23 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
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.8"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de"
integrity sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==
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-simple-maps@^2.3.0: react-simple-maps@^2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-2.3.0.tgz" resolved "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-2.3.0.tgz"
@ -5546,6 +5605,13 @@ redent@^3.0.0:
indent-string "^4.0.0" indent-string "^4.0.0"
strip-indent "^3.0.0" strip-indent "^3.0.0"
redux@^4.0.0, redux@^4.0.4:
version "4.2.0"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
dependencies:
"@babel/runtime" "^7.9.2"
regenerate-unicode-properties@^10.0.1: regenerate-unicode-properties@^10.0.1:
version "10.0.1" version "10.0.1"
resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz"
@ -6319,6 +6385,11 @@ timezone-support@^2.0.2:
dependencies: dependencies:
commander "2.20.0" commander "2.20.0"
tiny-invariant@^1.0.6:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
tiny-lru@8.0.2: tiny-lru@8.0.2:
version "8.0.2" version "8.0.2"
resolved "https://registry.npmjs.org/tiny-lru/-/tiny-lru-8.0.2.tgz" resolved "https://registry.npmjs.org/tiny-lru/-/tiny-lru-8.0.2.tgz"
@ -6527,6 +6598,11 @@ uri-js@^4.2.2:
dependencies: dependencies:
punycode "^2.1.0" punycode "^2.1.0"
use-memo-one@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20"
integrity sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==
use-sync-external-store@1.1.0: use-sync-external-store@1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82"