From 3cfb87a7532571740ec94868ff2074d633865d01 Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Mon, 11 Mar 2024 16:31:16 +0100 Subject: [PATCH 01/20] [#453] Storybook update --- govtool/frontend/.storybook/preview.tsx | 48 ++++++++------ .../src/stories/DashboardCard.stories.ts | 17 +++-- .../src/stories/DashboardTopNav.stories.ts | 16 +---- .../stories/DelegateActionRadio.stories.ts | 16 +++++ .../frontend/src/stories/Input.stories.tsx | 5 ++ .../src/stories/LinkWithIcon.stories.tsx | 26 ++++++++ .../src/stories/LoadingButton.stories.tsx | 31 ++++++++++ govtool/frontend/src/stories/Step.stories.tsx | 62 +++++++++++++++++++ .../frontend/src/stories/TextArea.stories.tsx | 42 +++++++++++++ .../modals/ExternalLinkModal.stories.tsx | 30 ++++----- .../stories/modals/StatusModal.stories.tsx | 32 +++++----- .../stories/modals/StatusWithLink.stories.tsx | 32 +++++----- .../modals/VotingPowerModal.stories.tsx | 56 +++++++++++++++++ 13 files changed, 325 insertions(+), 88 deletions(-) create mode 100644 govtool/frontend/src/stories/LinkWithIcon.stories.tsx create mode 100644 govtool/frontend/src/stories/LoadingButton.stories.tsx create mode 100644 govtool/frontend/src/stories/Step.stories.tsx create mode 100644 govtool/frontend/src/stories/TextArea.stories.tsx create mode 100644 govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx diff --git a/govtool/frontend/.storybook/preview.tsx b/govtool/frontend/.storybook/preview.tsx index f3deaefc6..406ac7970 100644 --- a/govtool/frontend/.storybook/preview.tsx +++ b/govtool/frontend/.storybook/preview.tsx @@ -1,8 +1,12 @@ +import React from "react"; import type { Preview } from "@storybook/react"; import { ThemeProvider } from "@emotion/react"; import { theme } from "../src/theme"; import { MemoryRouter, Routes, Route } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "react-query"; +import { I18nextProvider } from "react-i18next"; +import i18n from "../src/i18n"; +import { ModalProvider } from "../src/context/modal"; const queryClient = new QueryClient(); @@ -19,26 +23,30 @@ const preview: Preview = { decorators: [ (Story) => ( - - - - - - - } - /> - - - + + + + + + + + + } + /> + + + + + ), ], diff --git a/govtool/frontend/src/stories/DashboardCard.stories.ts b/govtool/frontend/src/stories/DashboardCard.stories.ts index 21bac97e4..fc47278eb 100644 --- a/govtool/frontend/src/stories/DashboardCard.stories.ts +++ b/govtool/frontend/src/stories/DashboardCard.stories.ts @@ -21,9 +21,7 @@ export const DashboardCardComponent: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", }, @@ -38,13 +36,22 @@ export const DashboardCardComponent: Story = { }, }; +export const WithDRepIdDashboardCardComponent: Story = { + args: { + description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", + firstButtonLabel: "first button", + imageURL: IMAGES.govActionDelegateImage, + secondButtonLabel: "second button", + title: "Action card", + cardId: "drep1gwsw9ckkhuwscj9savt5f7u9xsrudw209hne7pggcktzuw5sv32", + }, +}; + export const isLoadingDashboardCard: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", isLoading: true, @@ -62,9 +69,7 @@ export const isProgressDashboardCard: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", inProgress: true, diff --git a/govtool/frontend/src/stories/DashboardTopNav.stories.ts b/govtool/frontend/src/stories/DashboardTopNav.stories.ts index 06508f3aa..3ecbb15b7 100644 --- a/govtool/frontend/src/stories/DashboardTopNav.stories.ts +++ b/govtool/frontend/src/stories/DashboardTopNav.stories.ts @@ -1,7 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; import { DashboardTopNav } from "@organisms"; -import { IMAGES } from "@/consts"; import { within, userEvent, waitFor, screen } from "@storybook/testing-library"; import { expect } from "@storybook/jest"; @@ -15,7 +14,7 @@ export default meta; type Story = StoryObj; export const DashboardTopNavComponent: Story = { - args: { title: "Example title", isDrawer: true }, + args: { title: "Example title" }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); expect(canvas.getByText("Example title")).toBeInTheDocument(); @@ -31,16 +30,3 @@ export const DashboardTopNavComponent: Story = { }); }, }; - -export const DashboardTopNavWithIcon: Story = { - args: { - title: "Example title", - isDrawer: true, - imageSRC: IMAGES.appLogoWithoutText, - imageHeight: 24, - }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - expect(canvas.getByRole("img")).toBeInTheDocument(); - }, -}; diff --git a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts index a05563d28..49c24295c 100644 --- a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts +++ b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts @@ -68,3 +68,19 @@ export const ActionRadioActive: Story = { ); }, }; + +export const ActionRadioOnlyTitle: Story = { + args: { + title: "Title", + value: "", + isChecked: false, + }, +}; + +export const ActionRadioOnlyTitleChecked: Story = { + args: { + title: "Title", + value: "", + isChecked: true, + }, +}; diff --git a/govtool/frontend/src/stories/Input.stories.tsx b/govtool/frontend/src/stories/Input.stories.tsx index cbe95a400..95a134c60 100644 --- a/govtool/frontend/src/stories/Input.stories.tsx +++ b/govtool/frontend/src/stories/Input.stories.tsx @@ -60,3 +60,8 @@ ErrorAndLabel.play = async ({ canvasElement }) => { expect(canvas.getByText("Label")).toBeInTheDocument(); expect(canvas.getByTestId("error-message-error")).toBeInTheDocument(); }; + +export const WithHelpfulText = Template.bind({}); +WithHelpfulText.args = { + helpfulText: "Helpful text", +}; diff --git a/govtool/frontend/src/stories/LinkWithIcon.stories.tsx b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx new file mode 100644 index 000000000..83e533f25 --- /dev/null +++ b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx @@ -0,0 +1,26 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { LinkWithIcon } from "@molecules"; +import { ICONS } from "@consts"; + +const meta: Meta = { + title: "Example/LinkWithIcon", + component: LinkWithIcon, + parameters: { + layout: "centered", + }, +}; + +export default meta; + +export const Default: StoryObj = { + args: { + label: "Default Link", + }, +}; + +export const WithCustomIcon: StoryObj = { + args: { + label: "Custom Icon Link", + icon: , + }, +}; diff --git a/govtool/frontend/src/stories/LoadingButton.stories.tsx b/govtool/frontend/src/stories/LoadingButton.stories.tsx new file mode 100644 index 000000000..935014cd1 --- /dev/null +++ b/govtool/frontend/src/stories/LoadingButton.stories.tsx @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { LoadingButton } from "@atoms"; + +const meta = { + title: "Example/LoadingButton", + component: LoadingButton, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + children: "Button", + variant: "contained", + isLoading: false, + }, +}; + +export const Loading: Story = { + args: { + children: "Button", + variant: "contained", + isLoading: true, + }, +}; diff --git a/govtool/frontend/src/stories/Step.stories.tsx b/govtool/frontend/src/stories/Step.stories.tsx new file mode 100644 index 000000000..aecebae56 --- /dev/null +++ b/govtool/frontend/src/stories/Step.stories.tsx @@ -0,0 +1,62 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { Button } from "@atoms"; +import OpenInNewIcon from "@mui/icons-material/OpenInNew"; + +import { Field, Step } from "@molecules"; + +const meta: Meta = { + title: "Example/Step", + component: Step, + parameters: { + layout: "centered", + }, +}; + +export default meta; + +export const WithButton: StoryObj = { + args: { + label: "Download this file", + stepNumber: 1, + component: ( + + ), + }, +}; + +export const WithIconButton: StoryObj = { + args: { + label: + "Save this file in a location that provides a public URL (ex. github)", + stepNumber: 2, + component: ( + + ), + }, +}; + +export const WithInput: StoryObj = { + args: { + label: + "Save this file in a location that provides a public URL (ex. github)", + stepNumber: 2, + component: , + }, +}; diff --git a/govtool/frontend/src/stories/TextArea.stories.tsx b/govtool/frontend/src/stories/TextArea.stories.tsx new file mode 100644 index 000000000..8f6cc178b --- /dev/null +++ b/govtool/frontend/src/stories/TextArea.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryFn } from "@storybook/react"; + +import { Field } from "@molecules"; +import { ComponentProps } from "react"; + +const meta: Meta = { + title: "Example/TextArea", + component: Field.TextArea, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], +}; + +export default meta; + +const Template: StoryFn> = (args) => { + return ; +}; + +export const Default = Template.bind({}); + +export const WithLabel = Template.bind({}); +WithLabel.args = { + label: "Label", +}; + +export const WithHelpfulText = Template.bind({}); +WithHelpfulText.args = { + helpfulText: "Helpful text here", +}; + +export const Error = Template.bind({}); +Error.args = { + errorMessage: "Error message", +}; + +export const ErrorAndLabel = Template.bind({}); +ErrorAndLabel.args = { + errorMessage: "Error message", + label: "Label", +}; diff --git a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx index dc2df8b5d..236943ac5 100644 --- a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx @@ -1,28 +1,22 @@ -import { ComponentProps, useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { useEffect } from "react"; +import { Meta, StoryFn } from "@storybook/react"; import { Modal } from "@atoms"; import { ExternalLinkModal, ExternalLinkModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; +import { useModal } from "../../context/modal"; import { userEvent, within, screen, waitFor } from "@storybook/testing-library"; import { expect, jest } from "@storybook/jest"; +import { callAll } from "@/utils"; const meta = { title: "Example/Modals/ExternalLinkModal", component: ExternalLinkModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals } = useModal(); const open = () => { openModal({ @@ -40,12 +34,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx index 24bb364b1..d7c0b56ce 100644 --- a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx @@ -1,22 +1,16 @@ import { useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; +import { expect } from "@storybook/jest"; +import { within, waitFor, screen, userEvent } from "@storybook/testing-library"; import { Modal } from "@atoms"; import { StatusModal, StatusModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; -import { within, waitFor, screen, userEvent } from "@storybook/testing-library"; -import { expect } from "@storybook/jest"; +import { useModal } from "../../context/modal"; +import { callAll } from "@utils"; const meta = { title: "Example/Modals/StatusModal", component: StatusModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; @@ -40,7 +34,7 @@ const performCommonAction = async (canvas: any, args: any) => { }); }; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals, closeModal } = useModal(); const open = () => { openModal({ @@ -67,12 +61,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx index e331a14bb..1181fb143 100644 --- a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx @@ -1,28 +1,22 @@ import { useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; +import { expect, jest } from "@storybook/jest"; +import { userEvent, waitFor, within, screen } from "@storybook/testing-library"; import { Modal } from "@atoms"; import { StatusModal, StatusModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; -import { userEvent, waitFor, within, screen } from "@storybook/testing-library"; -import { expect, jest } from "@storybook/jest"; +import { useModal } from "../../context/modal"; +import { callAll } from "@utils"; const meta = { title: "Example/Modals/StatusModalWithLink", component: StatusModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals, closeModal } = useModal(); const open = () => { openModal({ @@ -48,12 +42,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx new file mode 100644 index 000000000..5820c9bb3 --- /dev/null +++ b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx @@ -0,0 +1,56 @@ +import { Meta, StoryFn } from "@storybook/react"; + +import { Modal } from "@atoms"; +import { StatusModal, VotingPowerModalState } from "@organisms"; +import { useModal } from "@context"; +import { callAll } from "@utils"; + +const meta = { + title: "Example/Modals/VotingPowerModal", + component: StatusModal, +} satisfies Meta; + +export default meta; + +const Template: StoryFn = (args) => { + const { openModal, modal, modals } = useModal(); + + const open = () => { + openModal({ + type: "votingPower", + state: { + ...args, + }, + }); + }; + + return ( + <> + + {modals[modal.type]?.component && ( + + openModal({ type: "none", state: null }) + ) + : undefined + } + > + {modals[modal.type]?.component ?? <>} + + )} + + ); +}; + +export const Default = Template.bind({}); +Default.args = { + yesVotes: 1000000000000, + noVotes: 10000000000, + abstainVotes: 324000000, + vote: "yes", +}; From 2cc923c6e37974130cffd20b79a8213b9bdda96a Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Wed, 13 Mar 2024 13:21:16 +0100 Subject: [PATCH 02/20] [#453] Fixes after CR --- govtool/frontend/src/stories/Input.stories.tsx | 7 +++++++ govtool/frontend/src/stories/TextArea.stories.tsx | 7 +++++++ .../src/stories/modals/ExternalLinkModal.stories.tsx | 10 +++------- .../src/stories/modals/StatusModal.stories.tsx | 10 +++------- .../src/stories/modals/StatusWithLink.stories.tsx | 10 +++------- .../src/stories/modals/VotingPowerModal.stories.tsx | 10 +++------- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/govtool/frontend/src/stories/Input.stories.tsx b/govtool/frontend/src/stories/Input.stories.tsx index 95a134c60..e863f036b 100644 --- a/govtool/frontend/src/stories/Input.stories.tsx +++ b/govtool/frontend/src/stories/Input.stories.tsx @@ -65,3 +65,10 @@ export const WithHelpfulText = Template.bind({}); WithHelpfulText.args = { helpfulText: "Helpful text", }; + +export const WithAllProps = Template.bind({}); +WithAllProps.args = { + label: "Label", + helpfulText: "Helpful text", + errorMessage: "Error message", +}; diff --git a/govtool/frontend/src/stories/TextArea.stories.tsx b/govtool/frontend/src/stories/TextArea.stories.tsx index 8f6cc178b..c378c6749 100644 --- a/govtool/frontend/src/stories/TextArea.stories.tsx +++ b/govtool/frontend/src/stories/TextArea.stories.tsx @@ -40,3 +40,10 @@ ErrorAndLabel.args = { errorMessage: "Error message", label: "Label", }; + +export const WithAllProps = Template.bind({}); +WithAllProps.args = { + label: "Label", + helpfulText: "Helpful text", + errorMessage: "Error message", +}; diff --git a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx index 236943ac5..05ac4c018 100644 --- a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx @@ -37,13 +37,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx index d7c0b56ce..c8474d741 100644 --- a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx @@ -64,13 +64,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx index 1181fb143..8c8ca391b 100644 --- a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx @@ -45,13 +45,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx index 5820c9bb3..fbca8d633 100644 --- a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx @@ -32,13 +32,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} From 575bba2d481cfa62255a826a22189368b2bfea9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Placzy=C5=84ski?= Date: Wed, 13 Mar 2024 14:03:44 +0100 Subject: [PATCH 03/20] Introduce frontend image build environment tag To ensure frontend image builds can distinguish between different environments, an additional distinction based on the environment tag has been introduced. This change was necessary as the commit altering the frontend module alone was insufficient. By adding an environment tag to the image tag name, applications with the same version can now be uniquely identified across various environments. Changes Made: - Modified the Makefile in the govtool/frontend directory to introduce an environment tag to the image tag name used in frontend image builds. The new tag is generated by appending the environment variable to the commit hash obtained from the git log command, ensuring each build is uniquely identified per environment. --- govtool/frontend/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/govtool/frontend/Makefile b/govtool/frontend/Makefile index 2721792b7..24f0702dc 100644 --- a/govtool/frontend/Makefile +++ b/govtool/frontend/Makefile @@ -7,7 +7,7 @@ endif .DEFAULT_GOAL := push-frontend # image tags -frontend_image_tag := $(shell git log -n 1 --format="%H" -- $(root_dir)/govtool/frontend) +frontend_image_tag := $(shell git log -n 1 --format="%H" -- $(root_dir)/govtool/frontend)-$(env) .PHONY: build-frontend build-frontend: docker-login From ffed96f2cb5a119dd6030cf12bd11441702df977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 12 Mar 2024 19:09:14 +0100 Subject: [PATCH 04/20] [#378] feat: add hash and validation of the metadata --- CHANGELOG.md | 3 +- govtool/frontend/package.json | 1 + .../CreateGovernanceActionForm.tsx | 8 +- .../StorageInformation.tsx | 103 +++++++++++++++++- .../src/components/organisms/StatusModal.tsx | 46 +++++++- .../src/consts/governanceActionFields.ts | 23 ++-- govtool/frontend/src/context/modal.tsx | 2 +- govtool/frontend/src/i18n/locales/en.ts | 19 ++++ govtool/frontend/src/utils/canonizeJSON.ts | 12 ++ govtool/frontend/src/utils/index.ts | 2 + .../src/utils/validateMetadataHash.ts | 61 +++++++++++ 11 files changed, 254 insertions(+), 26 deletions(-) create mode 100644 govtool/frontend/src/utils/canonizeJSON.ts create mode 100644 govtool/frontend/src/utils/validateMetadataHash.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index a89f944c1..2cb0840cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,8 @@ changes. - Create GA creation form [Issue 360](https://github.com/IntersectMBO/govtool/issues/360) - Create TextArea [Issue 110](https://github.com/IntersectMBO/govtool/issues/110) - Choose GA type - GA Submiter [Issue 358](https://github.com/IntersectMBO/govtool/issues/358) - - Add on-chain inputs validation [Issue 377](https://github.com/IntersectMBO/govtool/issues/377) +- Add hash and validation of the metadata [Issue 378](https://github.com/IntersectMBO/govtool/issues/378) ### Added @@ -44,6 +44,7 @@ changes. - Fixed CSP settings to allow error reports with Sentry [Issue 291](https://github.com/IntersectMBO/govtool/issues/291). ### Changed + - `drep/list` now return also `status` and `type` fields. Also it now returns the retired dreps, and you can search for given drep by name using optional query parameter. If the drep name is passed exactly, then you can even find a drep that's sole voter. [Issue 446](https://github.com/IntersectMBO/govtool/issues/446) - `drep/list` and `drep/info` endpoints now return additional data such as metadata url and hash, and voting power [Issue 223](https://github.com/IntersectMBO/govtool/issues/223) - `drep/info` now does not return sole voters (dreps without metadata) [Issue 317](https://github.com/IntersectMBO/govtool/issues/317) diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index b6ca5e643..8ce160dd4 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -22,6 +22,7 @@ "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@sentry/react": "^7.77.0", + "@types/jsonld": "^1.5.13", "@types/react": "^18.2.12", "@types/react-gtm-module": "^2.0.2", "axios": "^1.4.0", diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/CreateGovernanceActionForm.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/CreateGovernanceActionForm.tsx index 0d49018e5..ca96904e6 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/CreateGovernanceActionForm.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/CreateGovernanceActionForm.tsx @@ -6,11 +6,11 @@ import { Button, InfoText, Spacer, Typography } from "@atoms"; import { GOVERNANCE_ACTION_FIELDS } from "@consts"; import { useCreateGovernanceActionForm, useTranslation } from "@hooks"; import { Field } from "@molecules"; +import { URL_REGEX } from "@/utils"; +import { GovernanceActionField } from "@/types/governanceAction"; import { BgCard } from "../BgCard"; import { ControlledField } from "../ControlledField"; -import { GovernanceActionField } from "@/types/governanceAction"; -import { URL_REGEX } from "@/utils"; const LINK_PLACEHOLDER = "https://website.com/"; const MAX_NUMBER_OF_LINKS = 8; @@ -117,10 +117,6 @@ export const CreateGovernanceActionForm = ({ placeholder={LINK_PLACEHOLDER} name={`links.${index}.link`} rules={{ - required: { - value: true, - message: t("createGovernanceAction.fields.validations.required"), - }, pattern: { value: URL_REGEX, message: t("createGovernanceAction.fields.validations.url"), diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx index dd1840868..e899a0db9 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx @@ -1,20 +1,85 @@ import { Dispatch, SetStateAction, useCallback, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { Box } from "@mui/material"; import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import { Button, Spacer, Typography } from "@atoms"; -import { ICONS } from "@consts"; +import { ICONS, PATHS } from "@consts"; import { useCreateGovernanceActionForm, useTranslation } from "@hooks"; import { Step } from "@molecules"; -import { BgCard, ControlledField } from "@organisms"; -import { URL_REGEX, downloadJson, openInNewTab } from "@utils"; +import { BgCard, ControlledField, StatusModalState } from "@organisms"; +import { + URL_REGEX, + downloadJson, + openInNewTab, + validateMetadataHash, + MetadataHashValidationErrors, +} from "@utils"; +import { ModalState, useModal } from "@/context"; +import I18n from "@/i18n"; type StorageInformationProps = { setStep: Dispatch>; }; +const externalDataDoesntMatchModal = { + type: "statusModal", + state: { + status: "warning", + title: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.title" + ), + message: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.message" + ), + buttonText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.buttonText" + ), + cancelText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.cancelRegistrationText" + ), + feedbackText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.feedbackText" + ), + }, +} as const; + +const urlCannotBeFound = { + type: "statusModal", + state: { + status: "warning", + title: I18n.t("createGovernanceAction.modals.urlCannotBeFound.title"), + message: I18n.t("createGovernanceAction.modals.urlCannotBeFound.message"), + link: "https://docs.sanchogov.tools", + linkText: I18n.t("createGovernanceAction.modals.urlCannotBeFound.linkText"), + buttonText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.buttonText" + ), + cancelText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.cancelRegistrationText" + ), + feedbackText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.feedbackText" + ), + }, +} as const; + +const storageInformationErrorModals: Record< + MetadataHashValidationErrors, + ModalState< + | (typeof externalDataDoesntMatchModal)["state"] + | (typeof urlCannotBeFound)["state"] + > +> = { + [MetadataHashValidationErrors.INVALID_URL]: urlCannotBeFound, + [MetadataHashValidationErrors.FETCH_ERROR]: urlCannotBeFound, + [MetadataHashValidationErrors.INVALID_JSON]: externalDataDoesntMatchModal, + [MetadataHashValidationErrors.INVALID_HASH]: externalDataDoesntMatchModal, +}; + export const StorageInformation = ({ setStep }: StorageInformationProps) => { const { t } = useTranslation(); + const navigate = useNavigate(); const { control, errors, @@ -23,6 +88,7 @@ export const StorageInformation = ({ setStep }: StorageInformationProps) => { getValues, watch, } = useCreateGovernanceActionForm(); + const { openModal, closeModal } = useModal(); const [isJsonDownloaded, setIsJsonDownloaded] = useState(false); // TODO: change on correct file name @@ -45,12 +111,41 @@ export const StorageInformation = ({ setStep }: StorageInformationProps) => { setIsJsonDownloaded(true); }; + const backToDashboard = () => { + navigate(PATHS.dashboard); + closeModal(); + }; + + const handleStoringURLJSONValidation = useCallback(async () => { + const storingURL = getValues("storingURL"); + try { + await createGovernanceAction(); + + // TODO: To be replaced wtih the correct hash + await validateMetadataHash(storingURL, "hash"); + } catch (error: any) { + if (Object.values(MetadataHashValidationErrors).includes(error.message)) { + openModal({ + ...storageInformationErrorModals[ + error.message as MetadataHashValidationErrors + ], + onSubmit: () => { + setStep(3); + }, + onCancel: backToDashboard, + // TODO: Open usersnap feedback + onFeedback: backToDashboard, + } as ModalState); + } + } + }, [getValues, generateJsonBody]); + return ( diff --git a/govtool/frontend/src/components/organisms/StatusModal.tsx b/govtool/frontend/src/components/organisms/StatusModal.tsx index 35b24ef4a..0a6ec6c66 100644 --- a/govtool/frontend/src/components/organisms/StatusModal.tsx +++ b/govtool/frontend/src/components/organisms/StatusModal.tsx @@ -8,11 +8,16 @@ import { useScreenDimension, useTranslation } from "@/hooks"; export interface StatusModalState { buttonText?: string; + cancelText?: string; + feedbackText?: string; status: "warning" | "info" | "success"; isInfo?: boolean; link?: string; + linkText?: string; message: React.ReactNode; onSubmit?: () => void; + onCancel?: () => void; + onFeedback?: () => void; title: string; dataTestId: string; } @@ -43,20 +48,20 @@ export function StatusModal() { textAlign="center" sx={{ fontSize: "16px", fontWeight: "400" }} > - {state?.message}{" "} + {state?.message} {state?.link && ( openInNewTab(state?.link || "")} target="_blank" sx={[{ "&:hover": { cursor: "pointer" } }]} > - {t("thisLink")} + {state?.linkText || t("thisLink")} )} + {state?.cancelText && ( + + )} + {state?.feedbackText && ( + + )} ); } diff --git a/govtool/frontend/src/consts/governanceActionFields.ts b/govtool/frontend/src/consts/governanceActionFields.ts index e5663758b..f96e7fb16 100644 --- a/govtool/frontend/src/consts/governanceActionFields.ts +++ b/govtool/frontend/src/consts/governanceActionFields.ts @@ -95,10 +95,15 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = { placeholderI18nKey: "createGovernanceAction.fields.declarations.receivingAddress.placeholder", rules: { - validate: (value) => { - if (bech32.decode(value).words.length) { - return true; - } else { + validate: async (value) => { + try { + const decoded = await bech32.decode(value); + if (decoded.words.length) { + return true; + } else { + throw new Error(); + } + } catch (error) { return I18n.t("createGovernanceAction.fields.validations.bech32"); } }, @@ -114,13 +119,9 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = { value: true, message: I18n.t("createGovernanceAction.fields.validations.required"), }, - validate: (value) => { - if (Number.isInteger(Number(value))) { - return true; - } else { - return I18n.t("createGovernanceAction.fields.validations.number"); - } - }, + validate: (value) => + Number.isInteger(Number(value)) || + I18n.t("createGovernanceAction.fields.validations.number"), }, }, }, diff --git a/govtool/frontend/src/context/modal.tsx b/govtool/frontend/src/context/modal.tsx index 4d6afdf0a..985910fde 100644 --- a/govtool/frontend/src/context/modal.tsx +++ b/govtool/frontend/src/context/modal.tsx @@ -47,7 +47,7 @@ const modals: Record = { type Optional = Pick, K> & Omit; -interface ModalState { +export interface ModalState { type: ModalType; state: T | null; } diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index edc1e2be7..904bcc045 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -191,6 +191,25 @@ export const en = { url: "Invalid URL", }, }, + modals: { + externalDataDoesntMatch: { + title: "Your External Data Does Not Match the Original File.", + message: + "GovTool checks the URL you entered to see if the JSON file that you self-host matches the one that was generated in GovTool. To complete registration, this match must be exact.\n\nIn this case, there is a mismatch. You can go back to the data edit screen and try the process again.", + buttonText: "Go to Data Edit Screen", + cancelRegistrationText: "Cancel Registration", + feedbackText: "Feedback", + }, + urlCannotBeFound: { + title: "The URL You Entered Cannot Be Found", + message: + "GovTool cannot find the URL that you entered. Please check it and re-enter.", + linkText: "Learn More about self-hosting", + buttonText: "Go to Data Edit Screen", + cancelRegistrationText: "Cancel Registration", + feedbackText: "Feedback", + }, + }, }, delegation: { description: diff --git a/govtool/frontend/src/utils/canonizeJSON.ts b/govtool/frontend/src/utils/canonizeJSON.ts new file mode 100644 index 000000000..72f884708 --- /dev/null +++ b/govtool/frontend/src/utils/canonizeJSON.ts @@ -0,0 +1,12 @@ +import jsonld from "jsonld"; + +/** + * Canonizes a JSON object using jsonld.canonize. + * + * @param json - The JSON object to be canonized. + * @returns A Promise that resolves to the canonized JSON object. + */ +export const canonizeJSON = async (json: Record) => { + const canonized = await jsonld.canonize(json); + return canonized; +}; diff --git a/govtool/frontend/src/utils/index.ts b/govtool/frontend/src/utils/index.ts index 313353de7..6a738852d 100644 --- a/govtool/frontend/src/utils/index.ts +++ b/govtool/frontend/src/utils/index.ts @@ -1,6 +1,7 @@ export * from "./adaFormat"; export * from "./basicReducer"; export * from "./callAll"; +export * from "./canonizeJSON"; export * from "./checkIsMaintenanceOn"; export * from "./checkIsWalletConnected"; export * from "./formatDate"; @@ -14,3 +15,4 @@ export * from "./jsonUtils"; export * from "./localStorage"; export * from "./openInNewTab"; export * from "./removeDuplicatedProposals"; +export * from "./validateMetadataHash"; diff --git a/govtool/frontend/src/utils/validateMetadataHash.ts b/govtool/frontend/src/utils/validateMetadataHash.ts new file mode 100644 index 000000000..b35f23e71 --- /dev/null +++ b/govtool/frontend/src/utils/validateMetadataHash.ts @@ -0,0 +1,61 @@ +import * as blake from "blakejs"; +import { isAxiosError } from "axios"; + +import { API } from "@/services"; + +import { canonizeJSON } from "./canonizeJSON"; +import { URL_REGEX } from "."; + +export enum MetadataHashValidationErrors { + INVALID_URL = "Invalid URL", + INVALID_JSON = "Invalid JSON", + INVALID_HASH = "Invalid hash", + FETCH_ERROR = "Error fetching data", +} + +/** + * Validates the metadata hash by fetching the metadata from the given URL, + * canonizing it, and comparing the hash with the provided hash. + * + * @param storingURL - The URL where the metadata is stored. + * @param hash - The hash to compare with the calculated hash of the metadata. + * @returns A promise that resolves to `true` if the metadata hash is valid, or rejects with an error message if validation fails. + */ +export const validateMetadataHash = async ( + storingURL: string, + hash: string +) => { + try { + if (!storingURL.match(URL_REGEX)) { + throw new Error(MetadataHashValidationErrors.INVALID_URL); + } + + const { data: userMetadataJSON } = await API.get(storingURL); + + let canonizedUserMetadata; + try { + canonizedUserMetadata = await canonizeJSON(userMetadataJSON); + } catch (error) { + throw new Error(MetadataHashValidationErrors.INVALID_JSON); + } + if (!canonizedUserMetadata) { + throw new Error(MetadataHashValidationErrors.INVALID_JSON); + } + + const hashedUserMetadata = blake.blake2bHex( + canonizedUserMetadata, + undefined, + 32 + ); + + if (hashedUserMetadata !== hash) { + throw new Error(MetadataHashValidationErrors.INVALID_HASH); + } + return true; + } catch (error) { + if (isAxiosError(error)) { + throw new Error(MetadataHashValidationErrors.FETCH_ERROR); + } + throw error; + } +}; From 854d91585af5d5121de6b16b16948d0405f22b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 13 Mar 2024 11:49:33 +0100 Subject: [PATCH 05/20] [#378] feat: create gov action transaction builder & submit --- .../StorageInformation.tsx | 121 +-- .../fields.ts} | 17 +- .../filters.ts} | 0 .../src/consts/governanceAction/index.ts | 5 + .../metadataHashValidationErrors.ts | 6 + .../consts/governanceAction/modalConfig.ts | 50 + .../sorting.ts} | 0 govtool/frontend/src/consts/index.ts | 4 +- govtool/frontend/src/context/wallet.tsx | 8 + .../forms/useCreateGovernanceActionForm.ts | 202 +++- govtool/frontend/src/i18n/locales/en.ts | 5 + .../frontend/src/types/governanceAction.ts | 3 +- govtool/frontend/src/utils/generateJsonld.ts | 30 + govtool/frontend/src/utils/index.ts | 1 + .../src/utils/validateMetadataHash.ts | 8 +- govtool/frontend/yarn.lock | 995 +++++++++++------- 16 files changed, 885 insertions(+), 570 deletions(-) rename govtool/frontend/src/consts/{governanceActionFields.ts => governanceAction/fields.ts} (93%) rename govtool/frontend/src/consts/{governanceActionsFilters.ts => governanceAction/filters.ts} (100%) create mode 100644 govtool/frontend/src/consts/governanceAction/index.ts create mode 100644 govtool/frontend/src/consts/governanceAction/metadataHashValidationErrors.ts create mode 100644 govtool/frontend/src/consts/governanceAction/modalConfig.ts rename govtool/frontend/src/consts/{governanceActionsSorting.ts => governanceAction/sorting.ts} (100%) create mode 100644 govtool/frontend/src/utils/generateJsonld.ts diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx index e899a0db9..3dbd72485 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/StorageInformation.tsx @@ -1,95 +1,29 @@ -import { Dispatch, SetStateAction, useCallback, useState } from "react"; -import { useNavigate } from "react-router-dom"; +import { Dispatch, SetStateAction, useCallback } from "react"; import { Box } from "@mui/material"; import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import { Button, Spacer, Typography } from "@atoms"; -import { ICONS, PATHS } from "@consts"; +import { ICONS } from "@consts"; import { useCreateGovernanceActionForm, useTranslation } from "@hooks"; import { Step } from "@molecules"; -import { BgCard, ControlledField, StatusModalState } from "@organisms"; -import { - URL_REGEX, - downloadJson, - openInNewTab, - validateMetadataHash, - MetadataHashValidationErrors, -} from "@utils"; -import { ModalState, useModal } from "@/context"; -import I18n from "@/i18n"; +import { BgCard, ControlledField } from "@organisms"; +import { URL_REGEX, openInNewTab } from "@utils"; type StorageInformationProps = { setStep: Dispatch>; }; -const externalDataDoesntMatchModal = { - type: "statusModal", - state: { - status: "warning", - title: I18n.t( - "createGovernanceAction.modals.externalDataDoesntMatch.title" - ), - message: I18n.t( - "createGovernanceAction.modals.externalDataDoesntMatch.message" - ), - buttonText: I18n.t( - "createGovernanceAction.modals.externalDataDoesntMatch.buttonText" - ), - cancelText: I18n.t( - "createGovernanceAction.modals.externalDataDoesntMatch.cancelRegistrationText" - ), - feedbackText: I18n.t( - "createGovernanceAction.modals.externalDataDoesntMatch.feedbackText" - ), - }, -} as const; - -const urlCannotBeFound = { - type: "statusModal", - state: { - status: "warning", - title: I18n.t("createGovernanceAction.modals.urlCannotBeFound.title"), - message: I18n.t("createGovernanceAction.modals.urlCannotBeFound.message"), - link: "https://docs.sanchogov.tools", - linkText: I18n.t("createGovernanceAction.modals.urlCannotBeFound.linkText"), - buttonText: I18n.t( - "createGovernanceAction.modals.urlCannotBeFound.buttonText" - ), - cancelText: I18n.t( - "createGovernanceAction.modals.urlCannotBeFound.cancelRegistrationText" - ), - feedbackText: I18n.t( - "createGovernanceAction.modals.urlCannotBeFound.feedbackText" - ), - }, -} as const; - -const storageInformationErrorModals: Record< - MetadataHashValidationErrors, - ModalState< - | (typeof externalDataDoesntMatchModal)["state"] - | (typeof urlCannotBeFound)["state"] - > -> = { - [MetadataHashValidationErrors.INVALID_URL]: urlCannotBeFound, - [MetadataHashValidationErrors.FETCH_ERROR]: urlCannotBeFound, - [MetadataHashValidationErrors.INVALID_JSON]: externalDataDoesntMatchModal, - [MetadataHashValidationErrors.INVALID_HASH]: externalDataDoesntMatchModal, -}; - export const StorageInformation = ({ setStep }: StorageInformationProps) => { const { t } = useTranslation(); - const navigate = useNavigate(); const { control, errors, createGovernanceAction, - generateJsonBody, getValues, watch, - } = useCreateGovernanceActionForm(); - const { openModal, closeModal } = useModal(); - const [isJsonDownloaded, setIsJsonDownloaded] = useState(false); + onClickDownloadJson, + isLoading, + } = useCreateGovernanceActionForm(setStep); // TODO: change on correct file name const fileName = getValues("governance_action_type"); @@ -100,53 +34,18 @@ export const StorageInformation = ({ setStep }: StorageInformationProps) => { [] ); - const isActionButtonDisabled = !watch("storingURL") || !isJsonDownloaded; + const isActionButtonDisabled = !watch("storingURL"); const onClickBack = useCallback(() => setStep(5), []); - const onClickDownloadJson = async () => { - const data = getValues(); - const jsonBody = await generateJsonBody(data); - downloadJson(jsonBody, fileName); - setIsJsonDownloaded(true); - }; - - const backToDashboard = () => { - navigate(PATHS.dashboard); - closeModal(); - }; - - const handleStoringURLJSONValidation = useCallback(async () => { - const storingURL = getValues("storingURL"); - try { - await createGovernanceAction(); - - // TODO: To be replaced wtih the correct hash - await validateMetadataHash(storingURL, "hash"); - } catch (error: any) { - if (Object.values(MetadataHashValidationErrors).includes(error.message)) { - openModal({ - ...storageInformationErrorModals[ - error.message as MetadataHashValidationErrors - ], - onSubmit: () => { - setStep(3); - }, - onCancel: backToDashboard, - // TODO: Open usersnap feedback - onFeedback: backToDashboard, - } as ModalState); - } - } - }, [getValues, generateJsonBody]); - return ( {t("createGovernanceAction.storingInformationTitle")} diff --git a/govtool/frontend/src/consts/governanceActionFields.ts b/govtool/frontend/src/consts/governanceAction/fields.ts similarity index 93% rename from govtool/frontend/src/consts/governanceActionFields.ts rename to govtool/frontend/src/consts/governanceAction/fields.ts index f96e7fb16..daf66244f 100644 --- a/govtool/frontend/src/consts/governanceActionFields.ts +++ b/govtool/frontend/src/consts/governanceAction/fields.ts @@ -127,7 +127,7 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = { }, } as const; -const commonContext = { +export const GOVERNANCE_ACTION_CONTEXT = { "@language": "en-us", CIP100: "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", @@ -176,18 +176,3 @@ const commonContext = { }, }, }; - -export const GOVERNANCE_ACTION_CONTEXTS = { - [GovernanceActionType.Info]: commonContext, - [GovernanceActionType.Treasury]: { - ...commonContext, - body: { - ...commonContext.body, - "@context": { - ...commonContext.body["@context"], - amount: "CIP108:amount", - receivingAddress: "CIP108:receivingAddress", - }, - }, - }, -}; diff --git a/govtool/frontend/src/consts/governanceActionsFilters.ts b/govtool/frontend/src/consts/governanceAction/filters.ts similarity index 100% rename from govtool/frontend/src/consts/governanceActionsFilters.ts rename to govtool/frontend/src/consts/governanceAction/filters.ts diff --git a/govtool/frontend/src/consts/governanceAction/index.ts b/govtool/frontend/src/consts/governanceAction/index.ts new file mode 100644 index 000000000..288b6cd15 --- /dev/null +++ b/govtool/frontend/src/consts/governanceAction/index.ts @@ -0,0 +1,5 @@ +export * from "./fields"; +export * from "./filters"; +export * from "./sorting"; +export * from "./modalConfig"; +export * from "./metadataHashValidationErrors"; diff --git a/govtool/frontend/src/consts/governanceAction/metadataHashValidationErrors.ts b/govtool/frontend/src/consts/governanceAction/metadataHashValidationErrors.ts new file mode 100644 index 000000000..0d3479ba4 --- /dev/null +++ b/govtool/frontend/src/consts/governanceAction/metadataHashValidationErrors.ts @@ -0,0 +1,6 @@ +export enum MetadataHashValidationErrors { + INVALID_URL = "Invalid URL", + INVALID_JSON = "Invalid JSON", + INVALID_HASH = "Invalid hash", + FETCH_ERROR = "Error fetching data", +} diff --git a/govtool/frontend/src/consts/governanceAction/modalConfig.ts b/govtool/frontend/src/consts/governanceAction/modalConfig.ts new file mode 100644 index 000000000..3cef83aca --- /dev/null +++ b/govtool/frontend/src/consts/governanceAction/modalConfig.ts @@ -0,0 +1,50 @@ +import { ModalState } from "@/context"; +import I18n from "@/i18n"; + +import { MetadataHashValidationErrors } from "./metadataHashValidationErrors"; + +const externalDataDoesntMatchModal = { + status: "warning", + title: I18n.t("createGovernanceAction.modals.externalDataDoesntMatch.title"), + message: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.message" + ), + buttonText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.buttonText" + ), + cancelText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.cancelRegistrationText" + ), + feedbackText: I18n.t( + "createGovernanceAction.modals.externalDataDoesntMatch.feedbackText" + ), +} as const; + +const urlCannotBeFound = { + status: "warning", + title: I18n.t("createGovernanceAction.modals.urlCannotBeFound.title"), + message: I18n.t("createGovernanceAction.modals.urlCannotBeFound.message"), + link: "https://docs.sanchogov.tools", + linkText: I18n.t("createGovernanceAction.modals.urlCannotBeFound.linkText"), + buttonText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.buttonText" + ), + cancelText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.cancelRegistrationText" + ), + feedbackText: I18n.t( + "createGovernanceAction.modals.urlCannotBeFound.feedbackText" + ), +}; + +export const storageInformationErrorModals: Record< + MetadataHashValidationErrors, + ModalState< + typeof externalDataDoesntMatchModal | typeof urlCannotBeFound + >["state"] +> = { + [MetadataHashValidationErrors.INVALID_URL]: urlCannotBeFound, + [MetadataHashValidationErrors.FETCH_ERROR]: urlCannotBeFound, + [MetadataHashValidationErrors.INVALID_JSON]: externalDataDoesntMatchModal, + [MetadataHashValidationErrors.INVALID_HASH]: externalDataDoesntMatchModal, +}; diff --git a/govtool/frontend/src/consts/governanceActionsSorting.ts b/govtool/frontend/src/consts/governanceAction/sorting.ts similarity index 100% rename from govtool/frontend/src/consts/governanceActionsSorting.ts rename to govtool/frontend/src/consts/governanceAction/sorting.ts diff --git a/govtool/frontend/src/consts/index.ts b/govtool/frontend/src/consts/index.ts index 3b8fcac7f..59f68e20a 100644 --- a/govtool/frontend/src/consts/index.ts +++ b/govtool/frontend/src/consts/index.ts @@ -1,7 +1,5 @@ export * from "./colors"; -export * from "./governanceActionFields"; -export * from "./governanceActionsFilters"; -export * from "./governanceActionsSorting"; +export * from "./governanceAction"; export * from "./icons"; export * from "./images"; export * from "./navItems"; diff --git a/govtool/frontend/src/context/wallet.tsx b/govtool/frontend/src/context/wallet.tsx index 2d72d4659..5353294d0 100644 --- a/govtool/frontend/src/context/wallet.tsx +++ b/govtool/frontend/src/context/wallet.tsx @@ -132,11 +132,13 @@ interface CardanoContext { buildSignSubmitConwayCertTx: ({ certBuilder, votingBuilder, + govActionBuilder, type, registrationType, }: { certBuilder?: CertificatesBuilder; votingBuilder?: VotingBuilder; + govActionBuilder?: VotingProposalBuilder; type?: "delegation" | "registration" | "soleVoterRegistration" | "vote"; proposalId?: string; registrationType?: DRepActionType; @@ -823,12 +825,14 @@ function CardanoProvider(props: Props) { async ({ certBuilder, votingBuilder, + govActionBuilder, type, proposalId, registrationType, }: { certBuilder?: CertificatesBuilder; votingBuilder?: VotingBuilder; + govActionBuilder?: VotingProposalBuilder; type?: "delegation" | "registration" | "soleVoterRegistration" | "vote"; proposalId?: string; registrationType?: DRepActionType; @@ -854,6 +858,10 @@ function CardanoProvider(props: Props) { txBuilder.set_voting_builder(votingBuilder); } + if (govActionBuilder) { + txBuilder.set_voting_proposal_builder(govActionBuilder); + } + if ( !walletState.changeAddress || !walletState.usedAddress || diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index 614e3d634..862f4ca27 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -2,12 +2,28 @@ import { GovernanceActionFieldSchemas, GovernanceActionType, } from "@/types/governanceAction"; -import { useCallback, useState } from "react"; +import { Dispatch, SetStateAction, useCallback, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { useFormContext } from "react-hook-form"; +import * as blake from "blakejs"; +import * as Sentry from "@sentry/react"; +import { useTranslation } from "react-i18next"; -import { CIP_100, CIP_108, GOVERNANCE_ACTION_CONTEXTS } from "@consts"; - -import * as jsonld from "jsonld"; +import { + CIP_100, + CIP_108, + GOVERNANCE_ACTION_CONTEXT, + MetadataHashValidationErrors, + PATHS, + storageInformationErrorModals, +} from "@consts"; +import { + canonizeJSON, + downloadJson, + generateJsonld, + validateMetadataHash, +} from "@/utils"; +import { useCardano, useModal } from "@/context"; export type CreateGovernanceActionValues = { links?: { link: string }[]; @@ -23,9 +39,19 @@ export const defaulCreateGovernanceActionValues: CreateGovernanceActionValues = storingURL: "", }; -export const useCreateGovernanceActionForm = () => { +export const useCreateGovernanceActionForm = ( + setStep?: Dispatch> +) => { + const { + buildNewInfoGovernanceAction, + buildTreasuryGovernanceAction, + buildSignSubmitConwayCertTx, + } = useCardano(); + const { t } = useTranslation(); const [isLoading, setIsLoading] = useState(false); - + const [hash, setHash] = useState(null); + const navigate = useNavigate(); + const { openModal, closeModal } = useModal(); const { control, formState: { errors, isValid }, @@ -36,17 +62,27 @@ export const useCreateGovernanceActionForm = () => { register, reset, } = useFormContext(); - const govActionType = watch("governance_action_type"); + const backToForm = useCallback(() => { + setStep?.(3); + closeModal(); + }, [setStep]); + + const backToDashboard = useCallback(() => { + navigate(PATHS.dashboard); + closeModal(); + }, []); + // TODO: To be moved to utils - const generateJsonBody = async (data: CreateGovernanceActionValues) => { + const generateMetadata = async (data: CreateGovernanceActionValues) => { + if (!govActionType) + throw new Error("Governance action type is not defined"); + + const acceptedKeys = ["title", "motivation", "abstract", "rationale"]; + const filteredData = Object.entries(data) - .filter( - ([key]) => - !Object.keys(defaulCreateGovernanceActionValues).includes(key) && - key !== "governance_action_type" - ) + .filter(([key]) => acceptedKeys.includes(key)) .map(([key, value]) => { return [CIP_108 + key, value]; }); @@ -66,32 +102,132 @@ export const useCreateGovernanceActionForm = () => { [`${CIP_108}references`]: references, }; - const doc = { - [`${CIP_108}body`]: body, - [`${CIP_100}hashAlgorithm`]: "blake2b-256", - [`${CIP_100}authors`]: [], - }; + const jsonld = await generateJsonld(body, GOVERNANCE_ACTION_CONTEXT); - const json = await jsonld.compact( - doc, - GOVERNANCE_ACTION_CONTEXTS[govActionType as GovernanceActionType] - ); + const canonizedJson = await canonizeJSON(jsonld); + const hash = blake.blake2bHex(canonizedJson, undefined, 32); - return json; + // That allows to validate metadata hash + setHash(hash); + + return jsonld; }; - const onSubmit = useCallback(async (data: CreateGovernanceActionValues) => { - try { - setIsLoading(true); - const jsonBody = generateJsonBody(data); + const onClickDownloadJson = async () => { + const data = getValues(); + const json = await generateMetadata(data); + + downloadJson(json, govActionType); + }; - return jsonBody; - } catch (e: any) { - } finally { - setIsLoading(false); - } + const validateHash = useCallback( + async (storingUrl: string, hash: string | null) => { + try { + console.log({ hash }); + if (!hash) throw new Error(MetadataHashValidationErrors.INVALID_HASH); + + await validateMetadataHash(storingUrl, hash); + } catch (error: any) { + if ( + Object.values(MetadataHashValidationErrors).includes(error.message) + ) { + openModal({ + type: "statusModal", + state: { + ...storageInformationErrorModals[ + error.message as MetadataHashValidationErrors + ], + onSubmit: backToForm, + onCancel: backToDashboard, + // TODO: Open usersnap feedback + onFeedback: backToDashboard, + }, + }); + } + throw error; + } + }, + [hash, backToForm] + ); + + const buildTransaction = useCallback( + async (data: CreateGovernanceActionValues) => { + if (!hash) return; + + const commonGovActionDetails = { + hash, + url: data.storingURL, + }; + try { + switch (govActionType) { + case GovernanceActionType.Info: + return await buildNewInfoGovernanceAction(commonGovActionDetails); + case GovernanceActionType.Treasury: + if ( + data.amount === undefined || + data.receivingAddress === undefined + ) { + throw new Error("Invalid treasury governance action data"); + } + + const treasuryActionDetails = { + ...commonGovActionDetails, + amount: data.amount, + receivingAddress: data.receivingAddress, + }; + + return await buildTreasuryGovernanceAction(treasuryActionDetails); + default: + throw new Error("Invalid governance action type"); + } + } catch (error: any) { + console.error(error); + throw error; + } + }, + [hash] + ); + + const showSuccessModal = useCallback(() => { + openModal({ + type: "statusModal", + state: { + status: "success", + title: t( + "createGovernanceAction.modals.submitTransactionSuccess.title" + ), + message: t( + "createGovernanceAction.modals.submitTransactionSuccess.message" + ), + buttonText: t("modals.common.goToDashboard"), + dataTestId: "governance-action-submitted-modal", + onSubmit: backToDashboard, + }, + }); }, []); + const onSubmit = useCallback( + async (data: CreateGovernanceActionValues) => { + try { + setIsLoading(true); + + await validateHash(data.storingURL, hash); + const votingProposalBuilder = await buildTransaction(data); + await buildSignSubmitConwayCertTx({ + govActionBuilder: votingProposalBuilder, + }); + + showSuccessModal(); + } catch (error: any) { + Sentry.captureException(error); + console.error(error); + } finally { + setIsLoading(false); + } + }, + [hash] + ); + return { control, errors, @@ -103,6 +239,6 @@ export const useCreateGovernanceActionForm = () => { watch, register, reset, - generateJsonBody, + onClickDownloadJson, }; }; diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 904bcc045..406864207 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -209,6 +209,11 @@ export const en = { cancelRegistrationText: "Cancel Registration", feedbackText: "Feedback", }, + submitTransactionSuccess: { + title: "Governance Action submitted!", + message: + "Your Governance Action may take a little time to submit to the chain.", + }, }, }, delegation: { diff --git a/govtool/frontend/src/types/governanceAction.ts b/govtool/frontend/src/types/governanceAction.ts index 5fd0b13eb..0d20ef88d 100644 --- a/govtool/frontend/src/types/governanceAction.ts +++ b/govtool/frontend/src/types/governanceAction.ts @@ -37,8 +37,7 @@ export type TreasuryGovernanceActionFieldSchema = }; export type GovernanceActionFieldSchemas = - | InfoGovernanceActionFieldSchema - | TreasuryGovernanceActionFieldSchema; + | InfoGovernanceActionFieldSchema & TreasuryGovernanceActionFieldSchema; export type GovernanceActionFields = Record< GovernanceActionType, diff --git a/govtool/frontend/src/utils/generateJsonld.ts b/govtool/frontend/src/utils/generateJsonld.ts new file mode 100644 index 000000000..21c962f07 --- /dev/null +++ b/govtool/frontend/src/utils/generateJsonld.ts @@ -0,0 +1,30 @@ +import * as jsonld from "jsonld"; + +import { CIP_100, CIP_108 } from "@/consts"; + +/** + * Generates a JSON-LD document by compacting the given body and context. + * + * @template T - The type of the body. + * @template C - The type of the context. + * @param {T} body - The body of the JSON-LD document. + * @param {C} context - The context of the JSON-LD document. + * @returns {Promise} - A promise that resolves to the compacted JSON-LD document. + */ +export const generateJsonld = async < + T extends string, + C extends jsonld.ContextDefinition +>( + body: T, + context: C +) => { + const doc = { + [`${CIP_108}body`]: body, + [`${CIP_100}hashAlgorithm`]: "blake2b-256", + [`${CIP_100}authors`]: [], + }; + + const json = await jsonld.compact(doc, context); + + return json; +}; diff --git a/govtool/frontend/src/utils/index.ts b/govtool/frontend/src/utils/index.ts index 6a738852d..34fc93664 100644 --- a/govtool/frontend/src/utils/index.ts +++ b/govtool/frontend/src/utils/index.ts @@ -16,3 +16,4 @@ export * from "./localStorage"; export * from "./openInNewTab"; export * from "./removeDuplicatedProposals"; export * from "./validateMetadataHash"; +export * from "./generateJsonld"; diff --git a/govtool/frontend/src/utils/validateMetadataHash.ts b/govtool/frontend/src/utils/validateMetadataHash.ts index b35f23e71..90c271816 100644 --- a/govtool/frontend/src/utils/validateMetadataHash.ts +++ b/govtool/frontend/src/utils/validateMetadataHash.ts @@ -5,13 +5,7 @@ import { API } from "@/services"; import { canonizeJSON } from "./canonizeJSON"; import { URL_REGEX } from "."; - -export enum MetadataHashValidationErrors { - INVALID_URL = "Invalid URL", - INVALID_JSON = "Invalid JSON", - INVALID_HASH = "Invalid hash", - FETCH_ERROR = "Error fetching data", -} +import { MetadataHashValidationErrors } from "@/consts"; /** * Validates the metadata hash by fetching the metadata from the given URL, diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index f493ac5aa..d9d285e12 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -40,7 +40,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz" integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.18.9", "@babel/core@^7.20.12", "@babel/core@^7.22.5", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.5", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.7.5", "@babel/core@^7.8.0": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.20.12", "@babel/core@^7.22.5", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.5", "@babel/core@^7.7.5": version "7.23.5" resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz" integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== @@ -878,7 +878,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/preset-env@^7.1.6", "@babel/preset-env@^7.23.2": +"@babel/preset-env@^7.23.2": version "7.23.5" resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz" integrity sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A== @@ -1016,14 +1016,7 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.22.5": - version "7.23.8" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz" - integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.23.2": +"@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2": version "7.23.8" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz" integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== @@ -1138,7 +1131,7 @@ resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== -"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.11.1", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0": +"@emotion/react@^11.11.1": version "11.11.1" resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz" integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== @@ -1168,7 +1161,7 @@ resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz" integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== -"@emotion/styled@^11.11.0", "@emotion/styled@^11.3.0": +"@emotion/styled@^11.11.0": version "11.11.0" resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz" integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== @@ -1205,6 +1198,56 @@ resolved "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-asmjs/-/cardano-serialization-lib-asmjs-12.0.0-alpha.16.tgz" integrity sha512-7AaQMlhA6/N/MWCiUUwtZtQmsHTkMjIGB9UfzN34qextTmk5Dvx++4UORedo/TVCs4lSfcBXZrNZClC7d9f8Fg== +"@esbuild/aix-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3" + integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g== + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220" + integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q== + +"@esbuild/android-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz#fb7130103835b6d43ea499c3f30cfb2b2ed58456" + integrity sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c" + integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw== + +"@esbuild/android-arm@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.8.tgz#b46e4d9e984e6d6db6c4224d72c86b7757e35bcb" + integrity sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/android-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2" + integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg== + +"@esbuild/android-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.8.tgz#a13db9441b5a4f4e4fec4a6f8ffacfea07888db7" + integrity sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A== + "@esbuild/darwin-arm64@0.18.20": version "0.18.20" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz" @@ -1220,6 +1263,276 @@ resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz" integrity sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw== +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/darwin-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e" + integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g== + +"@esbuild/darwin-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz#75c5c88371eea4bfc1f9ecfd0e75104c74a481ac" + integrity sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a" + integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA== + +"@esbuild/freebsd-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz#9d7259fea4fd2b5f7437b52b542816e89d7c8575" + integrity sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/freebsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2" + integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw== + +"@esbuild/freebsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz#abac03e1c4c7c75ee8add6d76ec592f46dbb39e3" + integrity sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545" + integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg== + +"@esbuild/linux-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz#c577932cf4feeaa43cb9cec27b89cbe0df7d9098" + integrity sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-arm@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3" + integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q== + +"@esbuild/linux-arm@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz#d6014d8b98b5cbc96b95dad3d14d75bb364fdc0f" + integrity sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4" + integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA== + +"@esbuild/linux-ia32@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz#2379a0554307d19ac4a6cdc15b08f0ea28e7a40d" + integrity sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-loong64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121" + integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg== + +"@esbuild/linux-loong64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz#e2a5bbffe15748b49356a6cd7b2d5bf60c5a7123" + integrity sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-mips64el@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9" + integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg== + +"@esbuild/linux-mips64el@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz#1359331e6f6214f26f4b08db9b9df661c57cfa24" + integrity sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-ppc64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912" + integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA== + +"@esbuild/linux-ppc64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz#9ba436addc1646dc89dae48c62d3e951ffe70951" + integrity sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-riscv64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916" + integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ== + +"@esbuild/linux-riscv64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz#fbcf0c3a0b20f40b5fc31c3b7695f0769f9de66b" + integrity sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-s390x@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8" + integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q== + +"@esbuild/linux-s390x@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz#989e8a05f7792d139d5564ffa7ff898ac6f20a4a" + integrity sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/linux-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766" + integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA== + +"@esbuild/linux-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz#b187295393a59323397fe5ff51e769ec4e72212b" + integrity sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/netbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d" + integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ== + +"@esbuild/netbsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz#c1ec0e24ea82313cb1c7bae176bd5acd5bde7137" + integrity sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/openbsd-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2" + integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw== + +"@esbuild/openbsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz#0c5b696ac66c6d70cf9ee17073a581a28af9e18d" + integrity sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/sunos-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767" + integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ== + +"@esbuild/sunos-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz#2a697e1f77926ff09fcc457d8f29916d6cd48fb1" + integrity sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-arm64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee" + integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ== + +"@esbuild/win32-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz#ec029e62a2fca8c071842ecb1bc5c2dd20b066f1" + integrity sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-ia32@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c" + integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg== + +"@esbuild/win32-ia32@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz#cbb9a3146bde64dc15543e48afe418c7a3214851" + integrity sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@esbuild/win32-x64@0.19.11": + version "0.19.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" + integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== + +"@esbuild/win32-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz#c8285183dbdb17008578dbacb6e22748709b4822" + integrity sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -1325,18 +1638,6 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz" integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@istanbuljs/load-nyc-config@^1.0.0", "@istanbuljs/load-nyc-config@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" @@ -1443,7 +1744,7 @@ jest-mock "^29.7.0" jest-util "^29.7.0" -"@jest/globals@^29.7.0", "@jest/globals@>= 28": +"@jest/globals@^29.7.0": version "29.7.0" resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== @@ -1661,7 +1962,7 @@ dependencies: "@babel/runtime" "^7.23.4" -"@mui/material@^5.0.0", "@mui/material@^5.14.4": +"@mui/material@^5.14.4": version "5.14.20" resolved "https://registry.npmjs.org/@mui/material/-/material-5.14.20.tgz" integrity sha512-SUcPZnN6e0h1AtrDktEl76Dsyo/7pyEUQ+SAVe9XhHg/iliA0b4Vo+Eg4HbNkELsMbpDsUF4WHp7rgflPG7qYQ== @@ -1744,7 +2045,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2076,11 +2377,76 @@ estree-walker "^2.0.2" picomatch "^2.3.1" +"@rollup/rollup-android-arm-eabi@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.2.tgz#ccb02257556bacbc1e756ab9b0b973cea2c7a664" + integrity sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA== + +"@rollup/rollup-android-arm64@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.2.tgz#21bd0fbafdf442c6a17645b840f6a94556b0e9bb" + integrity sha512-yZ+MUbnwf3SHNWQKJyWh88ii2HbuHCFQnAYTeeO1Nb8SyEiWASEi5dQUygt3ClHWtA9My9RQAYkjvrsZ0WK8Xg== + "@rollup/rollup-darwin-arm64@4.9.2": version "4.9.2" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.2.tgz" integrity sha512-vqJ/pAUh95FLc/G/3+xPqlSBgilPnauVf2EXOQCZzhZJCXDXt/5A8mH/OzU6iWhb3CNk5hPJrh8pqJUPldN5zw== +"@rollup/rollup-darwin-x64@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.2.tgz#1b06291ff1c41af94d2786cd167188c5bf7caec9" + integrity sha512-otPHsN5LlvedOprd3SdfrRNhOahhVBwJpepVKUN58L0RnC29vOAej1vMEaVU6DadnpjivVsNTM5eNt0CcwTahw== + +"@rollup/rollup-linux-arm-gnueabihf@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.2.tgz#147069948bba00f435122f411210624e72638ebf" + integrity sha512-ewG5yJSp+zYKBYQLbd1CUA7b1lSfIdo9zJShNTyc2ZP1rcPrqyZcNlsHgs7v1zhgfdS+kW0p5frc0aVqhZCiYQ== + +"@rollup/rollup-linux-arm64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.2.tgz#3a50f0e7ae6e444d11c61fce12783196454a4efb" + integrity sha512-pL6QtV26W52aCWTG1IuFV3FMPL1m4wbsRG+qijIvgFO/VBsiXJjDPE/uiMdHBAO6YcpV4KvpKtd0v3WFbaxBtg== + +"@rollup/rollup-linux-arm64-musl@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz#3882a4e3a564af9e55804beeb67076857b035ab7" + integrity sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ== + +"@rollup/rollup-linux-arm64-musl@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.2.tgz#82b5e75484d91c25d4e649d018d9523e72d6dac2" + integrity sha512-On+cc5EpOaTwPSNetHXBuqylDW+765G/oqB9xGmWU3npEhCh8xu0xqHGUA+4xwZLqBbIZNcBlKSIYfkBm6ko7g== + +"@rollup/rollup-linux-riscv64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.2.tgz#ca96f2d43a553d73aec736e991c07010561bc7a9" + integrity sha512-Wnx/IVMSZ31D/cO9HSsU46FjrPWHqtdF8+0eyZ1zIB5a6hXaZXghUKpRrC4D5DcRTZOjml2oBhXoqfGYyXKipw== + +"@rollup/rollup-linux-x64-gnu@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.2.tgz#db1cece244ea46706c0e1a522ec19ca0173abc55" + integrity sha512-ym5x1cj4mUAMBummxxRkI4pG5Vht1QMsJexwGP8547TZ0sox9fCLDHw9KCH9c1FO5d9GopvkaJsBIOkTKxksdw== + +"@rollup/rollup-linux-x64-musl@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.2.tgz#c15b26b86827f75977bf59ebd41ce5d788713936" + integrity sha512-m0hYELHGXdYx64D6IDDg/1vOJEaiV8f1G/iO+tejvRCJNSwK4jJ15e38JQy5Q6dGkn1M/9KcyEOwqmlZ2kqaZg== + +"@rollup/rollup-win32-arm64-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.2.tgz#60152948f9fb08e8c50c1555e334ca9f9f1f53aa" + integrity sha512-x1CWburlbN5JjG+juenuNa4KdedBdXLjZMp56nHFSHTOsb/MI2DYiGzLtRGHNMyydPGffGId+VgjOMrcltOksA== + +"@rollup/rollup-win32-ia32-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.2.tgz#657288cff10311f997d8dbd648590441760ae6d9" + integrity sha512-VVzCB5yXR1QlfsH1Xw1zdzQ4Pxuzv+CPr5qpElpKhVxlxD3CRdfubAG9mJROl6/dmj5gVYDDWk8sC+j9BI9/kQ== + +"@rollup/rollup-win32-x64-msvc@4.9.2": + version "4.9.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.2.tgz#830f3a3fba67f6216a5884368431918029045afe" + integrity sha512-SYRedJi+mweatroB+6TTnJYLts0L0bosg531xnQWtklOI6dezEagx4Q0qDyvRdK+qgdA3YZpjjGuPFtxBmddBA== + "@sentry-internal/feedback@7.85.0": version "7.85.0" resolved "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.85.0.tgz" @@ -2345,7 +2711,7 @@ dependencies: memoizerific "^1.11.3" -"@storybook/blocks@^7.4.5", "@storybook/blocks@7.6.3": +"@storybook/blocks@7.6.3", "@storybook/blocks@^7.4.5": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.6.3.tgz" integrity sha512-EyjyNNCZMcV9UnBSujwduiq+F1VLVX/f16fTTPqqZOHigyfrG5LoEYC6dwOC4yO/xfWY+h3qJ51yiugMxVl0Vg== @@ -2528,7 +2894,7 @@ "@storybook/client-logger" "7.6.3" "@storybook/preview-api" "7.6.3" -"@storybook/core-common@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", "@storybook/core-common@7.6.3": +"@storybook/core-common@7.6.3", "@storybook/core-common@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.3.tgz" integrity sha512-/ZE4BEyGwBHCQCOo681GyBKF4IqCiwVV/ZJCHTMTHFCPLJT2r+Qwv4tnI7xt1kwflOlbBlG6B6CvAqTjjVw/Ew== @@ -2619,7 +2985,7 @@ "@storybook/csf-tools" "7.6.3" unplugin "^1.3.1" -"@storybook/csf-tools@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", "@storybook/csf-tools@7.6.3": +"@storybook/csf-tools@7.6.3", "@storybook/csf-tools@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.3.tgz" integrity sha512-Zi3pg2pg88/mvBKewkfWhFUR1J4uYpHI5fSjOE+J/FeZObX/DIE7r+wJxZ0UBGyrk0Wy7Jajlb2uSP56Y0i19w== @@ -2729,7 +3095,7 @@ resolved "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.6.3.tgz" integrity sha512-WpgdpJpY6rionluxjFZLbKiSDjvQJ5cPgufjvBRuXTsnVOsH3JNRWnPdkQkJLT9uTUMoNcyBMxbjYkK3vU6wSg== -"@storybook/preview-api@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0", "@storybook/preview-api@7.6.3": +"@storybook/preview-api@7.6.3", "@storybook/preview-api@^7.0.0-beta.0 || ^7.0.0-rc.0 || ^7.0.0": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.3.tgz" integrity sha512-uPaK7yLE1P++F+IOb/1j9pgdCwfMYZrUPHogF/Mf9r4cfEjDCcIeKgGMcsbU1KnkzNQQGPh8JRzRr/iYnLjswg== @@ -2772,7 +3138,7 @@ magic-string "^0.30.0" react-docgen "^7.0.0" -"@storybook/react@^7.4.5", "@storybook/react@7.6.3": +"@storybook/react@7.6.3", "@storybook/react@^7.4.5": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/react/-/react-7.6.3.tgz" integrity sha512-W+530cC0BAU+yBc7NzSXYWR3e8Lo5qMsmFJjWYK7zGW/YZGhSG3mjhF9pDzNM+cMtHvUS6qf5PJPQM8jePpPhg== @@ -2808,7 +3174,7 @@ memoizerific "^1.11.3" qs "^6.10.0" -"@storybook/telemetry@^7.1.0", "@storybook/telemetry@7.6.3": +"@storybook/telemetry@7.6.3", "@storybook/telemetry@^7.1.0": version "7.6.3" resolved "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.6.3.tgz" integrity sha512-NDCZWhVIUI3M6Lq4M/HPOvZqDXqANDNbI3kyHr4pFGoVaCUXuDPokL9wR+CZcMvATkJ1gHrfLPBdcRq6Biw3Iw== @@ -2890,7 +3256,47 @@ resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.100.tgz" integrity sha512-XVWFsKe6ei+SsDbwmsuRkYck1SXRpO60Hioa4hoLwR8fxbA9eVp6enZtMxzVVMBi8ej5seZ4HZQeAWepbukiBw== -"@swc/core@*", "@swc/core@^1.3.18": +"@swc/core-darwin-x64@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.100.tgz#d84f5c0bb4603c252884d011a698ed7c634b1505" + integrity sha512-KF/MXrnH1nakm1wbt4XV8FS7kvqD9TGmVxeJ0U4bbvxXMvzeYUurzg3AJUTXYmXDhH/VXOYJE5N5RkwZZPs5iA== + +"@swc/core-linux-arm64-gnu@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.100.tgz#1ed4b92b373882d8f338c4e0a0aa64cdaa6106f1" + integrity sha512-p8hikNnAEJrw5vHCtKiFT4hdlQxk1V7vqPmvUDgL/qe2menQDK/i12tbz7/3BEQ4UqUPnvwpmVn2d19RdEMNxw== + +"@swc/core-linux-arm64-musl@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.100.tgz#9db560f7459e42e65ec02670d6a8316e7c850cfc" + integrity sha512-BWx/0EeY89WC4q3AaIaBSGfQxkYxIlS3mX19dwy2FWJs/O+fMvF9oLk/CyJPOZzbp+1DjGeeoGFuDYpiNO91JA== + +"@swc/core-linux-x64-gnu@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.100.tgz#228826ea48879bf1e73683fbef4373e3e762e424" + integrity sha512-XUdGu3dxAkjsahLYnm8WijPfKebo+jHgHphDxaW0ovI6sTdmEGFDew7QzKZRlbYL2jRkUuuKuDGvD6lO5frmhA== + +"@swc/core-linux-x64-musl@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.100.tgz#09a234dbbf625d071ecb663680e997a62d230d49" + integrity sha512-PhoXKf+f0OaNW/GCuXjJ0/KfK9EJX7z2gko+7nVnEA0p3aaPtbP6cq1Ubbl6CMoPL+Ci3gZ7nYumDqXNc3CtLQ== + +"@swc/core-win32-arm64-msvc@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.100.tgz#add1c82884c10a9054ed6a48f884097aa85c6d2b" + integrity sha512-PwLADZN6F9cXn4Jw52FeP/MCLVHm8vwouZZSOoOScDtihjY495SSjdPnlosMaRSR4wJQssGwiD/4MbpgQPqbAw== + +"@swc/core-win32-ia32-msvc@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.100.tgz#e0b6c5ae7f3250adeeb88dae83558d3f45148c56" + integrity sha512-0f6nicKSLlDKlyPRl2JEmkpBV4aeDfRQg6n8mPqgL7bliZIcDahG0ej+HxgNjZfS3e0yjDxsNRa6sAqWU2Z60A== + +"@swc/core-win32-x64-msvc@1.3.100": + version "1.3.100" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.100.tgz#34721dff151d7dcf165675f18aeed0a12264d88c" + integrity sha512-b7J0rPoMkRTa3XyUGt8PwCaIBuYWsL2DqbirrQKRESzgCvif5iNpqaM6kjIjI/5y5q1Ycv564CB51YDpiS8EtQ== + +"@swc/core@^1.3.18": version "1.3.100" resolved "https://registry.npmjs.org/@swc/core/-/core-1.3.100.tgz" integrity sha512-7dKgTyxJjlrMwFZYb1auj3Xq0D8ZBe+5oeIgfMlRU05doXZypYJe0LAk0yjj3WdbwYzpF+T1PLxwTWizI0pckw== @@ -2926,7 +3332,7 @@ resolved "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== -"@testing-library/dom@^9.0.0", "@testing-library/dom@>=7.21.4": +"@testing-library/dom@^9.0.0": version "9.3.3" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz" integrity sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw== @@ -3156,7 +3562,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@>= 28", "@types/jest@28.1.3": +"@types/jest@28.1.3": version "28.1.3" resolved "https://registry.npmjs.org/@types/jest/-/jest-28.1.3.tgz" integrity sha512-Tsbjk8Y2hkBaY/gJsataeb4q9Mubw9EOz7+4RjPkzD5KjTvHHs7cpws22InaoXxAVAhF5HfFbzJjo6oKWqSZLw== @@ -3212,7 +3618,7 @@ "@types/node" "*" form-data "^4.0.0" -"@types/node@*", "@types/node@^18.0.0 || >=20.0.0", "@types/node@^20.4.8", "@types/node@>= 14": +"@types/node@*", "@types/node@^20.4.8": version "20.10.3" resolved "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz" integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg== @@ -3256,13 +3662,6 @@ resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/react-dom@*", "@types/react-dom@^18.0.11": - version "18.2.17" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz" - integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== - dependencies: - "@types/react" "*" - "@types/react-dom@^18.0.0": version "18.2.18" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz" @@ -3270,6 +3669,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.0.11": + version "18.2.17" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== + dependencies: + "@types/react" "*" + "@types/react-gtm-module@^2.0.2": version "2.0.3" resolved "https://registry.npmjs.org/@types/react-gtm-module/-/react-gtm-module-2.0.3.tgz" @@ -3282,7 +3688,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^18.2.12", "@types/react@>=16": +"@types/react@*", "@types/react@>=16", "@types/react@^18.2.12": version "18.2.42" resolved "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz" integrity sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA== @@ -3380,7 +3786,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.59.0": +"@typescript-eslint/parser@^5.59.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== @@ -3426,7 +3832,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@^5.45.0", "@typescript-eslint/utils@5.62.0": +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.45.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== @@ -3509,7 +3915,7 @@ dependencies: tinyspy "^2.2.0" -"@vitest/ui@^1.0.0", "@vitest/ui@^1.1.0": +"@vitest/ui@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@vitest/ui/-/ui-1.1.0.tgz" integrity sha512-7yU1QRFBplz0xJqcgt+agcbrNFdBmLo8UUppdKkFmYx+Ih0+yMYQOyr7kOB+YoggJY/p5ZzXxdbiOz7NBX2y+w== @@ -3556,7 +3962,7 @@ "@yarnpkg/libzip" "^2.3.0" tslib "^1.13.0" -"@yarnpkg/libzip@^2.3.0", "@yarnpkg/libzip@2.3.0": +"@yarnpkg/libzip@2.3.0", "@yarnpkg/libzip@^2.3.0": version "2.3.0" resolved "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.3.0.tgz" integrity sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg== @@ -3594,7 +4000,7 @@ acorn-walk@^8.3.2: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^7.4.1: +acorn@^7.4.1: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -3604,12 +4010,7 @@ acorn@^8.10.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -acorn@^8.11.2: - version "8.11.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== - -acorn@^8.9.0: +acorn@^8.11.2, acorn@^8.9.0: version "8.11.2" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== @@ -3619,6 +4020,11 @@ address@^1.0.1: resolved "https://registry.npmjs.org/address/-/address-1.2.2.tgz" integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== +agent-base@5: + version "5.1.1" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz" + integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== + agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz" @@ -3626,11 +4032,6 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" -agent-base@5: - version "5.1.1" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz" - integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" @@ -3644,7 +4045,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.12.4, ajv@^6.9.1: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3697,11 +4098,6 @@ ansi-styles@^5.0.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" @@ -3746,13 +4142,6 @@ aria-hidden@^1.1.1: dependencies: tslib "^2.0.0" -aria-query@^5.0.0: - version "5.3.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - aria-query@5.1.3: version "5.1.3" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" @@ -3760,6 +4149,13 @@ aria-query@5.1.3: dependencies: deep-equal "^2.0.5" +aria-query@^5.0.0: + version "5.3.0" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" @@ -4057,7 +4453,7 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.21.9, browserslist@^4.22.1, "browserslist@>= 4.21.0": +browserslist@^4.21.9, browserslist@^4.22.1: version "4.22.2" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz" integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== @@ -4351,16 +4747,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.6.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -4461,12 +4857,7 @@ content-type@~1.0.4: resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -convert-source-map@^1.5.0: - version "1.9.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^1.7.0: +convert-source-map@^1.5.0, convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== @@ -4581,27 +4972,20 @@ date-fns@^2.30.0: dependencies: "@babel/runtime" "^7.21.0" -debug@^2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" @@ -4829,7 +5213,7 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" -domelementtype@^1.3.1, domelementtype@1: +domelementtype@1, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== @@ -4874,11 +5258,6 @@ duplexify@^3.5.0, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -4906,11 +5285,6 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" @@ -4981,46 +5355,18 @@ es6-error@^4.0.1: integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== esbuild-plugin-alias@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz" - integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ== - -esbuild-register@^3.5.0: - version "3.5.0" - resolved "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz" - integrity sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A== - dependencies: - debug "^4.3.4" - -esbuild@^0.18.0, esbuild@>=0.10.0, "esbuild@>=0.12 <1": - version "0.18.20" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" - integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== - optionalDependencies: - "@esbuild/android-arm" "0.18.20" - "@esbuild/android-arm64" "0.18.20" - "@esbuild/android-x64" "0.18.20" - "@esbuild/darwin-arm64" "0.18.20" - "@esbuild/darwin-x64" "0.18.20" - "@esbuild/freebsd-arm64" "0.18.20" - "@esbuild/freebsd-x64" "0.18.20" - "@esbuild/linux-arm" "0.18.20" - "@esbuild/linux-arm64" "0.18.20" - "@esbuild/linux-ia32" "0.18.20" - "@esbuild/linux-loong64" "0.18.20" - "@esbuild/linux-mips64el" "0.18.20" - "@esbuild/linux-ppc64" "0.18.20" - "@esbuild/linux-riscv64" "0.18.20" - "@esbuild/linux-s390x" "0.18.20" - "@esbuild/linux-x64" "0.18.20" - "@esbuild/netbsd-x64" "0.18.20" - "@esbuild/openbsd-x64" "0.18.20" - "@esbuild/sunos-x64" "0.18.20" - "@esbuild/win32-arm64" "0.18.20" - "@esbuild/win32-ia32" "0.18.20" - "@esbuild/win32-x64" "0.18.20" + version "0.2.1" + resolved "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz" + integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ== + +esbuild-register@^3.5.0: + version "3.5.0" + resolved "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz" + integrity sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A== + dependencies: + debug "^4.3.4" -esbuild@^0.18.10: +esbuild@^0.18.0, esbuild@^0.18.10: version "0.18.20" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== @@ -5182,7 +5528,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@*, "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@^8.38.0, eslint@>=6, eslint@>=7: +eslint@^8.38.0: version "8.55.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz" integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA== @@ -5666,19 +6012,19 @@ fs-exists-sync@^0.1.0: resolved "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz" integrity sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg== -fs-extra@^11.1.0: - version "11.2.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== +fs-extra@11.1.1: + version "11.1.1" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@11.1.1: - version "11.1.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== +fs-extra@^11.1.0: + version "11.2.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -5696,16 +6042,16 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: - version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - fsevents@2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -5815,18 +6161,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.0.0: - version "10.3.10" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@^10.2.2: +glob@^10.0.0, glob@^10.2.2: version "10.3.10" resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== @@ -6086,7 +6421,7 @@ human-signals@^5.0.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== -i18next@^23.7.19, "i18next@>= 23.2.3": +i18next@^23.7.19: version "23.7.19" resolved "https://registry.npmjs.org/i18next/-/i18next-23.7.19.tgz" integrity sha512-1aP+YSJl+nLxr42ZJtNhpWpNWYsc6nCbVCf2x4uizIX1BYfcigiRMlb3vOkE1p3+qrI+aD6h5G2Fg+2d2oMIOQ== @@ -6151,7 +6486,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -6344,6 +6679,11 @@ is-path-inside@^3.0.2, is-path-inside@^3.0.3: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-object@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" @@ -6351,11 +6691,6 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-plain-object@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz" @@ -6494,18 +6829,7 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-instrument@^5.1.0: +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== @@ -6516,18 +6840,7 @@ istanbul-lib-instrument@^5.1.0: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" -istanbul-lib-instrument@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz" - integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-instrument@^6.0.1: +istanbul-lib-instrument@^6.0.0, istanbul-lib-instrument@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz" integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== @@ -6576,12 +6889,12 @@ istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== +jackspeak@2.1.1, jackspeak@^2.3.5: + version "2.1.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.1.1.tgz#2a42db4cfbb7e55433c28b6f75d8b796af9669cd" + integrity sha512-juf9stUEwUaILepraGOWIJTLwg48bUnBmRqd2ln2Os1sW987zeoj/hzhbvRB95oMuS2ZTpjULmdwHNX4rzZIZw== dependencies: - "@isaacs/cliui" "^8.0.2" + cliui "^8.0.1" optionalDependencies: "@pkgjs/parseargs" "^0.11.0" @@ -6604,7 +6917,7 @@ jest-changed-files@^29.7.0: jest-util "^29.7.0" p-limit "^3.1.0" -jest-circus@^29.3.1, jest-circus@^29.6.4, jest-circus@^29.7.0: +jest-circus@^29.6.4, jest-circus@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz" integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== @@ -6713,7 +7026,7 @@ jest-each@^29.7.0: jest-util "^29.7.0" pretty-format "^29.7.0" -jest-environment-node@^29.3.1, jest-environment-node@^29.6.4, jest-environment-node@^29.7.0: +jest-environment-node@^29.6.4, jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== @@ -6807,15 +7120,7 @@ jest-message-util@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.0.6: - version "27.5.1" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - -jest-mock@^27.3.0: +jest-mock@^27.0.6, jest-mock@^27.3.0: version "27.5.1" resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz" integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== @@ -6878,7 +7183,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -6893,7 +7198,7 @@ jest-resolve@*, jest-resolve@^29.7.0: resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.3.1, jest-runner@^29.6.4, jest-runner@^29.7.0: +jest-runner@^29.6.4, jest-runner@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz" integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== @@ -7042,7 +7347,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -"jest@^27.0.0 || ^28.0.0 || ^29.0.0", jest@^29.3.1, jest@^29.6.4, "jest@>= 28": +jest@^29.6.4: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -7114,7 +7419,7 @@ jscodeshift@^0.15.1: temp "^0.8.4" write-file-atomic "^2.3.0" -jsdom@*, jsdom@^23.0.1: +jsdom@^23.0.1: version "23.0.1" resolved "https://registry.npmjs.org/jsdom/-/jsdom-23.0.1.tgz" integrity sha512-2i27vgvlUsGEBO9+/kJQRbtqtm+191b5zAZrU/UezVmnC2dlDAFLgDYJvAEi94T4kjsRKkezEtLQTgsNEsW2lQ== @@ -7230,7 +7535,7 @@ ky-universal@^0.11.0: abort-controller "^3.0.0" node-fetch "^3.2.10" -ky@^0.33.3, ky@>=0.31.4: +ky@^0.33.3: version "0.33.3" resolved "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz" integrity sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw== @@ -7497,7 +7802,7 @@ microseconds@0.2.0: resolved "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz" integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== -"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -7509,16 +7814,16 @@ mime-types@^2.1.12, mime-types@^2.1.25, mime-types@~2.1.24, mime-types@~2.1.34: dependencies: mime-db "1.52.0" -mime@^2.0.3: - version "2.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - mime@1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.0.3: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -7534,7 +7839,7 @@ min-indent@^1.0.0, min-indent@^1.0.1: resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@*: +minimatch@*, minimatch@^9.0.1: version "9.0.3" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== @@ -7555,13 +7860,6 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -7574,16 +7872,16 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.4" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - minipass@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" @@ -7905,14 +8203,7 @@ os-homedir@^1.0.1: resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^2.2.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8144,7 +8435,7 @@ pkg-types@^1.0.3: mlly "^1.2.0" pathe "^1.1.0" -playwright-core@>=1.2.0, playwright-core@1.40.1: +playwright-core@1.40.1, playwright-core@>=1.2.0: version "1.40.1" resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz" integrity sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ== @@ -8330,13 +8621,6 @@ pure-rand@^6.0.0: resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz" integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== -qs@^6.10.0: - version "6.11.2" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - qs@6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" @@ -8344,6 +8628,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@^6.10.0: + version "6.11.2" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" @@ -8427,7 +8718,7 @@ react-docgen@^7.0.0: resolve "^1.22.1" strip-indent "^4.0.0" -"react-dom@^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.2.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, "react-dom@16.8.0 - 18": +react-dom@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== @@ -8449,7 +8740,7 @@ react-gtm-module@^2.0.11: resolved "https://registry.npmjs.org/react-gtm-module/-/react-gtm-module-2.0.11.tgz" integrity sha512-8gyj4TTxeP7eEyc2QKawEuQoAZdjKvMY4pgWfycGmqGByhs17fR+zEBs0JUDq4US/l+vbTl+6zvUIx27iDo/Vw== -react-hook-form@^7.0.0, react-hook-form@^7.47.0: +react-hook-form@^7.47.0: version "7.48.2" resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.48.2.tgz" integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== @@ -8462,12 +8753,12 @@ react-i18next@^14.0.1: "@babel/runtime" "^7.22.5" html-parse-stringify "^3.0.1" -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@18.1.0: + version "18.1.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== -react-is@^16.7.0: +react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -8482,11 +8773,6 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-is@18.1.0: - version "18.1.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz" - integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== - react-json-tree@^0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.18.0.tgz" @@ -8563,7 +8849,7 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -"react@^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", "react@^16.3.0 || ^17.0.1 || ^18.0.0", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 0.14.0", "react@>= 16.8.0", react@>=16, react@>=16.6.0, react@>=16.8, react@>=16.8.0, "react@15.x || 16.x || 17.x || 18.x", "react@16.8.0 - 18": +react@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -8602,16 +8888,7 @@ readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.1.1: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^3.4.0: +readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -8802,6 +9079,13 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rimraf@^2.6.1: version "2.7.1" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" @@ -8809,13 +9093,6 @@ rimraf@^2.6.1: dependencies: glob "^7.1.3" -rimraf@^3.0.0, rimraf@^3.0.2, rimraf@3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" @@ -8823,7 +9100,7 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" -rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, "rollup@^2.25.0 || ^3.3.0", rollup@^3.27.1: +"rollup@^2.25.0 || ^3.3.0", rollup@^3.27.1: version "3.29.4" resolved "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz" integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== @@ -8869,17 +9146,12 @@ rxjs@^7.8.1: dependencies: tslib "^2.1.0" -safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@5.1.2: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@5.2.1: +safe-buffer@5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8912,22 +9184,12 @@ schema-utils@^2.7.0: ajv "^6.12.4" ajv-keywords "^3.5.2" -semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.7.2" resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -8939,11 +9201,6 @@ semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: dependencies: lru-cache "^6.0.0" -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - send@0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -9045,12 +9302,7 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -signal-exit@^4.1.0: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== @@ -9098,14 +9350,6 @@ source-map-js@^1.0.2: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-support@^0.5.16: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" @@ -9114,6 +9358,14 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.16: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.5.7: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" @@ -9246,20 +9498,6 @@ stream-shift@^1.0.0: resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -9276,15 +9514,6 @@ string-length@^5.0.1: char-regex "^2.0.0" strip-ansi "^7.0.1" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -9294,21 +9523,19 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: - ansi-regex "^5.0.1" + safe-buffer "~5.1.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" @@ -9585,12 +9812,7 @@ ts-dedent@^2.0.0, ts-dedent@^2.2.0: resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== -tslib@^1.13.0: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^1.8.1: +tslib@^1.13.0, tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -9619,7 +9841,7 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-detect@^4.0.0, type-detect@^4.0.8, type-detect@4.0.8: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -9644,12 +9866,7 @@ type-fest@^0.6.0: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== -type-fest@^0.8.0: - version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^0.8.1: +type-fest@^0.8.0, type-fest@^0.8.1: version "0.8.1" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== @@ -9684,7 +9901,7 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@*, typescript@^5.0.2, "typescript@>= 4.3.x", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": +typescript@^5.0.2: version "5.3.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz" integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== @@ -9781,7 +9998,7 @@ unload@2.2.0: "@babel/runtime" "^7.6.2" detect-node "^2.0.4" -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -9920,7 +10137,7 @@ vite-plugin-istanbul@^3.0.1: picocolors "^1.0.0" test-exclude "^6.0.0" -"vite@^3.0.0 || ^4.0.0 || ^5.0.0", vite@^4, vite@^4.1.0-beta.0, "vite@^4.2.0 || ^5.0.0", vite@^4.3.9: +vite@^4.3.9: version "4.5.1" resolved "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz" integrity sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA== @@ -9942,7 +10159,7 @@ vite@^5.0.0: optionalDependencies: fsevents "~2.3.3" -vitest@^1.0.0, vitest@^1.1.0, "vitest@>= 0.32": +vitest@^1.1.0: version "1.2.2" resolved "https://registry.npmjs.org/vitest/-/vitest-1.2.2.tgz" integrity sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw== @@ -10023,7 +10240,7 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -web-streams-polyfill@^3.0.3, web-streams-polyfill@>=3.2.1: +web-streams-polyfill@^3.0.3: version "3.3.3" resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz" integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== @@ -10140,15 +10357,6 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" @@ -10167,15 +10375,6 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" From e50ee516d070ef1884be52193305f01666bd52fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Wed, 13 Mar 2024 15:35:24 +0100 Subject: [PATCH 06/20] add pending transaction for governance action creation --- .../components/organisms/DashboardCards.tsx | 23 +++++--- govtool/frontend/src/context/wallet.tsx | 52 ++++++++++++++++++- govtool/frontend/src/i18n/locales/en.ts | 4 ++ govtool/frontend/src/utils/localStorage.ts | 10 ++-- 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/govtool/frontend/src/components/organisms/DashboardCards.tsx b/govtool/frontend/src/components/organisms/DashboardCards.tsx index 6f2d1c11d..ed3fefc52 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards.tsx @@ -20,14 +20,15 @@ export const DashboardCards = () => { buildSignSubmitConwayCertTx, delegateTo, delegateTransaction, - voter, dRepID, dRepIDBech32, + govActionTransaction, isDrepLoading, isPendingTransaction, registerTransaction, soleVoterTransaction, stakeKey, + voter, } = useCardano(); const navigate = useNavigate(); const { currentDelegation, isCurrentDelegationLoading } = @@ -185,6 +186,15 @@ export const DashboardCards = () => { [isPendingTransaction, navigate] ); + const onClickGovernanceActionCardActionButton = useCallback(() => { + if(govActionTransaction.transactionHash) { + navigate(PATHS.dashboardGovernanceActions) + return + } + navigate(PATHS.createGovernanceAction) + + }, [govActionTransaction.transactionHash, navigate]) + const displayedDelegationId = useMemo(() => { const restrictedNames = [ dRepID, @@ -525,16 +535,13 @@ export const DashboardCards = () => { navigate(PATHS.createGovernanceAction)} + firstButtonAction={onClickGovernanceActionCardActionButton} firstButtonLabel={t( `dashboard.proposeGovernanceAction.${ - // TODO: add isPendingGovernanceAction to the context - // isPendingGovernanceAction ? "propose" : "viewGovernanceActions" - `propose` + govActionTransaction.transactionHash ? "view" : "propose" }` - )} + )} + inProgress={!!govActionTransaction.transactionHash} secondButtonLabel={t("learnMore")} secondButtonAction={() => openInNewTab( diff --git a/govtool/frontend/src/context/wallet.tsx b/govtool/frontend/src/context/wallet.tsx index 5353294d0..0e445fe37 100644 --- a/govtool/frontend/src/context/wallet.tsx +++ b/govtool/frontend/src/context/wallet.tsx @@ -62,6 +62,7 @@ import { generateAnchor, getItemFromLocalStorage, getPubDRepID, + GOVERNANCE_ACTION_KEY, openInNewTab, PROTOCOL_PARAMS_KEY, REGISTER_SOLE_VOTER_TRANSACTION_KEY, @@ -160,6 +161,7 @@ interface CardanoContext { cip95MetadataURL?: string, cip95MetadataHash?: string ) => Promise; + govActionTransaction: TransactionHistoryItem; delegateTransaction: TransactionHistoryItem; registerTransaction: TransactionHistoryItem & { type: DRepActionType }; soleVoterTransaction: TransactionHistoryItem & { @@ -229,6 +231,8 @@ function CardanoProvider(props: Props) { const [registerTransaction, setRegisterTransaction] = useState< TransactionHistoryItem & { type: DRepActionType } >({ time: undefined, transactionHash: "", type: "" }); + const [govActionTransaction, setGovActionTransaction] = + useState({ time: undefined, transactionHash: "" }); const [soleVoterTransaction, setSoleVoterTransaction] = useState< TransactionHistoryItem & { type: Omit } >({ time: undefined, transactionHash: "", type: "" }); @@ -513,12 +517,42 @@ function CardanoProvider(props: Props) { let interval = setInterval(checkVoteTransaction, REFRESH_TIME); checkVoteTransaction(); } + if (govActionTransaction?.transactionHash) { + const checkGovActionTransaction = async () => { + const resetGovActionTransaction = () => { + clearInterval(interval); + removeItemFromLocalStorage(GOVERNANCE_ACTION_KEY + `_${stakeKey}`); + setGovActionTransaction({ + time: undefined, + transactionHash: "", + }); + }; + const status = await getTransactionStatus( + govActionTransaction.transactionHash + ); + if (status.transactionConfirmed) { + resetGovActionTransaction(); + if (isEnabled) addSuccessAlert(t("alerts.govAction.success")); + } + if ( + new Date().getTime() - + new Date(govActionTransaction?.time).getTime() > + TIME_TO_EXPIRE_TRANSACTION + ) { + resetGovActionTransaction(); + if (isEnabled) addErrorAlert(t("alerts.govAction.failed")); + } + }; + let interval = setInterval(checkGovActionTransaction, REFRESH_TIME); + checkGovActionTransaction(); + } if ( isEnabled && (voteTransaction?.transactionHash || registerTransaction?.transactionHash || soleVoterTransaction?.transactionHash || - delegateTransaction?.transactionHash) + delegateTransaction?.transactionHash || + govActionTransaction.transactionHash) ) { addWarningAlert(t("alerts.transactionInProgress"), 10000); } @@ -527,6 +561,7 @@ function CardanoProvider(props: Props) { registerTransaction, soleVoterTransaction, voteTransaction, + govActionTransaction, ]); const getChangeAddress = async (enabledApi: CardanoApiWallet) => { @@ -945,6 +980,19 @@ function CardanoProvider(props: Props) { "utf8" ).toString("hex"); + if (govActionBuilder) { + setGovActionTransaction({ + time: new Date(), + transactionHash: resultHash, + }); + setItemToLocalStorage( + GOVERNANCE_ACTION_KEY + `_${stakeKey}`, + JSON.stringify({ + time: new Date(), + transactionHash: resultHash, + }) + ); + } if (type === "registration") { setRegisterTransaction({ time: new Date(), @@ -1362,6 +1410,7 @@ function CardanoProvider(props: Props) { voter, voteTransaction, walletApi, + govActionTransaction, }), [ address, @@ -1398,6 +1447,7 @@ function CardanoProvider(props: Props) { voter, voteTransaction, walletApi, + govActionTransaction, ] ); diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 406864207..5a44392cf 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -7,6 +7,10 @@ export const en = { "Your voting power has been successfully delegated! Please refresh the page.", success: "Your voting power has been successfully delegated!", }, + govAction: { + failed: "Creating Governance Action transaction failed", + success: "Your Governance Action has been submitted", + }, metadataUpdate: { failed: "Update DRep metadata transaction failed", success: "You have successfully updated DRep metadata!", diff --git a/govtool/frontend/src/utils/localStorage.ts b/govtool/frontend/src/utils/localStorage.ts index 8655509fb..1a678056d 100644 --- a/govtool/frontend/src/utils/localStorage.ts +++ b/govtool/frontend/src/utils/localStorage.ts @@ -1,12 +1,12 @@ -export const WALLET_LS_KEY = "wallet_data"; -export const DELEGATE_TRANSACTION_KEY = "delegate_transaction"; -export const REGISTER_TRANSACTION_KEY = "register_transaction"; -export const REGISTER_SOLE_VOTER_TRANSACTION_KEY = - "register_sole_voter_transaction"; +export const GOVERNANCE_ACTION_KEY = "create_governance_action" export const DELEGATE_TO_KEY = "delegate_to_transaction"; +export const DELEGATE_TRANSACTION_KEY = "delegate_transaction"; export const PROTOCOL_PARAMS_KEY = "protocol_params"; +export const REGISTER_SOLE_VOTER_TRANSACTION_KEY ="register_sole_voter_transaction"; +export const REGISTER_TRANSACTION_KEY = "register_transaction"; export const SANCHO_INFO_KEY = "sancho_info"; export const VOTE_TRANSACTION_KEY = "vote_transaction"; +export const WALLET_LS_KEY = "wallet_data"; export function getItemFromLocalStorage(key: string) { const item = window.localStorage.getItem(key); From 401b34876826ee5b4ff65f4dc38de0c653c04796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 13 Mar 2024 15:51:47 +0100 Subject: [PATCH 07/20] [#378] remove console.log of hash --- .../frontend/src/hooks/forms/useCreateGovernanceActionForm.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index 862f4ca27..abd6b0d7f 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -123,7 +123,6 @@ export const useCreateGovernanceActionForm = ( const validateHash = useCallback( async (storingUrl: string, hash: string | null) => { try { - console.log({ hash }); if (!hash) throw new Error(MetadataHashValidationErrors.INVALID_HASH); await validateMetadataHash(storingUrl, hash); From 919d72d12c26206531fa520442eaf1166c3a9081 Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Mon, 11 Mar 2024 16:31:16 +0100 Subject: [PATCH 08/20] [#453] Storybook update --- govtool/frontend/.storybook/preview.tsx | 48 ++++++++------ .../src/stories/DashboardCard.stories.ts | 17 +++-- .../src/stories/DashboardTopNav.stories.ts | 16 +---- .../stories/DelegateActionRadio.stories.ts | 16 +++++ .../frontend/src/stories/Input.stories.tsx | 5 ++ .../src/stories/LinkWithIcon.stories.tsx | 26 ++++++++ .../src/stories/LoadingButton.stories.tsx | 31 ++++++++++ govtool/frontend/src/stories/Step.stories.tsx | 62 +++++++++++++++++++ .../frontend/src/stories/TextArea.stories.tsx | 42 +++++++++++++ .../modals/ExternalLinkModal.stories.tsx | 30 ++++----- .../stories/modals/StatusModal.stories.tsx | 32 +++++----- .../stories/modals/StatusWithLink.stories.tsx | 32 +++++----- .../modals/VotingPowerModal.stories.tsx | 56 +++++++++++++++++ 13 files changed, 325 insertions(+), 88 deletions(-) create mode 100644 govtool/frontend/src/stories/LinkWithIcon.stories.tsx create mode 100644 govtool/frontend/src/stories/LoadingButton.stories.tsx create mode 100644 govtool/frontend/src/stories/Step.stories.tsx create mode 100644 govtool/frontend/src/stories/TextArea.stories.tsx create mode 100644 govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx diff --git a/govtool/frontend/.storybook/preview.tsx b/govtool/frontend/.storybook/preview.tsx index f3deaefc6..406ac7970 100644 --- a/govtool/frontend/.storybook/preview.tsx +++ b/govtool/frontend/.storybook/preview.tsx @@ -1,8 +1,12 @@ +import React from "react"; import type { Preview } from "@storybook/react"; import { ThemeProvider } from "@emotion/react"; import { theme } from "../src/theme"; import { MemoryRouter, Routes, Route } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "react-query"; +import { I18nextProvider } from "react-i18next"; +import i18n from "../src/i18n"; +import { ModalProvider } from "../src/context/modal"; const queryClient = new QueryClient(); @@ -19,26 +23,30 @@ const preview: Preview = { decorators: [ (Story) => ( - - - - - - - } - /> - - - + + + + + + + + + } + /> + + + + + ), ], diff --git a/govtool/frontend/src/stories/DashboardCard.stories.ts b/govtool/frontend/src/stories/DashboardCard.stories.ts index 21bac97e4..fc47278eb 100644 --- a/govtool/frontend/src/stories/DashboardCard.stories.ts +++ b/govtool/frontend/src/stories/DashboardCard.stories.ts @@ -21,9 +21,7 @@ export const DashboardCardComponent: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", }, @@ -38,13 +36,22 @@ export const DashboardCardComponent: Story = { }, }; +export const WithDRepIdDashboardCardComponent: Story = { + args: { + description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", + firstButtonLabel: "first button", + imageURL: IMAGES.govActionDelegateImage, + secondButtonLabel: "second button", + title: "Action card", + cardId: "drep1gwsw9ckkhuwscj9savt5f7u9xsrudw209hne7pggcktzuw5sv32", + }, +}; + export const isLoadingDashboardCard: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", isLoading: true, @@ -62,9 +69,7 @@ export const isProgressDashboardCard: Story = { args: { description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.", firstButtonLabel: "first button", - imageHeight: 80, imageURL: IMAGES.govActionDelegateImage, - imageWidth: 115, secondButtonLabel: "second button", title: "Action card", inProgress: true, diff --git a/govtool/frontend/src/stories/DashboardTopNav.stories.ts b/govtool/frontend/src/stories/DashboardTopNav.stories.ts index 06508f3aa..3ecbb15b7 100644 --- a/govtool/frontend/src/stories/DashboardTopNav.stories.ts +++ b/govtool/frontend/src/stories/DashboardTopNav.stories.ts @@ -1,7 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; import { DashboardTopNav } from "@organisms"; -import { IMAGES } from "@/consts"; import { within, userEvent, waitFor, screen } from "@storybook/testing-library"; import { expect } from "@storybook/jest"; @@ -15,7 +14,7 @@ export default meta; type Story = StoryObj; export const DashboardTopNavComponent: Story = { - args: { title: "Example title", isDrawer: true }, + args: { title: "Example title" }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); expect(canvas.getByText("Example title")).toBeInTheDocument(); @@ -31,16 +30,3 @@ export const DashboardTopNavComponent: Story = { }); }, }; - -export const DashboardTopNavWithIcon: Story = { - args: { - title: "Example title", - isDrawer: true, - imageSRC: IMAGES.appLogoWithoutText, - imageHeight: 24, - }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - expect(canvas.getByRole("img")).toBeInTheDocument(); - }, -}; diff --git a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts index a05563d28..49c24295c 100644 --- a/govtool/frontend/src/stories/DelegateActionRadio.stories.ts +++ b/govtool/frontend/src/stories/DelegateActionRadio.stories.ts @@ -68,3 +68,19 @@ export const ActionRadioActive: Story = { ); }, }; + +export const ActionRadioOnlyTitle: Story = { + args: { + title: "Title", + value: "", + isChecked: false, + }, +}; + +export const ActionRadioOnlyTitleChecked: Story = { + args: { + title: "Title", + value: "", + isChecked: true, + }, +}; diff --git a/govtool/frontend/src/stories/Input.stories.tsx b/govtool/frontend/src/stories/Input.stories.tsx index cbe95a400..95a134c60 100644 --- a/govtool/frontend/src/stories/Input.stories.tsx +++ b/govtool/frontend/src/stories/Input.stories.tsx @@ -60,3 +60,8 @@ ErrorAndLabel.play = async ({ canvasElement }) => { expect(canvas.getByText("Label")).toBeInTheDocument(); expect(canvas.getByTestId("error-message-error")).toBeInTheDocument(); }; + +export const WithHelpfulText = Template.bind({}); +WithHelpfulText.args = { + helpfulText: "Helpful text", +}; diff --git a/govtool/frontend/src/stories/LinkWithIcon.stories.tsx b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx new file mode 100644 index 000000000..83e533f25 --- /dev/null +++ b/govtool/frontend/src/stories/LinkWithIcon.stories.tsx @@ -0,0 +1,26 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { LinkWithIcon } from "@molecules"; +import { ICONS } from "@consts"; + +const meta: Meta = { + title: "Example/LinkWithIcon", + component: LinkWithIcon, + parameters: { + layout: "centered", + }, +}; + +export default meta; + +export const Default: StoryObj = { + args: { + label: "Default Link", + }, +}; + +export const WithCustomIcon: StoryObj = { + args: { + label: "Custom Icon Link", + icon: , + }, +}; diff --git a/govtool/frontend/src/stories/LoadingButton.stories.tsx b/govtool/frontend/src/stories/LoadingButton.stories.tsx new file mode 100644 index 000000000..935014cd1 --- /dev/null +++ b/govtool/frontend/src/stories/LoadingButton.stories.tsx @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { LoadingButton } from "@atoms"; + +const meta = { + title: "Example/LoadingButton", + component: LoadingButton, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + children: "Button", + variant: "contained", + isLoading: false, + }, +}; + +export const Loading: Story = { + args: { + children: "Button", + variant: "contained", + isLoading: true, + }, +}; diff --git a/govtool/frontend/src/stories/Step.stories.tsx b/govtool/frontend/src/stories/Step.stories.tsx new file mode 100644 index 000000000..aecebae56 --- /dev/null +++ b/govtool/frontend/src/stories/Step.stories.tsx @@ -0,0 +1,62 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { Button } from "@atoms"; +import OpenInNewIcon from "@mui/icons-material/OpenInNew"; + +import { Field, Step } from "@molecules"; + +const meta: Meta = { + title: "Example/Step", + component: Step, + parameters: { + layout: "centered", + }, +}; + +export default meta; + +export const WithButton: StoryObj = { + args: { + label: "Download this file", + stepNumber: 1, + component: ( + + ), + }, +}; + +export const WithIconButton: StoryObj = { + args: { + label: + "Save this file in a location that provides a public URL (ex. github)", + stepNumber: 2, + component: ( + + ), + }, +}; + +export const WithInput: StoryObj = { + args: { + label: + "Save this file in a location that provides a public URL (ex. github)", + stepNumber: 2, + component: , + }, +}; diff --git a/govtool/frontend/src/stories/TextArea.stories.tsx b/govtool/frontend/src/stories/TextArea.stories.tsx new file mode 100644 index 000000000..8f6cc178b --- /dev/null +++ b/govtool/frontend/src/stories/TextArea.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryFn } from "@storybook/react"; + +import { Field } from "@molecules"; +import { ComponentProps } from "react"; + +const meta: Meta = { + title: "Example/TextArea", + component: Field.TextArea, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], +}; + +export default meta; + +const Template: StoryFn> = (args) => { + return ; +}; + +export const Default = Template.bind({}); + +export const WithLabel = Template.bind({}); +WithLabel.args = { + label: "Label", +}; + +export const WithHelpfulText = Template.bind({}); +WithHelpfulText.args = { + helpfulText: "Helpful text here", +}; + +export const Error = Template.bind({}); +Error.args = { + errorMessage: "Error message", +}; + +export const ErrorAndLabel = Template.bind({}); +ErrorAndLabel.args = { + errorMessage: "Error message", + label: "Label", +}; diff --git a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx index dc2df8b5d..236943ac5 100644 --- a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx @@ -1,28 +1,22 @@ -import { ComponentProps, useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { useEffect } from "react"; +import { Meta, StoryFn } from "@storybook/react"; import { Modal } from "@atoms"; import { ExternalLinkModal, ExternalLinkModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; +import { useModal } from "../../context/modal"; import { userEvent, within, screen, waitFor } from "@storybook/testing-library"; import { expect, jest } from "@storybook/jest"; +import { callAll } from "@/utils"; const meta = { title: "Example/Modals/ExternalLinkModal", component: ExternalLinkModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals } = useModal(); const open = () => { openModal({ @@ -40,12 +34,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx index 24bb364b1..d7c0b56ce 100644 --- a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx @@ -1,22 +1,16 @@ import { useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; +import { expect } from "@storybook/jest"; +import { within, waitFor, screen, userEvent } from "@storybook/testing-library"; import { Modal } from "@atoms"; import { StatusModal, StatusModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; -import { within, waitFor, screen, userEvent } from "@storybook/testing-library"; -import { expect } from "@storybook/jest"; +import { useModal } from "../../context/modal"; +import { callAll } from "@utils"; const meta = { title: "Example/Modals/StatusModal", component: StatusModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; @@ -40,7 +34,7 @@ const performCommonAction = async (canvas: any, args: any) => { }); }; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals, closeModal } = useModal(); const open = () => { openModal({ @@ -67,12 +61,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx index e331a14bb..1181fb143 100644 --- a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx @@ -1,28 +1,22 @@ import { useEffect } from "react"; -import { Story, Meta, StoryFn } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; +import { expect, jest } from "@storybook/jest"; +import { userEvent, waitFor, within, screen } from "@storybook/testing-library"; import { Modal } from "@atoms"; import { StatusModal, StatusModalState } from "@organisms"; -import { ModalProvider, useModal } from "../../context/modal"; -import { userEvent, waitFor, within, screen } from "@storybook/testing-library"; -import { expect, jest } from "@storybook/jest"; +import { useModal } from "../../context/modal"; +import { callAll } from "@utils"; const meta = { title: "Example/Modals/StatusModalWithLink", component: StatusModal, - decorators: [ - (Story) => ( - - - - ), - ], } satisfies Meta; export default meta; const Template: StoryFn = (args) => { - const { openModal, modal, closeModal } = useModal(); + const { openModal, modal, modals, closeModal } = useModal(); const open = () => { openModal({ @@ -48,12 +42,18 @@ const Template: StoryFn = (args) => { - {modal?.component && ( + {modals[modal.type]?.component && ( + openModal({ type: "none", state: null }) + ) + : undefined + } > - {modal.component} + {modals[modal.type]?.component ?? <>} )} diff --git a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx new file mode 100644 index 000000000..5820c9bb3 --- /dev/null +++ b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx @@ -0,0 +1,56 @@ +import { Meta, StoryFn } from "@storybook/react"; + +import { Modal } from "@atoms"; +import { StatusModal, VotingPowerModalState } from "@organisms"; +import { useModal } from "@context"; +import { callAll } from "@utils"; + +const meta = { + title: "Example/Modals/VotingPowerModal", + component: StatusModal, +} satisfies Meta; + +export default meta; + +const Template: StoryFn = (args) => { + const { openModal, modal, modals } = useModal(); + + const open = () => { + openModal({ + type: "votingPower", + state: { + ...args, + }, + }); + }; + + return ( + <> + + {modals[modal.type]?.component && ( + + openModal({ type: "none", state: null }) + ) + : undefined + } + > + {modals[modal.type]?.component ?? <>} + + )} + + ); +}; + +export const Default = Template.bind({}); +Default.args = { + yesVotes: 1000000000000, + noVotes: 10000000000, + abstainVotes: 324000000, + vote: "yes", +}; From b17a9c2f86635285936f73106320a25d41732137 Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Wed, 13 Mar 2024 13:21:16 +0100 Subject: [PATCH 09/20] [#453] Fixes after CR --- govtool/frontend/src/stories/Input.stories.tsx | 7 +++++++ govtool/frontend/src/stories/TextArea.stories.tsx | 7 +++++++ .../src/stories/modals/ExternalLinkModal.stories.tsx | 10 +++------- .../src/stories/modals/StatusModal.stories.tsx | 10 +++------- .../src/stories/modals/StatusWithLink.stories.tsx | 10 +++------- .../src/stories/modals/VotingPowerModal.stories.tsx | 10 +++------- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/govtool/frontend/src/stories/Input.stories.tsx b/govtool/frontend/src/stories/Input.stories.tsx index 95a134c60..e863f036b 100644 --- a/govtool/frontend/src/stories/Input.stories.tsx +++ b/govtool/frontend/src/stories/Input.stories.tsx @@ -65,3 +65,10 @@ export const WithHelpfulText = Template.bind({}); WithHelpfulText.args = { helpfulText: "Helpful text", }; + +export const WithAllProps = Template.bind({}); +WithAllProps.args = { + label: "Label", + helpfulText: "Helpful text", + errorMessage: "Error message", +}; diff --git a/govtool/frontend/src/stories/TextArea.stories.tsx b/govtool/frontend/src/stories/TextArea.stories.tsx index 8f6cc178b..c378c6749 100644 --- a/govtool/frontend/src/stories/TextArea.stories.tsx +++ b/govtool/frontend/src/stories/TextArea.stories.tsx @@ -40,3 +40,10 @@ ErrorAndLabel.args = { errorMessage: "Error message", label: "Label", }; + +export const WithAllProps = Template.bind({}); +WithAllProps.args = { + label: "Label", + helpfulText: "Helpful text", + errorMessage: "Error message", +}; diff --git a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx index 236943ac5..05ac4c018 100644 --- a/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/ExternalLinkModal.stories.tsx @@ -37,13 +37,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx index d7c0b56ce..c8474d741 100644 --- a/govtool/frontend/src/stories/modals/StatusModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusModal.stories.tsx @@ -64,13 +64,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx index 1181fb143..8c8ca391b 100644 --- a/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx +++ b/govtool/frontend/src/stories/modals/StatusWithLink.stories.tsx @@ -45,13 +45,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} diff --git a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx index 5820c9bb3..fbca8d633 100644 --- a/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/VotingPowerModal.stories.tsx @@ -32,13 +32,9 @@ const Template: StoryFn = (args) => { {modals[modal.type]?.component && ( - openModal({ type: "none", state: null }) - ) - : undefined - } + handleClose={callAll(modals[modal.type]?.onClose, () => + openModal({ type: "none", state: null }) + )} > {modals[modal.type]?.component ?? <>} From bb1bc51ec3b657c11cd22961fc35b14bcddf3fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Placzy=C5=84ski?= Date: Wed, 13 Mar 2024 14:03:44 +0100 Subject: [PATCH 10/20] Introduce frontend image build environment tag To ensure frontend image builds can distinguish between different environments, an additional distinction based on the environment tag has been introduced. This change was necessary as the commit altering the frontend module alone was insufficient. By adding an environment tag to the image tag name, applications with the same version can now be uniquely identified across various environments. Changes Made: - Modified the Makefile in the govtool/frontend directory to introduce an environment tag to the image tag name used in frontend image builds. The new tag is generated by appending the environment variable to the commit hash obtained from the git log command, ensuring each build is uniquely identified per environment. --- govtool/frontend/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/govtool/frontend/Makefile b/govtool/frontend/Makefile index 2721792b7..24f0702dc 100644 --- a/govtool/frontend/Makefile +++ b/govtool/frontend/Makefile @@ -7,7 +7,7 @@ endif .DEFAULT_GOAL := push-frontend # image tags -frontend_image_tag := $(shell git log -n 1 --format="%H" -- $(root_dir)/govtool/frontend) +frontend_image_tag := $(shell git log -n 1 --format="%H" -- $(root_dir)/govtool/frontend)-$(env) .PHONY: build-frontend build-frontend: docker-login From 854034f63e9b4111560a01df625e3ded3eb82f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 13 Mar 2024 16:03:45 +0100 Subject: [PATCH 11/20] [#378] fix text wrapping on review governance action submission --- .../ReviewCreatedGovernanceAction.tsx | 7 +- .../forms/useCreateGovernanceActionForm.ts | 4 +- govtool/frontend/src/i18n/locales/en.ts | 81 ++++++++++--------- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx index 6afc22249..aaefa6d6f 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx @@ -53,11 +53,14 @@ export const ReviewCreatedGovernanceAction = ({ key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, " "); return ( - + {label} - + {value as string} diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index abd6b0d7f..2e7e40041 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -166,7 +166,7 @@ export const useCreateGovernanceActionForm = ( data.amount === undefined || data.receivingAddress === undefined ) { - throw new Error("Invalid treasury governance action data"); + throw new Error(t("errors.invalidTreasuryGovernanceActionType")); } const treasuryActionDetails = { @@ -177,7 +177,7 @@ export const useCreateGovernanceActionForm = ( return await buildTreasuryGovernanceAction(treasuryActionDetails); default: - throw new Error("Invalid governance action type"); + throw new Error(t("errors.invalidGovernanceActionType")); } } catch (error: any) { console.error(error); diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 5a44392cf..98999d447 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -139,35 +139,17 @@ export const en = { creatingAGovernanceActionDescription: "To create a Governance Action, you will need to:\n\n• Fill out a form with the relevant data\n• Pay a refundable deposit of ₳{{deposit}}\n• Store the metadata of your Governance Action at your own expense.\n\nYour deposit will be refunded to your wallet when the Governance Action is either enacted or expired.\n\nThe deposit will not affect your Voting Power.", editSubmission: "Edit submission", - formTitle: "Governance Action details", - references: "References and Supporting Information", - reviewSubmission: "Review your submission", - storeDataCheckboxLabel: - "I agree to store correctly this information and to maintain them over the years", - storeDataLink: "Learn more about storing information", - storeDataTitle: "Store and Maintain the Data Yourself", - storingInformationDescription: - "Download your file, save it to your chosen location, and enter the URL of that location in step 3", - storingInformationStep1Label: "Download this file", - storingInformationStep2Label: - "Save this file in a location that provides a public URL (ex. github)", - storingInformationStep2Link: "Read full guide", - storingInformationStep3Label: "Paste the URL here", - storingInformationTitle: "Information Storage Steps", - storingInformationURLPlaceholder: "URL", - supportingLinks: "Supporting links", - title: "Create a Governance Action", fields: { declarations: { - title: { - label: "Title", - placeholder: "A name for this Action", - }, abstract: { label: "Abstract", placeholder: "Summary", tip: "General summary of the Action", }, + amount: { + label: "Amount", + placeholder: "e.g. 20000", + }, motivation: { label: "Motivation", placeholder: "Problem this GA will solve", @@ -182,41 +164,59 @@ export const en = { label: "Receiving Address", placeholder: "The address to receive funds", }, - amount: { - label: "Amount", - placeholder: "e.g. 20000", + title: { + label: "Title", + placeholder: "A name for this Action", }, }, + formTitle: "Governance Action details", + references: "References and Supporting Information", + reviewSubmission: "Review your submission", + storeDataCheckboxLabel: + "I agree to store correctly this information and to maintain them over the years", + storeDataLink: "Learn more about storing information", + storeDataTitle: "Store and Maintain the Data Yourself", + storingInformationDescription: + "Download your file, save it to your chosen location, and enter the URL of that location in step 3", + storingInformationStep1Label: "Download this file", + storingInformationStep2Label: + "Save this file in a location that provides a public URL (ex. github)", + storingInformationStep2Link: "Read full guide", + storingInformationStep3Label: "Paste the URL here", + storingInformationTitle: "Information Storage Steps", + storingInformationURLPlaceholder: "URL", + supportingLinks: "Supporting links", + title: "Create a Governance Action", validations: { - maxLength: "Max {{maxLength}} characters", - required: "This field is required", bech32: "Invalid bech32 address", + maxLength: "Max {{maxLength}} characters", number: "Only number is allowed", + required: "This field is required", url: "Invalid URL", }, }, modals: { externalDataDoesntMatch: { - title: "Your External Data Does Not Match the Original File.", - message: - "GovTool checks the URL you entered to see if the JSON file that you self-host matches the one that was generated in GovTool. To complete registration, this match must be exact.\n\nIn this case, there is a mismatch. You can go back to the data edit screen and try the process again.", buttonText: "Go to Data Edit Screen", cancelRegistrationText: "Cancel Registration", feedbackText: "Feedback", + message: + "GovTool checks the URL you entered to see if the JSON file that you self-host matches the one that was generated in GovTool. To complete registration, this match must be exact.\n\nIn this case, there is a mismatch. You can go back to the data edit screen and try the process again.", + title: "Your External Data Does Not Match the Original File.", }, - urlCannotBeFound: { - title: "The URL You Entered Cannot Be Found", + submitTransactionSuccess: { message: - "GovTool cannot find the URL that you entered. Please check it and re-enter.", - linkText: "Learn More about self-hosting", + "Your Governance Action may take a little time to submit to the chain.", + title: "Governance Action submitted!", + }, + urlCannotBeFound: { buttonText: "Go to Data Edit Screen", cancelRegistrationText: "Cancel Registration", feedbackText: "Feedback", - }, - submitTransactionSuccess: { - title: "Governance Action submitted!", + linkText: "Learn More about self-hosting", message: - "Your Governance Action may take a little time to submit to the chain.", + "GovTool cannot find the URL that you entered. Please check it and re-enter.", + title: "The URL You Entered Cannot Be Found", }, }, }, @@ -260,14 +260,15 @@ export const en = { appCannotGetUtxos: "Application can not get utxos", checkIsWalletConnected: "Check if the wallet is connected.", dRepIdNotFound: "DrepId not found", - notUsingAnchor: "DRep Registration - not using anchor", + invalidGovernanceActionType: "Invalid Governance Action Type", noAddressesFound: "No addresses found", noStakeKeySelected: "No stake key selected", + notUsingAnchor: "DRep Registration - not using anchor", registeringStakeKey: "Registering stake key", somethingWentWrong: "Something went wrong", - useCardano: "useCardano must be used within a CardanoProvider", tryingConnectTo: "You are trying to connect with a wallet connected to {{networkFrom}}. Please adjust your wallet settings to connect to {{networkTo}} or select a different wallet.", + useCardano: "useCardano must be used within a CardanoProvider", walletNoCIP30Nor90Support: "Your wallet does not support the required CIP-30 extension, CIP-95.", walletNoCIP30Support: "Your wallet does not support CIP-30 extensions.", From 7f12a1c4d4efa3e49fb2fb48fc49c6b69449071f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 14 Mar 2024 11:17:09 +0100 Subject: [PATCH 12/20] [#364] fix: i18n labels of storage information screen --- govtool/frontend/src/i18n/locales/en.ts | 37 +++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 98999d447..b32f08b3b 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -169,24 +169,6 @@ export const en = { placeholder: "A name for this Action", }, }, - formTitle: "Governance Action details", - references: "References and Supporting Information", - reviewSubmission: "Review your submission", - storeDataCheckboxLabel: - "I agree to store correctly this information and to maintain them over the years", - storeDataLink: "Learn more about storing information", - storeDataTitle: "Store and Maintain the Data Yourself", - storingInformationDescription: - "Download your file, save it to your chosen location, and enter the URL of that location in step 3", - storingInformationStep1Label: "Download this file", - storingInformationStep2Label: - "Save this file in a location that provides a public URL (ex. github)", - storingInformationStep2Link: "Read full guide", - storingInformationStep3Label: "Paste the URL here", - storingInformationTitle: "Information Storage Steps", - storingInformationURLPlaceholder: "URL", - supportingLinks: "Supporting links", - title: "Create a Governance Action", validations: { bech32: "Invalid bech32 address", maxLength: "Max {{maxLength}} characters", @@ -195,6 +177,24 @@ export const en = { url: "Invalid URL", }, }, + formTitle: "Governance Action details", + references: "References and Supporting Information", + reviewSubmission: "Review your submission", + storeDataCheckboxLabel: + "I agree to store correctly this information and to maintain them over the years", + storeDataLink: "Learn more about storing information", + storeDataTitle: "Store and Maintain the Data Yourself", + storingInformationDescription: + "Download your file, save it to your chosen location, and enter the URL of that location in step 3", + storingInformationStep1Label: "Download this file", + storingInformationStep2Label: + "Save this file in a location that provides a public URL (ex. github)", + storingInformationStep2Link: "Read full guide", + storingInformationStep3Label: "Paste the URL here", + storingInformationTitle: "Information Storage Steps", + storingInformationURLPlaceholder: "URL", + supportingLinks: "Supporting links", + title: "Create a Governance Action", modals: { externalDataDoesntMatch: { buttonText: "Go to Data Edit Screen", @@ -261,6 +261,7 @@ export const en = { checkIsWalletConnected: "Check if the wallet is connected.", dRepIdNotFound: "DrepId not found", invalidGovernanceActionType: "Invalid Governance Action Type", + invalidTreasuryGovernanceActionType: "Invalid Treasury Governance Action", noAddressesFound: "No addresses found", noStakeKeySelected: "No stake key selected", notUsingAnchor: "DRep Registration - not using anchor", From b65aa9fc33fec37d8d86993ca0a4902945ccbc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 14 Mar 2024 11:17:09 +0100 Subject: [PATCH 13/20] [#364] fix: i18n labels of storage information screen --- govtool/frontend/src/i18n/locales/en.ts | 37 +++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 98999d447..b32f08b3b 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -169,24 +169,6 @@ export const en = { placeholder: "A name for this Action", }, }, - formTitle: "Governance Action details", - references: "References and Supporting Information", - reviewSubmission: "Review your submission", - storeDataCheckboxLabel: - "I agree to store correctly this information and to maintain them over the years", - storeDataLink: "Learn more about storing information", - storeDataTitle: "Store and Maintain the Data Yourself", - storingInformationDescription: - "Download your file, save it to your chosen location, and enter the URL of that location in step 3", - storingInformationStep1Label: "Download this file", - storingInformationStep2Label: - "Save this file in a location that provides a public URL (ex. github)", - storingInformationStep2Link: "Read full guide", - storingInformationStep3Label: "Paste the URL here", - storingInformationTitle: "Information Storage Steps", - storingInformationURLPlaceholder: "URL", - supportingLinks: "Supporting links", - title: "Create a Governance Action", validations: { bech32: "Invalid bech32 address", maxLength: "Max {{maxLength}} characters", @@ -195,6 +177,24 @@ export const en = { url: "Invalid URL", }, }, + formTitle: "Governance Action details", + references: "References and Supporting Information", + reviewSubmission: "Review your submission", + storeDataCheckboxLabel: + "I agree to store correctly this information and to maintain them over the years", + storeDataLink: "Learn more about storing information", + storeDataTitle: "Store and Maintain the Data Yourself", + storingInformationDescription: + "Download your file, save it to your chosen location, and enter the URL of that location in step 3", + storingInformationStep1Label: "Download this file", + storingInformationStep2Label: + "Save this file in a location that provides a public URL (ex. github)", + storingInformationStep2Link: "Read full guide", + storingInformationStep3Label: "Paste the URL here", + storingInformationTitle: "Information Storage Steps", + storingInformationURLPlaceholder: "URL", + supportingLinks: "Supporting links", + title: "Create a Governance Action", modals: { externalDataDoesntMatch: { buttonText: "Go to Data Edit Screen", @@ -261,6 +261,7 @@ export const en = { checkIsWalletConnected: "Check if the wallet is connected.", dRepIdNotFound: "DrepId not found", invalidGovernanceActionType: "Invalid Governance Action Type", + invalidTreasuryGovernanceActionType: "Invalid Treasury Governance Action", noAddressesFound: "No addresses found", noStakeKeySelected: "No stake key selected", notUsingAnchor: "DRep Registration - not using anchor", From 5d15dc9cc2e651dfee2db85718f57c1534d5b996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Thu, 14 Mar 2024 14:42:09 +0100 Subject: [PATCH 14/20] [#462] [#463] fix cards width and fonts for RWDs --- .../src/components/atoms/Typography.tsx | 4 +-- .../src/components/molecules/ActionCard.tsx | 24 +++++----------- .../ReviewCreatedGovernanceAction.tsx | 2 +- .../components/organisms/DashboardCards.tsx | 28 +++++++++---------- .../src/components/organisms/Hero.tsx | 2 +- .../src/components/organisms/HomeCards.tsx | 10 +++++-- .../src/components/organisms/TopNav.tsx | 4 +-- 7 files changed, 34 insertions(+), 40 deletions(-) diff --git a/govtool/frontend/src/components/atoms/Typography.tsx b/govtool/frontend/src/components/atoms/Typography.tsx index 1bcaf6131..34e1af742 100644 --- a/govtool/frontend/src/components/atoms/Typography.tsx +++ b/govtool/frontend/src/components/atoms/Typography.tsx @@ -8,7 +8,7 @@ export const Typography = ({ }: TypographyProps) => { const fontSize = { headline1: 100, - headline2: 50, + headline2: 57, headline3: 36, headline4: 32, headline5: 28, @@ -21,7 +21,7 @@ export const Typography = ({ const fontWeight = { headline1: 600, - headline2: 600, + headline2: 700, headline3: 400, headline4: 600, headline5: 500, diff --git a/govtool/frontend/src/components/molecules/ActionCard.tsx b/govtool/frontend/src/components/molecules/ActionCard.tsx index 2ac0dd63f..548af7091 100644 --- a/govtool/frontend/src/components/molecules/ActionCard.tsx +++ b/govtool/frontend/src/components/molecules/ActionCard.tsx @@ -33,7 +33,7 @@ export const ActionCard: FC = ({ ...props }) => { secondButtonLabel, title, } = props; - const { isMobile, screenWidth } = useScreenDimension(); + const { screenWidth } = useScreenDimension(); const { palette: { boxShadow2 }, @@ -52,23 +52,14 @@ export const ActionCard: FC = ({ ...props }) => { > {imageURL ? ( - + ) : null} {title ? ( {title} @@ -79,9 +70,8 @@ export const ActionCard: FC = ({ ...props }) => { sx={{ mb: 4.25, mt: 1.75, - textAlign: screenWidth < 640 ? "center" : "left", }} - variant={isMobile ? "body2" : "body1"} + variant={"body1"} > {description} @@ -103,11 +93,11 @@ export const ActionCard: FC = ({ ...props }) => { data-testid={dataTestIdSecondButton} onClick={secondButtonAction} sx={{ - visibility: secondButtonLabel ? "visible" : "hidden", + display: !secondButtonLabel && screenWidth < 768 ? "none" : "block", ml: screenWidth < 640 ? 0 : 2, mt: screenWidth < 640 ? 2 : 0, + visibility: secondButtonLabel ? "visible" : "hidden", width: screenWidth < 640 ? "100%" : "auto", - display: !secondButtonLabel && screenWidth < 768 ? "none" : "block", }} variant="outlined" > diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx index aaefa6d6f..0d8e74b33 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx @@ -58,7 +58,7 @@ export const ReviewCreatedGovernanceAction = ({ {label} {value as string} diff --git a/govtool/frontend/src/components/organisms/DashboardCards.tsx b/govtool/frontend/src/components/organisms/DashboardCards.tsx index ed3fefc52..ffa2e6c99 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards.tsx @@ -33,7 +33,7 @@ export const DashboardCards = () => { const navigate = useNavigate(); const { currentDelegation, isCurrentDelegationLoading } = useGetAdaHolderCurrentDelegationQuery(stakeKey); - const { isMobile, screenWidth } = useScreenDimension(); + const { screenWidth } = useScreenDimension(); const { openModal } = useModal(); const [isRetirementLoading, setIsRetirementLoading] = useState(false); @@ -187,13 +187,12 @@ export const DashboardCards = () => { ); const onClickGovernanceActionCardActionButton = useCallback(() => { - if(govActionTransaction.transactionHash) { - navigate(PATHS.dashboardGovernanceActions) - return + if (govActionTransaction.transactionHash) { + navigate(PATHS.dashboardGovernanceActions); + return; } - navigate(PATHS.createGovernanceAction) - - }, [govActionTransaction.transactionHash, navigate]) + navigate(PATHS.createGovernanceAction); + }, [govActionTransaction.transactionHash, navigate]); const displayedDelegationId = useMemo(() => { const restrictedNames = [ @@ -333,11 +332,12 @@ export const DashboardCards = () => { display: "grid", gridTemplateColumns: screenWidth < 1280 - ? "1fr" - : screenWidth > 1728 - ? "repeat(3, minmax(300px, 572px))" - : "repeat(2, minmax(300px, 572px))", - px: isMobile ? 2 : 5, + ? "repeat(1, minmax(300px, 530px))" + : screenWidth >= 1728 + ? "repeat(3, minmax(300px, 570px))" + : "repeat(2, minmax(300px, 530px))", + justifyContent: screenWidth < 1024 ? "center" : "flex-start", + px: screenWidth < 640 ? 2 : 5, py: 3, rowGap: 3, }} @@ -538,9 +538,9 @@ export const DashboardCards = () => { firstButtonAction={onClickGovernanceActionCardActionButton} firstButtonLabel={t( `dashboard.proposeGovernanceAction.${ - govActionTransaction.transactionHash ? "view" : "propose" + govActionTransaction.transactionHash ? "view" : "propose" }` - )} + )} inProgress={!!govActionTransaction.transactionHash} secondButtonLabel={t("learnMore")} secondButtonAction={() => diff --git a/govtool/frontend/src/components/organisms/Hero.tsx b/govtool/frontend/src/components/organisms/Hero.tsx index bdc6bcbbe..baae0bca4 100644 --- a/govtool/frontend/src/components/organisms/Hero.tsx +++ b/govtool/frontend/src/components/organisms/Hero.tsx @@ -38,7 +38,7 @@ export const Hero = () => { {t("hero.headline")} diff --git a/govtool/frontend/src/components/organisms/HomeCards.tsx b/govtool/frontend/src/components/organisms/HomeCards.tsx index 4539587c1..fca3f2c2c 100644 --- a/govtool/frontend/src/components/organisms/HomeCards.tsx +++ b/govtool/frontend/src/components/organisms/HomeCards.tsx @@ -53,9 +53,13 @@ export const HomeCards = () => { return ( = 1920 ? "1fr 1fr" : "1fr"} + gridTemplateColumns={ + screenWidth < 2560 + ? "repeat(1, minmax(300px, 866px))" + : "repeat(2, minmax(300px, 866px))" + } justifyItems="center" mb={screenWidth < 640 ? 10 : 17} mt={screenWidth < 640 ? 10 : 14.5} @@ -68,7 +72,7 @@ export const HomeCards = () => { ? 10 : 34 } - rowGap={5} + rowGap={4.625} > {/* DELEGATE CARD */} { : "transparent", borderBottom: isMobile ? 1 : 0, borderColor: "lightblue", + borderRadius: 0, boxShadow: 0, justifyContent: "center", flex: 1, From 1b6b1633f438eeb2d3bc4859a8584cc7c2f440e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 14 Mar 2024 15:18:39 +0100 Subject: [PATCH 15/20] [#451] fix: whitelist any jsonld file in CSP --- CHANGELOG.md | 2 ++ scripts/govtool/config/templates/docker-compose.yml.tpl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cb0840cf..0188ff91d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ As a minor extension, we also keep a semantic version for the `UNRELEASED` changes. ## [Unreleased] + - Add generate jsonld function [Issue 451](https://github.com/IntersectMBO/govtool/issues/451) - Create GA review subbmision page [Issue 362](https://github.com/IntersectMBO/govtool/issues/362) - Create GA creation form [Issue 360](https://github.com/IntersectMBO/govtool/issues/360) @@ -16,6 +17,7 @@ changes. - Choose GA type - GA Submiter [Issue 358](https://github.com/IntersectMBO/govtool/issues/358) - Add on-chain inputs validation [Issue 377](https://github.com/IntersectMBO/govtool/issues/377) - Add hash and validation of the metadata [Issue 378](https://github.com/IntersectMBO/govtool/issues/378) +- Add githubusercontent.com and ipfs.io to content security policy header [Issue 451](https://github.com/IntersectMBO/govtool/issues/451) ### Added diff --git a/scripts/govtool/config/templates/docker-compose.yml.tpl b/scripts/govtool/config/templates/docker-compose.yml.tpl index 9ef1ce811..03c05abee 100644 --- a/scripts/govtool/config/templates/docker-compose.yml.tpl +++ b/scripts/govtool/config/templates/docker-compose.yml.tpl @@ -225,7 +225,7 @@ services: - "traefik.http.routers.frontend.rule=Host(``)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.routers.frontend.tls.certresolver=myresolver" - - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" + - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com *.githubusercontent.com *.ipfs.io; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" - "traefik.http.routers.frontend.middlewares=frontend-csp@docker" - "traefik.http.services.frontend.loadbalancer.server.port=80" From 4e348fa5378775fe28cde90c85751445fec1a460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Thu, 14 Mar 2024 23:14:42 +0100 Subject: [PATCH 16/20] [#481] ]wrap too long link --- govtool/frontend/src/components/organisms/ExternalLinkModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx b/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx index 77d2cf509..2a111ed6f 100644 --- a/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx +++ b/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx @@ -42,6 +42,7 @@ export function ExternalLinkModal() { marginBottom: "38px", color: primaryBlue, textDecoration: "underline", + wordBreak: "break-word", }} > {state?.externalLink} From e662a3f67624d42bf0feb489633c1a94f85e7a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Thu, 14 Mar 2024 14:42:09 +0100 Subject: [PATCH 17/20] [#462] [#463] fix cards width and fonts for RWDs --- .../src/components/atoms/Typography.tsx | 4 +-- .../src/components/molecules/ActionCard.tsx | 24 +++++----------- .../ReviewCreatedGovernanceAction.tsx | 2 +- .../components/organisms/DashboardCards.tsx | 28 +++++++++---------- .../src/components/organisms/Hero.tsx | 2 +- .../src/components/organisms/HomeCards.tsx | 10 +++++-- .../src/components/organisms/TopNav.tsx | 4 +-- 7 files changed, 34 insertions(+), 40 deletions(-) diff --git a/govtool/frontend/src/components/atoms/Typography.tsx b/govtool/frontend/src/components/atoms/Typography.tsx index 1bcaf6131..34e1af742 100644 --- a/govtool/frontend/src/components/atoms/Typography.tsx +++ b/govtool/frontend/src/components/atoms/Typography.tsx @@ -8,7 +8,7 @@ export const Typography = ({ }: TypographyProps) => { const fontSize = { headline1: 100, - headline2: 50, + headline2: 57, headline3: 36, headline4: 32, headline5: 28, @@ -21,7 +21,7 @@ export const Typography = ({ const fontWeight = { headline1: 600, - headline2: 600, + headline2: 700, headline3: 400, headline4: 600, headline5: 500, diff --git a/govtool/frontend/src/components/molecules/ActionCard.tsx b/govtool/frontend/src/components/molecules/ActionCard.tsx index 2ac0dd63f..548af7091 100644 --- a/govtool/frontend/src/components/molecules/ActionCard.tsx +++ b/govtool/frontend/src/components/molecules/ActionCard.tsx @@ -33,7 +33,7 @@ export const ActionCard: FC = ({ ...props }) => { secondButtonLabel, title, } = props; - const { isMobile, screenWidth } = useScreenDimension(); + const { screenWidth } = useScreenDimension(); const { palette: { boxShadow2 }, @@ -52,23 +52,14 @@ export const ActionCard: FC = ({ ...props }) => { > {imageURL ? ( - + ) : null} {title ? ( {title} @@ -79,9 +70,8 @@ export const ActionCard: FC = ({ ...props }) => { sx={{ mb: 4.25, mt: 1.75, - textAlign: screenWidth < 640 ? "center" : "left", }} - variant={isMobile ? "body2" : "body1"} + variant={"body1"} > {description} @@ -103,11 +93,11 @@ export const ActionCard: FC = ({ ...props }) => { data-testid={dataTestIdSecondButton} onClick={secondButtonAction} sx={{ - visibility: secondButtonLabel ? "visible" : "hidden", + display: !secondButtonLabel && screenWidth < 768 ? "none" : "block", ml: screenWidth < 640 ? 0 : 2, mt: screenWidth < 640 ? 2 : 0, + visibility: secondButtonLabel ? "visible" : "hidden", width: screenWidth < 640 ? "100%" : "auto", - display: !secondButtonLabel && screenWidth < 768 ? "none" : "block", }} variant="outlined" > diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx index aaefa6d6f..0d8e74b33 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/ReviewCreatedGovernanceAction.tsx @@ -58,7 +58,7 @@ export const ReviewCreatedGovernanceAction = ({ {label} {value as string} diff --git a/govtool/frontend/src/components/organisms/DashboardCards.tsx b/govtool/frontend/src/components/organisms/DashboardCards.tsx index ed3fefc52..ffa2e6c99 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards.tsx @@ -33,7 +33,7 @@ export const DashboardCards = () => { const navigate = useNavigate(); const { currentDelegation, isCurrentDelegationLoading } = useGetAdaHolderCurrentDelegationQuery(stakeKey); - const { isMobile, screenWidth } = useScreenDimension(); + const { screenWidth } = useScreenDimension(); const { openModal } = useModal(); const [isRetirementLoading, setIsRetirementLoading] = useState(false); @@ -187,13 +187,12 @@ export const DashboardCards = () => { ); const onClickGovernanceActionCardActionButton = useCallback(() => { - if(govActionTransaction.transactionHash) { - navigate(PATHS.dashboardGovernanceActions) - return + if (govActionTransaction.transactionHash) { + navigate(PATHS.dashboardGovernanceActions); + return; } - navigate(PATHS.createGovernanceAction) - - }, [govActionTransaction.transactionHash, navigate]) + navigate(PATHS.createGovernanceAction); + }, [govActionTransaction.transactionHash, navigate]); const displayedDelegationId = useMemo(() => { const restrictedNames = [ @@ -333,11 +332,12 @@ export const DashboardCards = () => { display: "grid", gridTemplateColumns: screenWidth < 1280 - ? "1fr" - : screenWidth > 1728 - ? "repeat(3, minmax(300px, 572px))" - : "repeat(2, minmax(300px, 572px))", - px: isMobile ? 2 : 5, + ? "repeat(1, minmax(300px, 530px))" + : screenWidth >= 1728 + ? "repeat(3, minmax(300px, 570px))" + : "repeat(2, minmax(300px, 530px))", + justifyContent: screenWidth < 1024 ? "center" : "flex-start", + px: screenWidth < 640 ? 2 : 5, py: 3, rowGap: 3, }} @@ -538,9 +538,9 @@ export const DashboardCards = () => { firstButtonAction={onClickGovernanceActionCardActionButton} firstButtonLabel={t( `dashboard.proposeGovernanceAction.${ - govActionTransaction.transactionHash ? "view" : "propose" + govActionTransaction.transactionHash ? "view" : "propose" }` - )} + )} inProgress={!!govActionTransaction.transactionHash} secondButtonLabel={t("learnMore")} secondButtonAction={() => diff --git a/govtool/frontend/src/components/organisms/Hero.tsx b/govtool/frontend/src/components/organisms/Hero.tsx index bdc6bcbbe..baae0bca4 100644 --- a/govtool/frontend/src/components/organisms/Hero.tsx +++ b/govtool/frontend/src/components/organisms/Hero.tsx @@ -38,7 +38,7 @@ export const Hero = () => { {t("hero.headline")} diff --git a/govtool/frontend/src/components/organisms/HomeCards.tsx b/govtool/frontend/src/components/organisms/HomeCards.tsx index 4539587c1..fca3f2c2c 100644 --- a/govtool/frontend/src/components/organisms/HomeCards.tsx +++ b/govtool/frontend/src/components/organisms/HomeCards.tsx @@ -53,9 +53,13 @@ export const HomeCards = () => { return ( = 1920 ? "1fr 1fr" : "1fr"} + gridTemplateColumns={ + screenWidth < 2560 + ? "repeat(1, minmax(300px, 866px))" + : "repeat(2, minmax(300px, 866px))" + } justifyItems="center" mb={screenWidth < 640 ? 10 : 17} mt={screenWidth < 640 ? 10 : 14.5} @@ -68,7 +72,7 @@ export const HomeCards = () => { ? 10 : 34 } - rowGap={5} + rowGap={4.625} > {/* DELEGATE CARD */} { : "transparent", borderBottom: isMobile ? 1 : 0, borderColor: "lightblue", + borderRadius: 0, boxShadow: 0, justifyContent: "center", flex: 1, From fa32861f78f525853a8aa0fa68b25471f0b35634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 14 Mar 2024 15:18:39 +0100 Subject: [PATCH 18/20] [#451] fix: whitelist any jsonld file in CSP --- CHANGELOG.md | 2 ++ scripts/govtool/config/templates/docker-compose.yml.tpl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cb0840cf..0188ff91d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ As a minor extension, we also keep a semantic version for the `UNRELEASED` changes. ## [Unreleased] + - Add generate jsonld function [Issue 451](https://github.com/IntersectMBO/govtool/issues/451) - Create GA review subbmision page [Issue 362](https://github.com/IntersectMBO/govtool/issues/362) - Create GA creation form [Issue 360](https://github.com/IntersectMBO/govtool/issues/360) @@ -16,6 +17,7 @@ changes. - Choose GA type - GA Submiter [Issue 358](https://github.com/IntersectMBO/govtool/issues/358) - Add on-chain inputs validation [Issue 377](https://github.com/IntersectMBO/govtool/issues/377) - Add hash and validation of the metadata [Issue 378](https://github.com/IntersectMBO/govtool/issues/378) +- Add githubusercontent.com and ipfs.io to content security policy header [Issue 451](https://github.com/IntersectMBO/govtool/issues/451) ### Added diff --git a/scripts/govtool/config/templates/docker-compose.yml.tpl b/scripts/govtool/config/templates/docker-compose.yml.tpl index 9ef1ce811..03c05abee 100644 --- a/scripts/govtool/config/templates/docker-compose.yml.tpl +++ b/scripts/govtool/config/templates/docker-compose.yml.tpl @@ -225,7 +225,7 @@ services: - "traefik.http.routers.frontend.rule=Host(``)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.routers.frontend.tls.certresolver=myresolver" - - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" + - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com *.githubusercontent.com *.ipfs.io; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" - "traefik.http.routers.frontend.middlewares=frontend-csp@docker" - "traefik.http.services.frontend.loadbalancer.server.port=80" From 5b409c4ac887f832166cff4f2923fba17603bbac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Thu, 14 Mar 2024 23:14:42 +0100 Subject: [PATCH 19/20] [#481] ]wrap too long link --- govtool/frontend/src/components/organisms/ExternalLinkModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx b/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx index 77d2cf509..2a111ed6f 100644 --- a/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx +++ b/govtool/frontend/src/components/organisms/ExternalLinkModal.tsx @@ -42,6 +42,7 @@ export function ExternalLinkModal() { marginBottom: "38px", color: primaryBlue, textDecoration: "underline", + wordBreak: "break-word", }} > {state?.externalLink} From 88e2a2bc19e8536222030822d1f14e3cb40f93c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 15 Mar 2024 16:28:19 +0100 Subject: [PATCH 20/20] [#377] fix: validation of ada amount --- .../src/consts/governanceAction/fields.ts | 18 +++++++++++++++--- govtool/frontend/src/i18n/locales/en.ts | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/govtool/frontend/src/consts/governanceAction/fields.ts b/govtool/frontend/src/consts/governanceAction/fields.ts index daf66244f..1dbe762c1 100644 --- a/govtool/frontend/src/consts/governanceAction/fields.ts +++ b/govtool/frontend/src/consts/governanceAction/fields.ts @@ -119,9 +119,21 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = { value: true, message: I18n.t("createGovernanceAction.fields.validations.required"), }, - validate: (value) => - Number.isInteger(Number(value)) || - I18n.t("createGovernanceAction.fields.validations.number"), + validate: (value) => { + const parsedValue = Number( + value.includes(",") ? value.replace(",", ".") : value + ); + + if (isNaN(parsedValue)) { + return I18n.t("createGovernanceAction.fields.validations.number"); + } + + if (parsedValue < 0) { + return I18n.t("createGovernanceAction.fields.validations.positive"); + } + + return true; + }, }, }, }, diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index b32f08b3b..166d05af5 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -175,6 +175,7 @@ export const en = { number: "Only number is allowed", required: "This field is required", url: "Invalid URL", + positive: "Only positive number is allowed", }, }, formTitle: "Governance Action details",