summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-10-22 01:31:46 -0300
committerSebastian <sebasjm@gmail.com>2021-10-22 01:31:46 -0300
commit2ec2161a7e1c0787b5e9ea14311f19c6b6a52d63 (patch)
treeef06a4edcb6b35f1743878f3a4cd77edc752a76f
parent3740010117df56c0ab8cfa97c983d9cf0143daf1 (diff)
downloadwallet-core-2ec2161a7e1c0787b5e9ea14311f19c6b6a52d63.tar.gz
wallet-core-2ec2161a7e1c0787b5e9ea14311f19c6b6a52d63.tar.bz2
wallet-core-2ec2161a7e1c0787b5e9ea14311f19c6b6a52d63.zip
some storybook exmaples
-rw-r--r--packages/anastasis-core/src/reducer-types.ts6
-rw-r--r--packages/anastasis-webui/.gitignore1
-rw-r--r--packages/anastasis-webui/.storybook/.babelrc25
-rw-r--r--packages/anastasis-webui/.storybook/main.js57
-rw-r--r--packages/anastasis-webui/.storybook/preview.js49
-rw-r--r--packages/anastasis-webui/package.json10
-rw-r--r--packages/anastasis-webui/src/components/menu/SideBar.tsx164
-rw-r--r--packages/anastasis-webui/src/context/anastasis.ts41
-rw-r--r--packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx63
-rw-r--r--packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx25
-rw-r--r--packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx35
-rw-r--r--packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx19
-rw-r--r--packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx60
-rw-r--r--packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx26
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx83
-rw-r--r--packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx39
-rw-r--r--packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx36
-rw-r--r--packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx17
-rw-r--r--packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx36
-rw-r--r--packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx20
-rw-r--r--packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx47
-rw-r--r--packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx18
-rw-r--r--packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx42
-rw-r--r--packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx24
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx81
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx42
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx44
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx25
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx50
-rw-r--r--packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx37
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveEmailEntry.tsx13
-rw-r--r--packages/anastasis-webui/src/pages/home/SolvePostEntry.tsx11
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveQuestionEntry.tsx11
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx121
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveScreen.tsx32
-rw-r--r--packages/anastasis-webui/src/pages/home/SolveSmsEntry.tsx13
-rw-r--r--packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx35
-rw-r--r--packages/anastasis-webui/src/pages/home/StartScreen.tsx32
-rw-r--r--packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx40
-rw-r--r--packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx16
-rw-r--r--packages/anastasis-webui/src/pages/home/index.tsx162
-rw-r--r--packages/anastasis-webui/src/utils/index.tsx161
-rw-r--r--pnpm-lock.yaml1139
43 files changed, 2725 insertions, 283 deletions
diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts
index f7ba9e0f1..1a443bf9b 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -23,7 +23,7 @@ export interface Policy {
authentication_method: number;
provider: string;
}[];
-}
+}
export interface PolicyProvider {
provider_url: string;
@@ -51,7 +51,7 @@ export interface ReducerStateBackup {
identity_attributes?: { [n: string]: string };
authentication_providers?: { [url: string]: AuthenticationProviderStatus };
authentication_methods?: AuthMethod[];
- required_attributes?: any;
+ required_attributes?: UserAttributeSpec[];
selected_continent?: string;
selected_country?: string;
secret_name?: string;
@@ -133,7 +133,7 @@ export interface ReducerStateRecovery {
selected_country?: string;
currencies?: string[];
- required_attributes?: any;
+ required_attributes?: UserAttributeSpec[];
/**
* Recovery information, used by the UI.
diff --git a/packages/anastasis-webui/.gitignore b/packages/anastasis-webui/.gitignore
index 5baa9defe..32d0a5057 100644
--- a/packages/anastasis-webui/.gitignore
+++ b/packages/anastasis-webui/.gitignore
@@ -2,3 +2,4 @@ node_modules
/build
/*.log
/size-plugin.json
+/storybook-static/
diff --git a/packages/anastasis-webui/.storybook/.babelrc b/packages/anastasis-webui/.storybook/.babelrc
new file mode 100644
index 000000000..610b6f339
--- /dev/null
+++ b/packages/anastasis-webui/.storybook/.babelrc
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+{
+ "presets": [
+ "preact-cli/babel"
+ ]
+} \ No newline at end of file
diff --git a/packages/anastasis-webui/.storybook/main.js b/packages/anastasis-webui/.storybook/main.js
new file mode 100644
index 000000000..f8e4bbcc7
--- /dev/null
+++ b/packages/anastasis-webui/.storybook/main.js
@@ -0,0 +1,57 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+module.exports = {
+ "stories": [
+ "../src/**/*.stories.mdx",
+ "../src/**/*.stories.@(js|jsx|ts|tsx)"
+ ],
+ "addons": [
+ "@storybook/preset-scss",
+ "@storybook/addon-a11y",
+ "@storybook/addon-essentials" //docs, control, actions, viewpot, toolbar, background
+ ],
+ // sb does not yet support new jsx transform by default
+ // https://github.com/storybookjs/storybook/issues/12881
+ // https://github.com/storybookjs/storybook/issues/12952
+ babel: async (options) => ({
+ ...options,
+ presets: [
+ ...options.presets,
+ [
+ '@babel/preset-react', {
+ runtime: 'automatic',
+ },
+ 'preset-react-jsx-transform'
+ ],
+ ],
+ }),
+ webpackFinal: (config) => {
+ // should be removed after storybook 6.3
+ // https://github.com/storybookjs/storybook/issues/12853#issuecomment-821576113
+ config.resolve.alias = {
+ react: "preact/compat",
+ "react-dom": "preact/compat",
+ };
+ return config;
+ },
+} \ No newline at end of file
diff --git a/packages/anastasis-webui/.storybook/preview.js b/packages/anastasis-webui/.storybook/preview.js
new file mode 100644
index 000000000..7cb9405ba
--- /dev/null
+++ b/packages/anastasis-webui/.storybook/preview.js
@@ -0,0 +1,49 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import "../src/scss/main.scss"
+import { TranslationProvider } from '../src/context/translation'
+import { h } from 'preact';
+
+
+export const parameters = {
+ controls: { expanded: true },
+}
+
+export const globalTypes = {
+ locale: {
+ name: 'Locale',
+ description: 'Internationalization locale',
+ defaultValue: 'en',
+ toolbar: {
+ icon: 'globe',
+ items: [
+ { value: 'en', right: 'πŸ‡ΊπŸ‡Έ', title: 'English' },
+ { value: 'es', right: 'πŸ‡ͺπŸ‡Έ', title: 'Spanish' },
+ ],
+ },
+ },
+};
+
+export const decorators = [
+ (Story, { globals }) => {
+ document.body.parentElement.classList = "has-aside-left has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded"
+ return <Story />
+ },
+ (Story, { globals }) => <TranslationProvider initial='en' forceLang={globals.locale}>
+ <Story />
+ </TranslationProvider>,
+];
diff --git a/packages/anastasis-webui/package.json b/packages/anastasis-webui/package.json
index 8f7711313..57cfdd8d4 100644
--- a/packages/anastasis-webui/package.json
+++ b/packages/anastasis-webui/package.json
@@ -8,7 +8,9 @@
"serve": "sirv build --port 8080 --cors --single",
"dev": "preact watch",
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
- "test": "jest ./tests"
+ "test": "jest ./tests",
+ "build-storybook": "build-storybook",
+ "storybook": "start-storybook -p 6006"
},
"eslintConfig": {
"parser": "@typescript-eslint/parser",
@@ -30,6 +32,12 @@
},
"devDependencies": {
"@creativebulma/bulma-tooltip": "^1.2.0",
+ "@storybook/addon-a11y": "^6.2.9",
+ "@storybook/addon-actions": "^6.2.9",
+ "@storybook/addon-essentials": "^6.2.9",
+ "@storybook/addon-links": "^6.2.9",
+ "@storybook/preact": "^6.2.9",
+ "@storybook/preset-scss": "^1.0.3",
"@types/enzyme": "^3.10.5",
"@types/jest": "^26.0.8",
"@typescript-eslint/eslint-plugin": "^2.25.0",
diff --git a/packages/anastasis-webui/src/components/menu/SideBar.tsx b/packages/anastasis-webui/src/components/menu/SideBar.tsx
index 628adb571..df582a5d0 100644
--- a/packages/anastasis-webui/src/components/menu/SideBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/SideBar.tsx
@@ -20,7 +20,9 @@
*/
-import { h, VNode } from 'preact';
+import { Fragment, h, VNode } from 'preact';
+import { BackupStates, RecoveryStates } from '../../../../anastasis-core/lib';
+import { useAnastasisContext } from '../../context/anastasis';
import { Translate } from '../../i18n';
import { LangSelector } from './LangSelector';
@@ -31,8 +33,9 @@ interface Props {
export function Sidebar({ mobile }: Props): VNode {
// const config = useConfigContext();
const config = { version: 'none' }
- const process = { env : { __VERSION__: '0.0.0'}}
-
+ const process = { env: { __VERSION__: '0.0.0' } }
+ const reducer = useAnastasisContext()!
+
return (
<aside class="aside is-placed-left is-expanded">
{mobile && <div class="footer" onClick={(e) => { return e.stopImmediatePropagation() }}>
@@ -47,52 +50,117 @@ export function Sidebar({ mobile }: Props): VNode {
</div>
</div>
<div class="menu is-menu-main">
- <p class="menu-label">
- <Translate>Back up a secret</Translate>
- </p>
+ {!reducer.currentReducerState &&
+ <p class="menu-label">
+ <Translate>Backup or Recorver</Translate>
+ </p>
+ }
<ul class="menu-list">
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-square-edit-outline" /></span>
- <span class="menu-item-label"><Translate>Location &amp; Currency</Translate></span>
- </div>
- </li>
- <li class="is-active">
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-cash-register" /></span>
- <span class="menu-item-label"><Translate>Personal information</Translate></span>
- </div>
- </li>
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-shopping" /></span>
- <span class="menu-item-label"><Translate>Authorization methods</Translate></span>
- </div>
- </li>
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-bank" /></span>
- <span class="menu-item-label"><Translate>Recovery policies</Translate></span>
- </div>
- </li>
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-bank" /></span>
- <span class="menu-item-label"><Translate>Enter secrets</Translate></span>
- </div>
- </li>
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-bank" /></span>
- <span class="menu-item-label"><Translate>Payment (optional)</Translate></span>
- </div>
- </li>
- <li>
- <div class="has-icon">
- <span class="icon"><i class="mdi mdi-cash" /></span>
- <span class="menu-item-label">Backup completed</span>
- </div>
- </li>
+ {!reducer.currentReducerState &&
+ <li>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>Start one options</Translate></span>
+ </div>
+ </li>
+ }
+ {reducer.currentReducerState && reducer.currentReducerState.backup_state ? <Fragment>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.ContinentSelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>Continent selection</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.CountrySelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>Country selection</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.UserAttributesCollecting ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>User attributes</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.AuthenticationsEditing ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>Auth methods</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.PoliciesReviewing ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>PoliciesReviewing</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.SecretEditing ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>SecretEditing</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.PoliciesPaying ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>PoliciesPaying</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.BackupFinished ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>BackupFinished</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.backup_state === BackupStates.TruthsPaying ? 'is-active' : ''}>
+ <div class="ml-4">
+
+ <span class="menu-item-label"><Translate>TruthsPaying</Translate></span>
+ </div>
+ </li>
+ </Fragment> : (reducer.currentReducerState && reducer.currentReducerState?.recovery_state && <Fragment>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.ContinentSelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>TruthsPaying</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.CountrySelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>CountrySelecting</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.UserAttributesCollecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>UserAttributesCollecting</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.SecretSelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>SecretSelecting</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.ChallengeSelecting ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>ChallengeSelecting</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.ChallengeSolving ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>ChallengeSolving</Translate></span>
+ </div>
+ </li>
+ <li class={reducer.currentReducerState.recovery_state === RecoveryStates.RecoveryFinished ? 'is-active' : ''}>
+ <div class="ml-4">
+ <span class="menu-item-label"><Translate>RecoveryFinished</Translate></span>
+ </div>
+ </li>
+ </Fragment>)}
+ {reducer.currentReducerState &&
+ <li>
+ <div class="buttons ml-4">
+ <button class="button is-danger is-right" onClick={() => reducer.reset()}>Reset session</button>
+ </div>
+ </li>
+ }
+
</ul>
</div>
</aside>
diff --git a/packages/anastasis-webui/src/context/anastasis.ts b/packages/anastasis-webui/src/context/anastasis.ts
new file mode 100644
index 000000000..e7f93ed43
--- /dev/null
+++ b/packages/anastasis-webui/src/context/anastasis.ts
@@ -0,0 +1,41 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext, h, VNode } from 'preact';
+import { useContext } from 'preact/hooks';
+import { AnastasisReducerApi } from '../hooks/use-anastasis-reducer';
+
+type Type = AnastasisReducerApi | undefined;
+
+const initial = undefined
+
+const Context = createContext<Type>(initial)
+
+interface Props {
+ value: AnastasisReducerApi;
+ children: any;
+}
+
+export const AnastasisProvider = ({ value, children }: Props): VNode => {
+ return h(Context.Provider, { value, children });
+}
+
+export const useAnastasisContext = (): Type => useContext(Context); \ No newline at end of file
diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
new file mode 100644
index 000000000..d28a6df43
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
@@ -0,0 +1,63 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { AttributeEntryScreen as TestedComponent } from './AttributeEntryScreen';
+
+
+export default {
+ title: 'Pages/AttributeEntryScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const WithSomeAttributes = createExample(TestedComponent, {
+ ...reducerStatesExample.attributeEditing,
+ required_attributes: [{
+ name: 'first',
+ label: 'first',
+ type: 'type',
+ uuid: 'asdasdsa1',
+ widget: 'wid',
+ }, {
+ name: 'pepe',
+ label: 'second',
+ type: 'type',
+ uuid: 'asdasdsa2',
+ widget: 'wid',
+ }, {
+ name: 'pepe2',
+ label: 'third',
+ type: 'type',
+ uuid: 'asdasdsa3',
+ widget: 'calendar',
+ }]
+} as ReducerState);
+
+export const Empty = createExample(TestedComponent, {
+ ...reducerStatesExample.attributeEditing,
+ required_attributes: undefined
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
index 6f87a3358..2f804f940 100644
--- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
@@ -1,15 +1,24 @@
/* eslint-disable @typescript-eslint/camelcase */
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
-import { ReducerStateRecovery, ReducerStateBackup } from "../../../../anastasis-core/lib";
+import { ReducerStateRecovery, ReducerStateBackup, UserAttributeSpec } from "anastasis-core/lib";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisReducerApi } from "../../hooks/use-anastasis-reducer";
import { AnastasisClientFrame, withProcessLabel, LabeledInput } from "./index";
-export function AttributeEntryScreen(props: AttributeEntryProps): VNode {
- const { reducer, reducerState: backupState } = props;
- const [attrs, setAttrs] = useState<Record<string, string>>(
- props.reducerState.identity_attributes ?? {}
- );
+export function AttributeEntryScreen(): VNode {
+ const reducer = useAnastasisContext()
+ const state = reducer?.currentReducerState
+ const currentIdentityAttributes = state && "identity_attributes" in state ? (state.identity_attributes || {}) : {}
+ const [attrs, setAttrs] = useState<Record<string, string>>(currentIdentityAttributes);
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || !("required_attributes" in reducer.currentReducerState)) {
+ return <div>invalid state</div>
+ }
+
return (
<AnastasisClientFrame
title={withProcessLabel(reducer, "Select Country")}
@@ -17,7 +26,7 @@ export function AttributeEntryScreen(props: AttributeEntryProps): VNode {
identity_attributes: attrs,
})}
>
- {backupState.required_attributes.map((x: any, i: number) => {
+ {reducer.currentReducerState.required_attributes?.map((x, i: number) => {
return (
<AttributeEntryField
key={i}
@@ -40,7 +49,7 @@ export interface AttributeEntryFieldProps {
isFirst: boolean;
value: string;
setValue: (newValue: string) => void;
- spec: any;
+ spec: UserAttributeSpec;
}
export function AttributeEntryField(props: AttributeEntryFieldProps): VNode {
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx
new file mode 100644
index 000000000..44d3795b2
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample, reducerStatesExample } from '../../utils';
+import { AuthenticationEditorScreen as TestedComponent } from './AuthenticationEditorScreen';
+
+
+export default {
+ title: 'Pages/AuthenticationEditorScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Example = createExample(TestedComponent, reducerStatesExample.authEditing);
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
index fc28942aa..e9ffccbac 100644
--- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/camelcase */
+import { AuthMethod, ReducerStateBackup } from "anastasis-core";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
-import { AuthMethod, ReducerStateBackup } from "anastasis-core";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisReducerApi } from "../../hooks/use-anastasis-reducer";
import { AuthMethodEmailSetup } from "./AuthMethodEmailSetup";
import { AuthMethodPostSetup } from "./AuthMethodPostSetup";
@@ -9,12 +10,18 @@ import { AuthMethodQuestionSetup } from "./AuthMethodQuestionSetup";
import { AuthMethodSmsSetup } from "./AuthMethodSmsSetup";
import { AnastasisClientFrame } from "./index";
-export function AuthenticationEditorScreen(props: AuthenticationEditorProps): VNode {
+export function AuthenticationEditorScreen(): VNode {
const [selectedMethod, setSelectedMethod] = useState<string | undefined>(
undefined
);
- const { reducer, backupState } = props;
- const providers = backupState.authentication_providers!;
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const providers = reducer.currentReducerState.authentication_providers!;
const authAvailableSet = new Set<string>();
for (const provKey of Object.keys(providers)) {
const p = providers[provKey];
@@ -52,14 +59,14 @@ export function AuthenticationEditorScreen(props: AuthenticationEditorProps): VN
disabled={!authAvailableSet.has(props.method)}
onClick={() => {
setSelectedMethod(props.method);
- reducer.dismissError();
+ if (reducer) reducer.dismissError();
}}
>
{props.label}
</button>
);
}
- const configuredAuthMethods: AuthMethod[] = backupState.authentication_methods ?? [];
+ const configuredAuthMethods: AuthMethod[] = reducer.currentReducerState.authentication_methods ?? [];
const haveMethodsConfigured = configuredAuthMethods.length;
return (
<AnastasisClientFrame title="Backup: Configure Authentication Methods">
diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
new file mode 100644
index 000000000..65a2b7e13
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
@@ -0,0 +1,60 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { BackupFinishedScreen as TestedComponent } from './BackupFinishedScreen';
+
+
+export default {
+ title: 'Pages/BackupFinishedScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Simple = createExample(TestedComponent, reducerStatesExample.backupFinished);
+
+export const WithName = createExample(TestedComponent, {...reducerStatesExample.backupFinished,
+ secret_name: 'super_secret',
+} as ReducerState);
+
+export const WithDetails = createExample(TestedComponent, {
+ ...reducerStatesExample.backupFinished,
+ secret_name: 'super_secret',
+ success_details: {
+ 'http://anastasis.net': {
+ policy_expiration: {
+ t_ms: 'never'
+ },
+ policy_version: 0
+ },
+ 'http://taler.net': {
+ policy_expiration: {
+ t_ms: new Date().getTime() + 60*60*24*1000
+ },
+ policy_version: 1
+ },
+ }
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
index 6c2770947..218f1d1fd 100644
--- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
@@ -1,23 +1,33 @@
import { h, VNode } from "preact";
-import { BackupReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
-export function BackupFinishedScreen(props: BackupReducerProps): VNode {
+export function BackupFinishedScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const details = reducer.currentReducerState.success_details
return (<AnastasisClientFrame hideNext title="Backup finished">
<p>
- Your backup of secret "{props.backupState.secret_name ?? "??"}" was
+ Your backup of secret "{reducer.currentReducerState.secret_name ?? "??"}" was
successful.
</p>
<p>The backup is stored by the following providers:</p>
- <ul>
- {Object.keys(props.backupState.success_details!).map((x, i) => {
- const sd = props.backupState.success_details![x];
+
+ {details && <ul>
+ {Object.keys(details).map((x, i) => {
+ const sd = details[x];
return (
<li key={i}>
{x} (Policy version {sd.policy_version})
</li>
);
})}
- </ul>
- <button onClick={() => props.reducer.reset()}>Back to start</button>
+ </ul>}
+ <button onClick={() => reducer.reset()}>Back to start</button>
</AnastasisClientFrame>);
}
diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
new file mode 100644
index 000000000..4f186c031
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
@@ -0,0 +1,83 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { ChallengeOverviewScreen as TestedComponent } from './ChallengeOverviewScreen';
+
+
+export default {
+ title: 'Pages/ChallengeOverviewScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const OneChallenge = createExample(TestedComponent, {...reducerStatesExample.challengeSelecting,
+ recovery_information: {
+ policies: [[{uuid:'1'}]],
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'just go for it',
+ type: 'question',
+ uuid: '1',
+ }]
+ },
+} as ReducerState);
+
+export const MoreChallenges = createExample(TestedComponent, {...reducerStatesExample.challengeSelecting,
+ recovery_information: {
+ policies: [[{uuid:'1'}, {uuid:'2'}],[{uuid:'3'}]],
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'just go for it',
+ type: 'question',
+ uuid: '1',
+ },{
+ cost: 'USD:1',
+ instructions: 'just go for it',
+ type: 'question',
+ uuid: '2',
+ },{
+ cost: 'USD:1',
+ instructions: 'just go for it',
+ type: 'question',
+ uuid: '3',
+ }]
+ },
+} as ReducerState);
+
+export const OneBadConfiguredPolicy = createExample(TestedComponent, {...reducerStatesExample.challengeSelecting,
+ recovery_information: {
+ policies: [[{uuid:'2'}]],
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'just go for it',
+ type: 'sasd',
+ uuid: '1',
+ }]
+ },
+} as ReducerState);
+
+export const NoPolicies = createExample(TestedComponent, reducerStatesExample.challengeSelecting);
diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
index 1f108ce6d..c9b52e91b 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
@@ -1,10 +1,21 @@
import { h, VNode } from "preact";
-import { RecoveryReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
+
+export function ChallengeOverviewScreen(): VNode {
+ const reducer = useAnastasisContext()
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
+ return <div>invalid state</div>
+ }
+
+ const policies = reducer.currentReducerState.recovery_information?.policies ?? [];
+ const chArr = reducer.currentReducerState.recovery_information?.challenges ?? [];
+ const challengeFeedback = reducer.currentReducerState?.challenge_feedback;
-export function ChallengeOverviewScreen(props: RecoveryReducerProps): VNode {
- const { recoveryState, reducer } = props;
- const policies = recoveryState.recovery_information!.policies;
- const chArr = recoveryState.recovery_information!.challenges;
const challenges: {
[uuid: string]: {
type: string;
@@ -22,15 +33,21 @@ export function ChallengeOverviewScreen(props: RecoveryReducerProps): VNode {
return (
<AnastasisClientFrame title="Recovery: Solve challenges">
<h2>Policies</h2>
- {policies.map((x, i) => {
+ {!policies.length && <p>
+ No policies found
+ </p>}
+ {policies.map((row, i) => {
return (
<div key={i}>
<h3>Policy #{i + 1}</h3>
- {x.map((x, j) => {
- const ch = challenges[x.uuid];
- const feedback = recoveryState.challenge_feedback?.[x.uuid];
+ {row.map(column => {
+ const ch = challenges[column.uuid];
+ if (!ch) return <div>
+ There is no challenge for this policy
+ </div>
+ const feedback = challengeFeedback?.[column.uuid];
return (
- <div key={j}
+ <div key={column.uuid}
style={{
borderLeft: "2px solid gray",
paddingLeft: "0.5em",
@@ -46,7 +63,7 @@ export function ChallengeOverviewScreen(props: RecoveryReducerProps): VNode {
{feedback?.state !== "solved" ? (
<button
onClick={() => reducer.transition("select_challenge", {
- uuid: x.uuid,
+ uuid: column.uuid,
})}
>
Solve
diff --git a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
new file mode 100644
index 000000000..aad37cd7f
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
@@ -0,0 +1,36 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample, reducerStatesExample } from '../../utils';
+import { ContinentSelectionScreen as TestedComponent } from './ContinentSelectionScreen';
+
+
+export default {
+ title: 'Pages/ContinentSelectionScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Backup = createExample(TestedComponent, reducerStatesExample.backupSelectCountry);
+export const Recovery = createExample(TestedComponent, reducerStatesExample.recoverySelectCountry);
diff --git a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
index 2fed23d4e..ad529a4a7 100644
--- a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
@@ -1,15 +1,16 @@
import { h, VNode } from "preact";
-import { CommonReducerProps, AnastasisClientFrame, withProcessLabel } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame, withProcessLabel } from "./index";
-export function ContinentSelectionScreen(props: CommonReducerProps): VNode {
- const { reducer, reducerState } = props;
+export function ContinentSelectionScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer || !reducer.currentReducerState || !("continents" in reducer.currentReducerState)) {
+ return <div />
+ }
const sel = (x: string): void => reducer.transition("select_continent", { continent: x });
return (
- <AnastasisClientFrame
- hideNext
- title={withProcessLabel(reducer, "Select Continent")}
- >
- {reducerState.continents.map((x: any) => (
+ <AnastasisClientFrame hideNext title={withProcessLabel(reducer, "Select Continent")}>
+ {reducer.currentReducerState.continents.map((x: any) => (
<button onClick={() => sel(x.name)} key={x.name}>
{x.name}
</button>
diff --git a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx
new file mode 100644
index 000000000..adf36980f
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx
@@ -0,0 +1,36 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample, reducerStatesExample } from '../../utils';
+import { CountrySelectionScreen as TestedComponent } from './CountrySelectionScreen';
+
+
+export default {
+ title: 'Pages/CountrySelectionScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Backup = createExample(TestedComponent, reducerStatesExample.backupSelectCountry);
+export const Recovery = createExample(TestedComponent, reducerStatesExample.recoverySelectCountry);
diff --git a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx
index dbe4b7616..555622c1d 100644
--- a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx
@@ -1,19 +1,23 @@
/* eslint-disable @typescript-eslint/camelcase */
import { h, VNode } from "preact";
-import { CommonReducerProps, AnastasisClientFrame, withProcessLabel } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame, withProcessLabel } from "./index";
-export function CountrySelectionScreen(props: CommonReducerProps): VNode {
- const { reducer, reducerState } = props;
+export function CountrySelectionScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || !("countries" in reducer.currentReducerState)) {
+ return <div>invalid state</div>
+ }
const sel = (x: any): void => reducer.transition("select_country", {
country_code: x.code,
currencies: [x.currency],
});
return (
- <AnastasisClientFrame
- hideNext
- title={withProcessLabel(reducer, "Select Country")}
- >
- {reducerState.countries.map((x: any) => (
+ <AnastasisClientFrame hideNext title={withProcessLabel(reducer, "Select Country")} >
+ {reducer.currentReducerState.countries.map((x: any) => (
<button onClick={() => sel(x)} key={x.name}>
{x.name} ({x.currency})
</button>
diff --git a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx
new file mode 100644
index 000000000..1a9462b88
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx
@@ -0,0 +1,47 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { PoliciesPayingScreen as TestedComponent } from './PoliciesPayingScreen';
+
+
+export default {
+ title: 'Pages/PoliciesPayingScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Example = createExample(TestedComponent, reducerStatesExample.policyPay);
+export const WithSomePaymentRequest = createExample(TestedComponent, {
+ ...reducerStatesExample.policyPay,
+ policy_payment_requests: [{
+ payto: 'payto://x-taler-bank/bank.taler/account-a',
+ provider: 'provider1'
+ }, {
+ payto: 'payto://x-taler-bank/bank.taler/account-b',
+ provider: 'provider2'
+ }]
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
index be74729eb..8a39cf0e4 100644
--- a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.tsx
@@ -1,9 +1,17 @@
import { h, VNode } from "preact";
-import { BackupReducerProps, AnastasisClientFrame } from "./index";
-
-export function PoliciesPayingScreen(props: BackupReducerProps): VNode {
- const payments = props.backupState.policy_payment_requests ?? [];
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
+export function PoliciesPayingScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const payments = reducer.currentReducerState.policy_payment_requests ?? [];
+
return (
<AnastasisClientFrame hideNext title="Backup: Recovery Document Payments">
<p>
@@ -19,7 +27,7 @@ export function PoliciesPayingScreen(props: BackupReducerProps): VNode {
);
})}
</ul>
- <button onClick={() => props.reducer.transition("pay", {})}>
+ <button onClick={() => reducer.transition("pay", {})}>
Check payment status now
</button>
</AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx
new file mode 100644
index 000000000..0c1842420
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx
@@ -0,0 +1,42 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { RecoveryFinishedScreen as TestedComponent } from './RecoveryFinishedScreen';
+
+
+export default {
+ title: 'Pages/RecoveryFinishedScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const NormalEnding = createExample(TestedComponent, {
+ ...reducerStatesExample.recoveryFinished,
+ core_secret: { mime: 'text/plain', value: 'hello' }
+} as ReducerState);
+
+export const BadEnding = createExample(TestedComponent, reducerStatesExample.recoveryFinished);
diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
index 7ccc511ff..8c8a2c7c8 100644
--- a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx
@@ -3,13 +3,31 @@ import {
decodeCrock
} from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
-import { RecoveryReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
-export function RecoveryFinishedScreen(props: RecoveryReducerProps): VNode {
+export function RecoveryFinishedScreen(): VNode {
+ const reducer = useAnastasisContext()
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const encodedSecret = reducer.currentReducerState.core_secret?.value
+ if (!encodedSecret) {
+ return <AnastasisClientFrame title="Recovery Problem" hideNext>
+ <p>
+ Secret not found
+ </p>
+ </AnastasisClientFrame>
+ }
+ const secret = bytesToString(decodeCrock(encodedSecret))
return (
<AnastasisClientFrame title="Recovery Finished" hideNext>
<p>
- Secret: {bytesToString(decodeCrock(props.recoveryState.core_secret?.value!))}
+ Secret: {secret}
</p>
</AnastasisClientFrame>
);
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
new file mode 100644
index 000000000..b52699e7b
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
@@ -0,0 +1,81 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { ReviewPoliciesScreen as TestedComponent } from './ReviewPoliciesScreen';
+
+
+export default {
+ title: 'Pages/ReviewPoliciesScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const HasPoliciesButMethodListIsEmpty = createExample(TestedComponent, {
+ ...reducerStatesExample.policyReview,
+ policies: [{
+ methods: [{
+ authentication_method: 0,
+ provider: 'asd'
+ },{
+ authentication_method: 1,
+ provider: 'asd'
+ }]
+ },{
+ methods: [{
+ authentication_method: 1,
+ provider: 'asd'
+ }]
+ }],
+ authentication_methods: []
+} as ReducerState);
+
+export const SomePoliciesWithMethods = createExample(TestedComponent, {
+ ...reducerStatesExample.policyReview,
+ policies: [{
+ methods: [{
+ authentication_method: 0,
+ provider: 'asd'
+ },{
+ authentication_method: 1,
+ provider: 'asd'
+ }]
+ },{
+ methods: [{
+ authentication_method: 1,
+ provider: 'asd'
+ }]
+ }],
+ authentication_methods: [{
+ challenge: 'asd',
+ instructions: 'ins',
+ type: 'type',
+ },{
+ challenge: 'asd2',
+ instructions: 'ins2',
+ type: 'type2',
+ }]
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
index 3e20538d2..b360ccaf0 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
@@ -1,35 +1,49 @@
/* eslint-disable @typescript-eslint/camelcase */
import { h, VNode } from "preact";
-import { BackupReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
+
+export function ReviewPoliciesScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const authMethods = reducer.currentReducerState.authentication_methods ?? [];
+ const policies = reducer.currentReducerState.policies ?? [];
-export function ReviewPoliciesScreen(props: BackupReducerProps): VNode {
- const { reducer, backupState } = props;
- const authMethods = backupState.authentication_methods!;
return (
<AnastasisClientFrame title="Backup: Review Recovery Policies">
- {backupState.policies?.map((p, i) => {
- const policyName = p.methods
- .map((x, i) => authMethods[x.authentication_method].type)
- .join(" + ");
+ {policies.map((p, policy_index) => {
+ const methods = p.methods
+ .map(x => authMethods[x.authentication_method] && ({ ...authMethods[x.authentication_method], provider: x.provider }))
+ .filter(x => !!x)
+
+ const policyName = methods.map(x => x.type).join(" + ");
+
return (
- <div key={i} class="policy">
+ <div key={policy_index} class="policy">
<h3>
- Policy #{i + 1}: {policyName}
+ Policy #{policy_index + 1}: {policyName}
</h3>
Required Authentications:
+ {!methods.length && <p>
+ No auth method found
+ </p>}
<ul>
- {p.methods.map((x, i) => {
- const m = authMethods[x.authentication_method];
+ {methods.map((m, i) => {
return (
<li key={i}>
- {m.type} ({m.instructions}) at provider {x.provider}
+ {m.type} ({m.instructions}) at provider {m.provider}
</li>
);
})}
</ul>
<div>
<button
- onClick={() => reducer.transition("delete_policy", { policy_index: i })}
+ onClick={() => reducer.transition("delete_policy", { policy_index })}
>
Delete Policy
</button>
diff --git a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx
new file mode 100644
index 000000000..18560356a
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx
@@ -0,0 +1,44 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { SecretEditorScreen as TestedComponent } from './SecretEditorScreen';
+
+
+export default {
+ title: 'Pages/SecretEditorScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const WithSecretNamePreselected = createExample(TestedComponent, {
+ ...reducerStatesExample.secretEdition,
+ secret_name: 'someSecretName',
+} as ReducerState);
+
+export const WithoutName = createExample(TestedComponent, {
+ ...reducerStatesExample.secretEdition,
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx
index 086d4921d..a5235d66c 100644
--- a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx
@@ -2,18 +2,29 @@
import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
import {
- BackupReducerProps,
AnastasisClientFrame,
- LabeledInput,
+ LabeledInput
} from "./index";
-export function SecretEditorScreen(props: BackupReducerProps): VNode {
- const { reducer } = props;
- const [secretName, setSecretName] = useState(
- props.backupState.secret_name ?? "",
- );
+export function SecretEditorScreen(): VNode {
+ const reducer = useAnastasisContext()
const [secretValue, setSecretValue] = useState("");
+
+ const currentSecretName = reducer?.currentReducerState
+ && ("secret_name" in reducer.currentReducerState)
+ && reducer.currentReducerState.secret_name;
+
+ const [secretName, setSecretName] = useState(currentSecretName || "");
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+
const secretNext = (): void => {
reducer.runTransaction(async (tx) => {
await tx.transition("enter_secret_name", {
diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx
new file mode 100644
index 000000000..e9c597023
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx
@@ -0,0 +1,50 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { SecretSelectionScreen as TestedComponent } from './SecretSelectionScreen';
+
+
+export default {
+ title: 'Pages/SecretSelectionScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Example = createExample(TestedComponent, {
+ ...reducerStatesExample.secretSelection,
+ recovery_document: {
+ provider_url: 'http://anastasis.url/',
+ secret_name: 'secretName',
+ version: 1,
+ },
+} as ReducerState);
+
+
+export const NoRecoveryDocumentFound = createExample(TestedComponent, {
+ ...reducerStatesExample.secretSelection,
+ recovery_document: undefined,
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
index 7cb7fdf20..903f57868 100644
--- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx
@@ -1,17 +1,29 @@
/* eslint-disable @typescript-eslint/camelcase */
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
-import { RecoveryReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
-export function SecretSelectionScreen(props: RecoveryReducerProps): VNode {
- const { reducer, recoveryState } = props;
+export function SecretSelectionScreen(): VNode {
const [selectingVersion, setSelectingVersion] = useState<boolean>(false);
- const [otherVersion, setOtherVersion] = useState<number>(
- recoveryState.recovery_document?.version ?? 0
- );
- const recoveryDocument = recoveryState.recovery_document!;
const [otherProvider, setOtherProvider] = useState<string>("");
+ const reducer = useAnastasisContext()
+
+ const currentVersion = reducer?.currentReducerState
+ && ("recovery_document" in reducer.currentReducerState)
+ && reducer.currentReducerState.recovery_document?.version;
+
+ const [otherVersion, setOtherVersion] = useState<number>(currentVersion || 0);
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
+ return <div>invalid state</div>
+ }
+
function selectVersion(p: string, n: number): void {
+ if (!reducer) return;
reducer.runTransaction(async (tx) => {
await tx.transition("change_version", {
version: n,
@@ -20,12 +32,21 @@ export function SecretSelectionScreen(props: RecoveryReducerProps): VNode {
setSelectingVersion(false);
});
}
+
+ const recoveryDocument = reducer.currentReducerState.recovery_document
+ if (!recoveryDocument) {
+ return (
+ <AnastasisClientFrame hideNav title="Recovery: Problem">
+ <p>No recovery document found</p>
+ </AnastasisClientFrame>
+ )
+ }
if (selectingVersion) {
return (
<AnastasisClientFrame hideNav title="Recovery: Select secret">
<p>Select a different version of the secret</p>
<select onChange={(e) => setOtherProvider((e.target as any).value)}>
- {Object.keys(recoveryState.authentication_providers ?? {}).map(
+ {Object.keys(reducer.currentReducerState.authentication_providers ?? {}).map(
(x, i) => (
<option key={i} selected={x === recoveryDocument.provider_url} value={x}>
{x}
diff --git a/packages/anastasis-webui/src/pages/home/SolveEmailEntry.tsx b/packages/anastasis-webui/src/pages/home/SolveEmailEntry.tsx
index 6296dc022..2c27895c2 100644
--- a/packages/anastasis-webui/src/pages/home/SolveEmailEntry.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveEmailEntry.tsx
@@ -1,14 +1,17 @@
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame, LabeledInput } from "./index";
import { SolveEntryProps } from "./SolveScreen";
-export function SolveEmailEntry(props: SolveEntryProps): VNode {
+export function SolveEmailEntry({ challenge, feedback }: SolveEntryProps): VNode {
const [answer, setAnswer] = useState("");
- const { reducer, challenge, feedback } = props;
- const next = (): void => reducer.transition("solve_challenge", {
- answer,
- });
+ const reducer = useAnastasisContext()
+ const next = (): void => {
+ if (reducer) reducer.transition("solve_challenge", {
+ answer,
+ })
+ };
return (
<AnastasisClientFrame
title="Recovery: Solve challenge"
diff --git a/packages/anastasis-webui/src/pages/home/SolvePostEntry.tsx b/packages/anastasis-webui/src/pages/home/SolvePostEntry.tsx
index b11ceed27..1a824acb8 100644
--- a/packages/anastasis-webui/src/pages/home/SolvePostEntry.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolvePostEntry.tsx
@@ -1,14 +1,15 @@
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame, LabeledInput } from "./index";
import { SolveEntryProps } from "./SolveScreen";
-export function SolvePostEntry(props: SolveEntryProps): VNode {
+export function SolvePostEntry({ challenge, feedback }: SolveEntryProps): VNode {
const [answer, setAnswer] = useState("");
- const { reducer, challenge, feedback } = props;
- const next = (): void => reducer.transition("solve_challenge", {
- answer,
- });
+ const reducer = useAnastasisContext()
+ const next = (): void => {
+ if (reducer) reducer.transition("solve_challenge", { answer })
+ };
return (
<AnastasisClientFrame
title="Recovery: Solve challenge"
diff --git a/packages/anastasis-webui/src/pages/home/SolveQuestionEntry.tsx b/packages/anastasis-webui/src/pages/home/SolveQuestionEntry.tsx
index 6393958b3..72dadbe89 100644
--- a/packages/anastasis-webui/src/pages/home/SolveQuestionEntry.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveQuestionEntry.tsx
@@ -1,14 +1,15 @@
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame, LabeledInput } from "./index";
import { SolveEntryProps } from "./SolveScreen";
-export function SolveQuestionEntry(props: SolveEntryProps): VNode {
+export function SolveQuestionEntry({ challenge, feedback }: SolveEntryProps): VNode {
const [answer, setAnswer] = useState("");
- const { reducer, challenge, feedback } = props;
- const next = (): void => reducer.transition("solve_challenge", {
- answer,
- });
+ const reducer = useAnastasisContext()
+ const next = (): void => {
+ if (reducer) reducer.transition("solve_challenge", { answer })
+ };
return (
<AnastasisClientFrame
title="Recovery: Solve challenge"
diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx
new file mode 100644
index 000000000..69af9be42
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx
@@ -0,0 +1,121 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { SolveScreen as TestedComponent } from './SolveScreen';
+
+
+export default {
+ title: 'Pages/SolveScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const NoInformation = createExample(TestedComponent, reducerStatesExample.challengeSolving);
+
+export const NotSupportedChallenge = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'chall-type',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'ASDASDSAD!1'
+} as ReducerState);
+
+export const MismatchedChallengeId = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'chall-type',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'no-no-no'
+} as ReducerState);
+
+export const SmsChallenge = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'sms',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'ASDASDSAD!1'
+} as ReducerState);
+
+export const QuestionChallenge = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'question',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'ASDASDSAD!1'
+} as ReducerState);
+
+export const EmailChallenge = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'email',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'ASDASDSAD!1'
+} as ReducerState);
+
+export const PostChallenge = createExample(TestedComponent, {
+ ...reducerStatesExample.challengeSolving,
+ recovery_information: {
+ challenges: [{
+ cost: 'USD:1',
+ instructions: 'follow htis instructions',
+ type: 'post',
+ uuid: 'ASDASDSAD!1'
+ }],
+ policies: [],
+ },
+ selected_challenge_uuid: 'ASDASDSAD!1'
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
index 357a7c2d3..05ae50b48 100644
--- a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
@@ -1,17 +1,31 @@
import { h, VNode } from "preact";
-import { AnastasisReducerApi } from "../../hooks/use-anastasis-reducer";
+import { ChallengeFeedback, ChallengeInfo } from "../../../../anastasis-core/lib";
+import { useAnastasisContext } from "../../context/anastasis";
import { SolveEmailEntry } from "./SolveEmailEntry";
import { SolvePostEntry } from "./SolvePostEntry";
import { SolveQuestionEntry } from "./SolveQuestionEntry";
import { SolveSmsEntry } from "./SolveSmsEntry";
import { SolveUnsupportedEntry } from "./SolveUnsupportedEntry";
-import { RecoveryReducerProps } from "./index";
-import { ChallengeInfo, ChallengeFeedback } from "../../../../anastasis-core/lib";
-export function SolveScreen(props: RecoveryReducerProps): VNode {
- const chArr = props.recoveryState.recovery_information!.challenges;
- const challengeFeedback = props.recoveryState.challenge_feedback ?? {};
- const selectedUuid = props.recoveryState.selected_challenge_uuid!;
+export function SolveScreen(): VNode {
+ const reducer = useAnastasisContext()
+
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.recovery_state === undefined) {
+ return <div>invalid state</div>
+ }
+
+ if (!reducer.currentReducerState.recovery_information) {
+ return <div>no recovery information found</div>
+ }
+ if (!reducer.currentReducerState.selected_challenge_uuid) {
+ return <div>no selected uuid</div>
+ }
+ const chArr = reducer.currentReducerState.recovery_information.challenges;
+ const challengeFeedback = reducer.currentReducerState.challenge_feedback ?? {};
+ const selectedUuid = reducer.currentReducerState.selected_challenge_uuid;
const challenges: {
[uuid: string]: ChallengeInfo;
} = {};
@@ -25,17 +39,15 @@ export function SolveScreen(props: RecoveryReducerProps): VNode {
email: SolveEmailEntry,
post: SolvePostEntry,
};
- const SolveDialog = dialogMap[selectedChallenge.type] ?? SolveUnsupportedEntry;
+ const SolveDialog = dialogMap[selectedChallenge?.type] ?? SolveUnsupportedEntry;
return (
<SolveDialog
challenge={selectedChallenge}
- reducer={props.reducer}
feedback={challengeFeedback[selectedUuid]} />
);
}
export interface SolveEntryProps {
- reducer: AnastasisReducerApi;
challenge: ChallengeInfo;
feedback?: ChallengeFeedback;
}
diff --git a/packages/anastasis-webui/src/pages/home/SolveSmsEntry.tsx b/packages/anastasis-webui/src/pages/home/SolveSmsEntry.tsx
index d0cd41332..163e0d1f3 100644
--- a/packages/anastasis-webui/src/pages/home/SolveSmsEntry.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveSmsEntry.tsx
@@ -1,14 +1,17 @@
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame, LabeledInput } from "./index";
import { SolveEntryProps } from "./SolveScreen";
-export function SolveSmsEntry(props: SolveEntryProps): VNode {
+export function SolveSmsEntry({ challenge, feedback }: SolveEntryProps): VNode {
const [answer, setAnswer] = useState("");
- const { reducer, challenge, feedback } = props;
- const next = (): void => reducer.transition("solve_challenge", {
- answer,
- });
+ const reducer = useAnastasisContext()
+ const next = (): void => {
+ if (reducer) reducer.transition("solve_challenge", {
+ answer,
+ })
+ };
return (
<AnastasisClientFrame
title="Recovery: Solve challenge"
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
new file mode 100644
index 000000000..ad84cd8f2
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample, reducerStatesExample } from '../../utils';
+import { StartScreen as TestedComponent } from './StartScreen';
+
+
+export default {
+ title: 'Pages/StartScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const InitialState = createExample(TestedComponent, reducerStatesExample.initial); \ No newline at end of file
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.tsx b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
index 38124887c..6625ec5b8 100644
--- a/packages/anastasis-webui/src/pages/home/StartScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
@@ -1,14 +1,34 @@
+
import { h, VNode } from "preact";
-import { AnastasisReducerApi } from "../../hooks/use-anastasis-reducer";
+import { useAnastasisContext } from "../../context/anastasis";
import { AnastasisClientFrame } from "./index";
-export function StartScreen(props: { reducer: AnastasisReducerApi; }): VNode {
+export function StartScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
return (
<AnastasisClientFrame hideNav title="Home">
- <button autoFocus onClick={() => props.reducer.startBackup()}>
- Backup
- </button>
- <button onClick={() => props.reducer.startRecover()}>Recover</button>
+ <div>
+ <section class="section is-main-section">
+ <div class="columns">
+ <div class="column" />
+ <div class="column is-four-fifths">
+
+ <div class="buttons is-right">
+ <button class="button is-success" autoFocus onClick={() => reducer.startBackup()}>
+ Backup
+ </button>
+
+ <button class="button is-info" onClick={() => reducer.startRecover()}>Recover</button>
+ </div>
+
+ </div>
+ <div class="column" />
+ </div>
+ </section>
+ </div>
</AnastasisClientFrame>
);
}
diff --git a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx
new file mode 100644
index 000000000..e2f3d521e
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { TruthsPayingScreen as TestedComponent } from './TruthsPayingScreen';
+
+
+export default {
+ title: 'Pages/TruthsPayingScreen',
+ component: TestedComponent,
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const Example = createExample(TestedComponent, reducerStatesExample.truthsPaying);
+export const WithPaytoList = createExample(TestedComponent, {
+ ...reducerStatesExample.truthsPaying,
+ payments: ['payto://x-taler-bank/bank/account']
+} as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
index 5b8a835b8..319f590a0 100644
--- a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.tsx
@@ -1,8 +1,16 @@
import { h, VNode } from "preact";
-import { BackupReducerProps, AnastasisClientFrame } from "./index";
+import { useAnastasisContext } from "../../context/anastasis";
+import { AnastasisClientFrame } from "./index";
-export function TruthsPayingScreen(props: BackupReducerProps): VNode {
- const payments = props.backupState.payments ?? [];
+export function TruthsPayingScreen(): VNode {
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <div>no reducer in context</div>
+ }
+ if (!reducer.currentReducerState || reducer.currentReducerState.backup_state === undefined) {
+ return <div>invalid state</div>
+ }
+ const payments = reducer.currentReducerState.payments ?? [];
return (
<AnastasisClientFrame
hideNext
@@ -17,7 +25,7 @@ export function TruthsPayingScreen(props: BackupReducerProps): VNode {
return <li key={i}>{x}</li>;
})}
</ul>
- <button onClick={() => props.reducer.transition("pay", {})}>
+ <button onClick={() => reducer.transition("pay", {})}>
Check payment status now
</button>
</AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/index.tsx b/packages/anastasis-webui/src/pages/home/index.tsx
index 5001d1ee4..4cec47ec8 100644
--- a/packages/anastasis-webui/src/pages/home/index.tsx
+++ b/packages/anastasis-webui/src/pages/home/index.tsx
@@ -1,28 +1,25 @@
import {
- Component,
- ComponentChildren,
- createContext,
- Fragment,
+ BackupStates,
+ RecoveryStates,
+ ReducerStateBackup,
+ ReducerStateRecovery
+} from "anastasis-core";
+import {
+ ComponentChildren, Fragment,
FunctionalComponent,
h,
- VNode,
+ VNode
} from "preact";
import {
- useContext,
useErrorBoundary,
useLayoutEffect,
- useRef,
+ useRef
} from "preact/hooks";
import { Menu } from "../../components/menu";
-import {
- BackupStates,
- RecoveryStates,
- ReducerStateBackup,
- ReducerStateRecovery,
-} from "anastasis-core";
+import { AnastasisProvider, useAnastasisContext } from "../../context/anastasis";
import {
AnastasisReducerApi,
- useAnastasisReducer,
+ useAnastasisReducer
} from "../../hooks/use-anastasis-reducer";
import { AttributeEntryScreen } from "./AttributeEntryScreen";
import { AuthenticationEditorScreen } from "./AuthenticationEditorScreen";
@@ -38,19 +35,11 @@ import { SecretSelectionScreen } from "./SecretSelectionScreen";
import { SolveScreen } from "./SolveScreen";
import { StartScreen } from "./StartScreen";
import { TruthsPayingScreen } from "./TruthsPayingScreen";
-import "./../home/style";
-
-const WithReducer = createContext<AnastasisReducerApi | undefined>(undefined);
function isBackup(reducer: AnastasisReducerApi): boolean {
return !!reducer.currentReducerState?.backup_state;
}
-export interface CommonReducerProps {
- reducer: AnastasisReducerApi;
- reducerState: ReducerStateBackup | ReducerStateRecovery;
-}
-
export function withProcessLabel(
reducer: AnastasisReducerApi,
text: string,
@@ -61,16 +50,6 @@ export function withProcessLabel(
return `Recovery: ${text}`;
}
-export interface BackupReducerProps {
- reducer: AnastasisReducerApi;
- backupState: ReducerStateBackup;
-}
-
-export interface RecoveryReducerProps {
- reducer: AnastasisReducerApi;
- recoveryState: ReducerStateRecovery;
-}
-
interface AnastasisClientFrameProps {
onNext?(): void;
title: string;
@@ -88,7 +67,7 @@ interface AnastasisClientFrameProps {
function ErrorBoundary(props: {
reducer: AnastasisReducerApi;
children: ComponentChildren;
-}) {
+}): VNode {
const [error, resetError] = useErrorBoundary((error) =>
console.log("got error", error),
);
@@ -113,7 +92,7 @@ function ErrorBoundary(props: {
}
export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
- const reducer = useContext(WithReducer);
+ const reducer = useAnastasisContext();
if (!reducer) {
return <p>Fatal: Reducer must be in context.</p>;
}
@@ -135,9 +114,8 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
<Menu title="Anastasis" />
<div>
<div class="home" onKeyPress={(e) => handleKeyPress(e)}>
- <button onClick={() => reducer.reset()}>Reset session</button>
<h1>{props.title}</h1>
- <ErrorBanner reducer={reducer} />
+ <ErrorBanner />
{props.children}
{!props.hideNav ? (
<div>
@@ -154,96 +132,94 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
const AnastasisClient: FunctionalComponent = () => {
const reducer = useAnastasisReducer();
return (
- <WithReducer.Provider value={reducer}>
+ <AnastasisProvider value={reducer}>
<ErrorBoundary reducer={reducer}>
<AnastasisClientImpl />
</ErrorBoundary>
- </WithReducer.Provider>
+ </AnastasisProvider>
);
};
const AnastasisClientImpl: FunctionalComponent = () => {
- const reducer = useContext(WithReducer)!;
- const reducerState = reducer.currentReducerState;
- if (!reducerState) {
- return <StartScreen reducer={reducer} />;
+ const reducer = useAnastasisContext()
+ if (!reducer) {
+ return <p>Fatal: Reducer must be in context.</p>;
+ }
+ const state = reducer.currentReducerState;
+ if (!state) {
+ return <StartScreen />;
}
console.log("state", reducer.currentReducerState);
if (
- reducerState.backup_state === BackupStates.ContinentSelecting ||
- reducerState.recovery_state === RecoveryStates.ContinentSelecting
+ state.backup_state === BackupStates.ContinentSelecting ||
+ state.recovery_state === RecoveryStates.ContinentSelecting
) {
return (
- <ContinentSelectionScreen reducer={reducer} reducerState={reducerState} />
+ <ContinentSelectionScreen />
);
}
if (
- reducerState.backup_state === BackupStates.CountrySelecting ||
- reducerState.recovery_state === RecoveryStates.CountrySelecting
+ state.backup_state === BackupStates.CountrySelecting ||
+ state.recovery_state === RecoveryStates.CountrySelecting
) {
return (
- <CountrySelectionScreen reducer={reducer} reducerState={reducerState} />
+ <CountrySelectionScreen />
);
}
if (
- reducerState.backup_state === BackupStates.UserAttributesCollecting ||
- reducerState.recovery_state === RecoveryStates.UserAttributesCollecting
+ state.backup_state === BackupStates.UserAttributesCollecting ||
+ state.recovery_state === RecoveryStates.UserAttributesCollecting
) {
return (
- <AttributeEntryScreen reducer={reducer} reducerState={reducerState} />
+ <AttributeEntryScreen />
);
}
- if (reducerState.backup_state === BackupStates.AuthenticationsEditing) {
+ if (state.backup_state === BackupStates.AuthenticationsEditing) {
return (
- <AuthenticationEditorScreen
- backupState={reducerState}
- reducer={reducer}
- />
+ <AuthenticationEditorScreen />
);
}
- if (reducerState.backup_state === BackupStates.PoliciesReviewing) {
+ if (state.backup_state === BackupStates.PoliciesReviewing) {
return (
- <ReviewPoliciesScreen reducer={reducer} backupState={reducerState} />
+ <ReviewPoliciesScreen />
);
}
- if (reducerState.backup_state === BackupStates.SecretEditing) {
- return <SecretEditorScreen reducer={reducer} backupState={reducerState} />;
+ if (state.backup_state === BackupStates.SecretEditing) {
+ return <SecretEditorScreen />;
}
- if (reducerState.backup_state === BackupStates.BackupFinished) {
- const backupState: ReducerStateBackup = reducerState;
- return <BackupFinishedScreen reducer={reducer} backupState={backupState} />;
+ if (state.backup_state === BackupStates.BackupFinished) {
+ return <BackupFinishedScreen />;
}
- if (reducerState.backup_state === BackupStates.TruthsPaying) {
- return <TruthsPayingScreen reducer={reducer} backupState={reducerState} />;
+ if (state.backup_state === BackupStates.TruthsPaying) {
+ return <TruthsPayingScreen />;
}
- if (reducerState.backup_state === BackupStates.PoliciesPaying) {
- const backupState: ReducerStateBackup = reducerState;
- return <PoliciesPayingScreen reducer={reducer} backupState={backupState} />;
+ if (state.backup_state === BackupStates.PoliciesPaying) {
+ return <PoliciesPayingScreen />;
}
- if (reducerState.recovery_state === RecoveryStates.SecretSelecting) {
+ if (state.recovery_state === RecoveryStates.SecretSelecting) {
return (
- <SecretSelectionScreen reducer={reducer} recoveryState={reducerState} />
+ <SecretSelectionScreen />
);
}
- if (reducerState.recovery_state === RecoveryStates.ChallengeSelecting) {
+ if (state.recovery_state === RecoveryStates.ChallengeSelecting) {
return (
- <ChallengeOverviewScreen reducer={reducer} recoveryState={reducerState} />
+ <ChallengeOverviewScreen />
);
}
- if (reducerState.recovery_state === RecoveryStates.ChallengeSolving) {
- return <SolveScreen reducer={reducer} recoveryState={reducerState} />;
+ if (state.recovery_state === RecoveryStates.ChallengeSolving) {
+ return <SolveScreen />;
}
- if (reducerState.recovery_state === RecoveryStates.RecoveryFinished) {
+ if (state.recovery_state === RecoveryStates.RecoveryFinished) {
return (
- <RecoveryFinishedScreen reducer={reducer} recoveryState={reducerState} />
+ <RecoveryFinishedScreen />
);
}
@@ -251,7 +227,9 @@ const AnastasisClientImpl: FunctionalComponent = () => {
return (
<AnastasisClientFrame hideNav title="Bug">
<p>Bug: Unknown state.</p>
- <button onClick={() => reducer.reset()}>Reset</button>
+ <div class="buttons is-right">
+ <button class="button" onClick={() => reducer.reset()}>Reset</button>
+ </div>
</AnastasisClientFrame>
);
};
@@ -282,26 +260,20 @@ export function LabeledInput(props: LabeledInputProps): VNode {
);
}
-interface ErrorBannerProps {
- reducer: AnastasisReducerApi;
-}
-
/**
- * Show a dismissable error banner if there is a current error.
+ * Show a dismissible error banner if there is a current error.
*/
-function ErrorBanner(props: ErrorBannerProps): VNode | null {
- const currentError = props.reducer.currentError;
- if (currentError) {
- return (
- <div id="error">
- <p>Error: {JSON.stringify(currentError)}</p>
- <button onClick={() => props.reducer.dismissError()}>
- Dismiss Error
- </button>
- </div>
- );
- }
- return null;
+function ErrorBanner(): VNode | null {
+ const reducer = useAnastasisContext();
+ if (!reducer || !reducer.currentError) return null;
+ return (
+ <div id="error">
+ <p>Error: {JSON.stringify(reducer.currentError)}</p>
+ <button onClick={() => reducer.dismissError()}>
+ Dismiss Error
+ </button>
+ </div>
+ );
}
export default AnastasisClient;
diff --git a/packages/anastasis-webui/src/utils/index.tsx b/packages/anastasis-webui/src/utils/index.tsx
new file mode 100644
index 000000000..d1d861469
--- /dev/null
+++ b/packages/anastasis-webui/src/utils/index.tsx
@@ -0,0 +1,161 @@
+/* eslint-disable @typescript-eslint/camelcase */
+import { BackupStates, RecoveryStates, ReducerState } from 'anastasis-core';
+import { FunctionalComponent, h, VNode } from 'preact';
+import { AnastasisProvider } from '../context/anastasis';
+
+export function createExample<Props>(Component: FunctionalComponent<Props>, currentReducerState?: ReducerState, props?: Partial<Props>): { (args: Props): VNode } {
+ const r = (args: Props): VNode => {
+ return <AnastasisProvider value={{
+ currentReducerState,
+ currentError: undefined,
+ back: () => { null },
+ dismissError: () => { null },
+ reset: () => { null },
+ runTransaction: () => { null },
+ startBackup: () => { null },
+ startRecover: () => { null },
+ transition: () => { null },
+ }}>
+ <Component {...args} />
+ </AnastasisProvider>
+ }
+ r.args = props
+ return r
+}
+
+const base = {
+ continents: [
+ {
+ name: "Europe"
+ },
+ {
+ name: "India"
+ },
+ {
+ name: "Asia"
+ },
+ {
+ name: "North America"
+ },
+ {
+ name: "Testcontinent"
+ }
+ ],
+ countries: [
+ {
+ code: "xx",
+ name: "Testland",
+ continent: "Testcontinent",
+ continent_i18n: {
+ de_DE: "Testkontinent"
+ },
+ name_i18n: {
+ de_DE: "Testlandt",
+ de_CH: "Testlandi",
+ fr_FR: "Testpais",
+ en_UK: "Testland"
+ },
+ currency: "TESTKUDOS",
+ call_code: "+00"
+ },
+ {
+ code: "xy",
+ name: "Demoland",
+ continent: "Testcontinent",
+ continent_i18n: {
+ de_DE: "Testkontinent"
+ },
+ name_i18n: {
+ de_DE: "Demolandt",
+ de_CH: "Demolandi",
+ fr_FR: "Demopais",
+ en_UK: "Demoland"
+ },
+ currency: "KUDOS",
+ call_code: "+01"
+ }
+ ],
+ authentication_providers: {
+ "http://localhost:8086/": {
+ http_status: 200,
+ annual_fee: "COL:0",
+ business_name: "ana",
+ currency: "COL",
+ liability_limit: "COL:10",
+ methods: [
+ {
+ type: "question",
+ usage_fee: "COL:0"
+ }
+ ],
+ salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
+ storage_limit_in_megabytes: 16,
+ truth_upload_fee: "COL:0"
+ },
+ "http://localhost:8087/": {
+ code: 8414,
+ hint: "request to provider failed"
+ },
+ "http://localhost:8088/": {
+ code: 8414,
+ hint: "request to provider failed"
+ },
+ "http://localhost:8089/": {
+ code: 8414,
+ hint: "request to provider failed"
+ }
+ },
+ // expiration: {
+ // d_ms: 1792525051855 // check t_ms
+ // },
+} as Partial<ReducerState>
+
+export const reducerStatesExample = {
+ initial: undefined,
+ recoverySelectCountry: {...base,
+ recovery_state: RecoveryStates.CountrySelecting
+ } as ReducerState,
+ backupSelectCountry: {...base,
+ backup_state: BackupStates.CountrySelecting
+ } as ReducerState,
+ recoverySelectContinent: {...base,
+ recovery_state: RecoveryStates.ContinentSelecting,
+ } as ReducerState,
+ backupSelectContinent: {...base,
+ backup_state: BackupStates.ContinentSelecting,
+ } as ReducerState,
+ secretSelection: {...base,
+ recovery_state: RecoveryStates.SecretSelecting,
+ } as ReducerState,
+ recoveryFinished: {...base,
+ recovery_state: RecoveryStates.RecoveryFinished,
+ } as ReducerState,
+ challengeSelecting: {...base,
+ recovery_state: RecoveryStates.ChallengeSelecting,
+ } as ReducerState,
+ challengeSolving: {...base,
+ recovery_state: RecoveryStates.ChallengeSolving,
+ } as ReducerState,
+ secretEdition: {...base,
+ backup_state: BackupStates.SecretEditing,
+ } as ReducerState,
+ policyReview: {...base,
+ backup_state: BackupStates.PoliciesReviewing,
+ } as ReducerState,
+ policyPay: {...base,
+ backup_state: BackupStates.PoliciesPaying,
+ } as ReducerState,
+ backupFinished: {...base,
+ backup_state: BackupStates.BackupFinished,
+ } as ReducerState,
+ authEditing: {...base,
+ backup_state: BackupStates.AuthenticationsEditing
+ } as ReducerState,
+ attributeEditing: {...base,
+ backup_state: BackupStates.UserAttributesCollecting
+ } as ReducerState,
+ truthsPaying: {...base,
+ backup_state: BackupStates.TruthsPaying
+ } as ReducerState,
+
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f5f77e575..cd6d7ae58 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -35,6 +35,12 @@ importers:
specifiers:
'@creativebulma/bulma-tooltip': ^1.2.0
'@gnu-taler/taler-util': workspace:^0.8.3
+ '@storybook/addon-a11y': ^6.2.9
+ '@storybook/addon-actions': ^6.2.9
+ '@storybook/addon-essentials': ^6.2.9
+ '@storybook/addon-links': ^6.2.9
+ '@storybook/preact': ^6.2.9
+ '@storybook/preset-scss': ^1.0.3
'@types/enzyme': ^3.10.5
'@types/jest': ^26.0.8
'@typescript-eslint/eslint-plugin': ^2.25.0
@@ -67,6 +73,12 @@ importers:
preact-router: 3.2.1_preact@10.5.14
devDependencies:
'@creativebulma/bulma-tooltip': 1.2.0
+ '@storybook/addon-a11y': 6.3.7
+ '@storybook/addon-actions': 6.3.7
+ '@storybook/addon-essentials': 6.3.7_typescript@3.9.10
+ '@storybook/addon-links': 6.3.12
+ '@storybook/preact': 6.3.7_preact@10.5.14+typescript@3.9.10
+ '@storybook/preset-scss': 1.0.3_sass-loader@10.2.0
'@types/enzyme': 3.10.9
'@types/jest': 26.0.24
'@typescript-eslint/eslint-plugin': 2.34.0_2b015b1c4b7c4a3ed9a197dc233b1a35
@@ -1724,6 +1736,15 @@ packages:
'@babel/helper-plugin-utils': 7.14.5
dev: true
+ /@babel/plugin-syntax-jsx/7.14.5:
+ resolution: {integrity: sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/helper-plugin-utils': 7.14.5
+ dev: true
+
/@babel/plugin-syntax-jsx/7.14.5_@babel+core@7.13.16:
resolution: {integrity: sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==}
engines: {node: '>=6.9.0'}
@@ -2812,6 +2833,19 @@ packages:
'@babel/helper-plugin-utils': 7.14.5
dev: true
+ /@babel/plugin-transform-react-jsx/7.14.9:
+ resolution: {integrity: sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/helper-annotate-as-pure': 7.14.5
+ '@babel/helper-module-imports': 7.14.5
+ '@babel/helper-plugin-utils': 7.14.5
+ '@babel/plugin-syntax-jsx': 7.14.5
+ '@babel/types': 7.15.0
+ dev: true
+
/@babel/plugin-transform-react-jsx/7.14.9_@babel+core@7.13.16:
resolution: {integrity: sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw==}
engines: {node: '>=6.9.0'}
@@ -4800,6 +4834,101 @@ packages:
- '@types/react'
dev: true
+ /@storybook/addon-docs/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-cyuyoLuB5ELhbrXgnZneDCHqNq1wSdWZ4dzdHy1E5WwLPEhLlD6INfEsm8gnDIb4IncYuzMhK3XYBDd7d3ijOg==}
+ peerDependencies:
+ '@storybook/angular': 6.3.7
+ '@storybook/vue': 6.3.7
+ '@storybook/vue3': 6.3.7
+ '@storybook/web-components': 6.3.7
+ lit: ^2.0.0-rc.1
+ lit-html: ^1.4.1 || ^2.0.0-rc.3
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ svelte: ^3.31.2
+ sveltedoc-parser: ^4.1.0
+ vue: ^2.6.10 || ^3.0.0
+ webpack: '*'
+ peerDependenciesMeta:
+ '@storybook/angular':
+ optional: true
+ '@storybook/vue':
+ optional: true
+ '@storybook/vue3':
+ optional: true
+ '@storybook/web-components':
+ optional: true
+ lit:
+ optional: true
+ lit-html:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ svelte:
+ optional: true
+ sveltedoc-parser:
+ optional: true
+ vue:
+ optional: true
+ webpack:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/generator': 7.15.0
+ '@babel/parser': 7.15.3
+ '@babel/plugin-transform-react-jsx': 7.14.9_@babel+core@7.15.0
+ '@babel/preset-env': 7.15.0_@babel+core@7.15.0
+ '@jest/transform': 26.6.2
+ '@mdx-js/loader': 1.6.22
+ '@mdx-js/mdx': 1.6.22
+ '@mdx-js/react': 1.6.22
+ '@storybook/addons': 6.3.7
+ '@storybook/api': 6.3.7
+ '@storybook/builder-webpack4': 6.3.7_typescript@3.9.10
+ '@storybook/client-api': 6.3.7
+ '@storybook/client-logger': 6.3.7
+ '@storybook/components': 6.3.7
+ '@storybook/core': 6.3.7_36f75bb62e0c484c1a06658ad2872463
+ '@storybook/core-events': 6.3.7
+ '@storybook/csf': 0.0.1
+ '@storybook/csf-tools': 6.3.7_@babel+core@7.15.0
+ '@storybook/node-logger': 6.3.7
+ '@storybook/postinstall': 6.3.7
+ '@storybook/source-loader': 6.3.7
+ '@storybook/theming': 6.3.7
+ acorn: 7.4.1
+ acorn-jsx: 5.3.2_acorn@7.4.1
+ acorn-walk: 7.2.0
+ core-js: 3.16.2
+ doctrine: 3.0.0
+ escodegen: 2.0.0
+ fast-deep-equal: 3.1.3
+ global: 4.4.0
+ html-tags: 3.1.0
+ js-string-escape: 1.0.1
+ loader-utils: 2.0.0
+ lodash: 4.17.21
+ p-limit: 3.1.0
+ prettier: 2.2.1
+ prop-types: 15.7.2
+ react-element-to-jsx-string: 14.3.2
+ regenerator-runtime: 0.13.9
+ remark-external-links: 8.0.0
+ remark-slug: 6.1.0
+ ts-dedent: 2.2.0
+ util-deprecate: 1.0.2
+ transitivePeerDependencies:
+ - '@storybook/builder-webpack5'
+ - '@storybook/manager-webpack5'
+ - '@types/react'
+ - supports-color
+ - typescript
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/addon-docs/6.3.7_typescript@4.3.5:
resolution: {integrity: sha512-cyuyoLuB5ELhbrXgnZneDCHqNq1wSdWZ4dzdHy1E5WwLPEhLlD6INfEsm8gnDIb4IncYuzMhK3XYBDd7d3ijOg==}
peerDependencies:
@@ -4955,6 +5084,89 @@ packages:
- webpack-command
dev: true
+ /@storybook/addon-essentials/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-ZWAW3qMFrrpfSekmCZibp/ivnohFLJdJweiIA0CLnuCNuuK9kQdpFahWdvyBy5NlCj3UJwB7epTZYZyHqYW7UQ==}
+ peerDependencies:
+ '@babel/core': ^7.9.6
+ '@storybook/vue': 6.3.7
+ '@storybook/web-components': 6.3.7
+ babel-loader: ^8.0.0
+ lit-html: ^1.4.1 || ^2.0.0-rc.3
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ webpack: '*'
+ peerDependenciesMeta:
+ '@storybook/vue':
+ optional: true
+ '@storybook/web-components':
+ optional: true
+ lit-html:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ webpack:
+ optional: true
+ dependencies:
+ '@storybook/addon-actions': 6.3.7
+ '@storybook/addon-backgrounds': 6.3.7
+ '@storybook/addon-controls': 6.3.7
+ '@storybook/addon-docs': 6.3.7_typescript@3.9.10
+ '@storybook/addon-measure': 2.0.0_a4b77c99d63b159b69a1438c89904ed9
+ '@storybook/addon-toolbars': 6.3.7
+ '@storybook/addon-viewport': 6.3.7
+ '@storybook/addons': 6.3.7
+ '@storybook/api': 6.3.7
+ '@storybook/node-logger': 6.3.7
+ core-js: 3.16.2
+ regenerator-runtime: 0.13.9
+ storybook-addon-outline: 1.4.1
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@storybook/angular'
+ - '@storybook/builder-webpack5'
+ - '@storybook/components'
+ - '@storybook/core-events'
+ - '@storybook/manager-webpack5'
+ - '@storybook/theming'
+ - '@storybook/vue3'
+ - '@types/react'
+ - lit
+ - supports-color
+ - svelte
+ - sveltedoc-parser
+ - typescript
+ - vue
+ - webpack-cli
+ - webpack-command
+ dev: true
+
+ /@storybook/addon-links/6.3.12:
+ resolution: {integrity: sha512-NfOGEm0+QxIrAXCa05LOXmxLtI+RlcDqHXZ1jNNj8mjeRoG1nX3qhkB8PWWIBbPuz+bktLV9ox8UZj0W6+ZPOQ==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ dependencies:
+ '@storybook/addons': 6.3.12
+ '@storybook/client-logger': 6.3.12
+ '@storybook/core-events': 6.3.12
+ '@storybook/csf': 0.0.1
+ '@storybook/router': 6.3.12
+ '@types/qs': 6.9.7
+ core-js: 3.16.2
+ global: 4.4.0
+ prop-types: 15.7.2
+ qs: 6.10.1
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ dev: true
+
/@storybook/addon-measure/2.0.0_a4b77c99d63b159b69a1438c89904ed9:
resolution: {integrity: sha512-ZhdT++cX+L9LwjhGYggvYUUVQH/MGn2rwbrAwCMzA/f2QTFvkjxzX8nDgMxIhaLCDC+gHIxfJG2wrWN0jkBr3g==}
peerDependencies:
@@ -5023,6 +5235,23 @@ packages:
- '@types/react'
dev: true
+ /@storybook/addons/6.3.12:
+ resolution: {integrity: sha512-UgoMyr7Qr0FS3ezt8u6hMEcHgyynQS9ucr5mAwZky3wpXRPFyUTmMto9r4BBUdqyUvTUj/LRKIcmLBfj+/l0Fg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ dependencies:
+ '@storybook/api': 6.3.12
+ '@storybook/channels': 6.3.12
+ '@storybook/client-logger': 6.3.12
+ '@storybook/core-events': 6.3.12
+ '@storybook/router': 6.3.12
+ '@storybook/theming': 6.3.12
+ core-js: 3.16.2
+ global: 4.4.0
+ regenerator-runtime: 0.13.9
+ dev: true
+
/@storybook/addons/6.3.7:
resolution: {integrity: sha512-9stVjTcc52bqqh7YQex/LpSjJ4e2Czm4/ZYDjIiNy0p4OZEx+yLhL5mZzMWh2NQd6vv+pHASBSxf2IeaR5511A==}
peerDependencies:
@@ -5059,6 +5288,34 @@ packages:
regenerator-runtime: 0.13.9
dev: true
+ /@storybook/api/6.3.12:
+ resolution: {integrity: sha512-LScRXUeCWEW/OP+jiooNMQICVdusv7azTmULxtm72fhkXFRiQs2CdRNTiqNg46JLLC9z95f1W+pGK66X6HiiQA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ dependencies:
+ '@reach/router': 1.3.4
+ '@storybook/channels': 6.3.12
+ '@storybook/client-logger': 6.3.12
+ '@storybook/core-events': 6.3.12
+ '@storybook/csf': 0.0.1
+ '@storybook/router': 6.3.12
+ '@storybook/semver': 7.3.2
+ '@storybook/theming': 6.3.12
+ '@types/reach__router': 1.3.9
+ core-js: 3.16.2
+ fast-deep-equal: 3.1.3
+ global: 4.4.0
+ lodash: 4.17.21
+ memoizerific: 1.11.3
+ qs: 6.10.1
+ regenerator-runtime: 0.13.9
+ store2: 2.12.0
+ telejson: 5.3.3
+ ts-dedent: 2.2.0
+ util-deprecate: 1.0.2
+ dev: true
+
/@storybook/api/6.3.7:
resolution: {integrity: sha512-57al8mxmE9agXZGo8syRQ8UhvGnDC9zkuwkBPXchESYYVkm3Mc54RTvdAOYDiy85VS4JxiGOywHayCaRwgUddQ==}
peerDependencies:
@@ -5117,6 +5374,96 @@ packages:
util-deprecate: 1.0.2
dev: true
+ /@storybook/builder-webpack4/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-M5envblMzAUrNqP1+ouKiL8iSIW/90+kBRU2QeWlZoZl1ib+fiFoKk06cgbaC70Bx1lU8nOnI/VBvB5pLhXLaw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-proposal-class-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-decorators': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-export-default-from': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-nullish-coalescing-operator': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-proposal-optional-chaining': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-private-methods': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.15.0
+ '@babel/plugin-transform-arrow-functions': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-block-scoping': 7.15.3_@babel+core@7.15.0
+ '@babel/plugin-transform-classes': 7.14.9_@babel+core@7.15.0
+ '@babel/plugin-transform-destructuring': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-transform-for-of': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-parameters': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-shorthand-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-spread': 7.14.6_@babel+core@7.15.0
+ '@babel/plugin-transform-template-literals': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-env': 7.15.0_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-typescript': 7.15.0_@babel+core@7.15.0
+ '@storybook/addons': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/api': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/channels': 6.3.7
+ '@storybook/client-api': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/client-logger': 6.3.7
+ '@storybook/components': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/core-common': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/core-events': 6.3.7
+ '@storybook/node-logger': 6.3.7
+ '@storybook/router': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/semver': 7.3.2
+ '@storybook/theming': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/ui': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@types/node': 14.17.10
+ '@types/webpack': 4.41.30
+ autoprefixer: 9.8.6
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ babel-plugin-macros: 2.8.0
+ babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.15.0
+ case-sensitive-paths-webpack-plugin: 2.4.0
+ core-js: 3.16.2
+ css-loader: 3.6.0_webpack@4.46.0
+ dotenv-webpack: 1.8.0_webpack@4.46.0
+ file-loader: 6.2.0_webpack@4.46.0
+ find-up: 5.0.0
+ fork-ts-checker-webpack-plugin: 4.1.6
+ fs-extra: 9.1.0
+ glob: 7.1.7
+ glob-promise: 3.4.0_glob@7.1.7
+ global: 4.4.0
+ html-webpack-plugin: 4.5.2_webpack@4.46.0
+ pnp-webpack-plugin: 1.6.4_typescript@3.9.10
+ postcss: 7.0.36
+ postcss-flexbugs-fixes: 4.2.1
+ postcss-loader: 4.3.0_postcss@7.0.36+webpack@4.46.0
+ raw-loader: 4.0.2_webpack@4.46.0
+ react: 16.14.0
+ react-dev-utils: 11.0.4
+ react-dom: 16.14.0_react@16.14.0
+ stable: 0.1.8
+ style-loader: 1.3.0_webpack@4.46.0
+ terser-webpack-plugin: 4.2.3_webpack@4.46.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ url-loader: 4.1.1_file-loader@6.2.0+webpack@4.46.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ webpack-dev-middleware: 3.7.3_webpack@4.46.0
+ webpack-filter-warnings-plugin: 1.2.1_webpack@4.46.0
+ webpack-hot-middleware: 2.25.0
+ webpack-virtual-modules: 0.2.2
+ transitivePeerDependencies:
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/builder-webpack4/6.3.7_8073bd74a106ff14517e8eecceb690e6:
resolution: {integrity: sha512-M5envblMzAUrNqP1+ouKiL8iSIW/90+kBRU2QeWlZoZl1ib+fiFoKk06cgbaC70Bx1lU8nOnI/VBvB5pLhXLaw==}
peerDependencies:
@@ -5207,6 +5554,94 @@ packages:
- webpack-command
dev: true
+ /@storybook/builder-webpack4/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-M5envblMzAUrNqP1+ouKiL8iSIW/90+kBRU2QeWlZoZl1ib+fiFoKk06cgbaC70Bx1lU8nOnI/VBvB5pLhXLaw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-proposal-class-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-decorators': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-export-default-from': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-nullish-coalescing-operator': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-proposal-optional-chaining': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-private-methods': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.15.0
+ '@babel/plugin-transform-arrow-functions': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-block-scoping': 7.15.3_@babel+core@7.15.0
+ '@babel/plugin-transform-classes': 7.14.9_@babel+core@7.15.0
+ '@babel/plugin-transform-destructuring': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-transform-for-of': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-parameters': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-shorthand-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-spread': 7.14.6_@babel+core@7.15.0
+ '@babel/plugin-transform-template-literals': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-env': 7.15.0_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-typescript': 7.15.0_@babel+core@7.15.0
+ '@storybook/addons': 6.3.7
+ '@storybook/api': 6.3.7
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/channels': 6.3.7
+ '@storybook/client-api': 6.3.7
+ '@storybook/client-logger': 6.3.7
+ '@storybook/components': 6.3.7
+ '@storybook/core-common': 6.3.7_typescript@3.9.10
+ '@storybook/core-events': 6.3.7
+ '@storybook/node-logger': 6.3.7
+ '@storybook/router': 6.3.7
+ '@storybook/semver': 7.3.2
+ '@storybook/theming': 6.3.7
+ '@storybook/ui': 6.3.7
+ '@types/node': 14.17.10
+ '@types/webpack': 4.41.30
+ autoprefixer: 9.8.6
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ babel-plugin-macros: 2.8.0
+ babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.15.0
+ case-sensitive-paths-webpack-plugin: 2.4.0
+ core-js: 3.16.2
+ css-loader: 3.6.0_webpack@4.46.0
+ dotenv-webpack: 1.8.0_webpack@4.46.0
+ file-loader: 6.2.0_webpack@4.46.0
+ find-up: 5.0.0
+ fork-ts-checker-webpack-plugin: 4.1.6
+ fs-extra: 9.1.0
+ glob: 7.1.7
+ glob-promise: 3.4.0_glob@7.1.7
+ global: 4.4.0
+ html-webpack-plugin: 4.5.2_webpack@4.46.0
+ pnp-webpack-plugin: 1.6.4_typescript@3.9.10
+ postcss: 7.0.36
+ postcss-flexbugs-fixes: 4.2.1
+ postcss-loader: 4.3.0_postcss@7.0.36+webpack@4.46.0
+ raw-loader: 4.0.2_webpack@4.46.0
+ react-dev-utils: 11.0.4
+ stable: 0.1.8
+ style-loader: 1.3.0_webpack@4.46.0
+ terser-webpack-plugin: 4.2.3_webpack@4.46.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ url-loader: 4.1.1_file-loader@6.2.0+webpack@4.46.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ webpack-dev-middleware: 3.7.3_webpack@4.46.0
+ webpack-filter-warnings-plugin: 1.2.1_webpack@4.46.0
+ webpack-hot-middleware: 2.25.0
+ webpack-virtual-modules: 0.2.2
+ transitivePeerDependencies:
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/builder-webpack4/6.3.7_typescript@4.3.5:
resolution: {integrity: sha512-M5envblMzAUrNqP1+ouKiL8iSIW/90+kBRU2QeWlZoZl1ib+fiFoKk06cgbaC70Bx1lU8nOnI/VBvB5pLhXLaw==}
peerDependencies:
@@ -5307,6 +5742,14 @@ packages:
telejson: 5.3.3
dev: true
+ /@storybook/channels/6.3.12:
+ resolution: {integrity: sha512-l4sA+g1PdUV8YCbgs47fIKREdEQAKNdQIZw0b7BfTvY9t0x5yfBywgQhYON/lIeiNGz2OlIuD+VUtqYfCtNSyw==}
+ dependencies:
+ core-js: 3.16.2
+ ts-dedent: 2.2.0
+ util-deprecate: 1.0.2
+ dev: true
+
/@storybook/channels/6.3.7:
resolution: {integrity: sha512-aErXO+SRO8MPp2wOkT2n9d0fby+8yM35tq1tI633B4eQsM74EykbXPv7EamrYPqp1AI4BdiloyEpr0hmr2zlvg==}
dependencies:
@@ -5369,6 +5812,13 @@ packages:
util-deprecate: 1.0.2
dev: true
+ /@storybook/client-logger/6.3.12:
+ resolution: {integrity: sha512-zNDsamZvHnuqLznDdP9dUeGgQ9TyFh4ray3t1VGO7ZqWVZ2xtVCCXjDvMnOXI2ifMpX5UsrOvshIPeE9fMBmiQ==}
+ dependencies:
+ core-js: 3.16.2
+ global: 4.4.0
+ dev: true
+
/@storybook/client-logger/6.3.7:
resolution: {integrity: sha512-BQRErHE3nIEuUJN/3S3dO1LzxAknOgrFeZLd4UVcH/fvjtS1F4EkhcbH+jNyUWvcWGv66PZYN0oFPEn/g3Savg==}
dependencies:
@@ -5446,6 +5896,77 @@ packages:
- '@types/react'
dev: true
+ /@storybook/core-client/6.3.7_3c33386fd9b1d5f07f48f07869b17b73:
+ resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ webpack: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/addons': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/client-api': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/client-logger': 6.3.7
+ '@storybook/core-events': 6.3.7
+ '@storybook/csf': 0.0.1
+ '@storybook/ui': 6.3.7_react-dom@16.14.0+react@16.14.0
+ airbnb-js-shims: 2.2.1
+ ansi-to-html: 0.6.15
+ core-js: 3.16.2
+ global: 4.4.0
+ lodash: 4.17.21
+ qs: 6.10.1
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ unfetch: 4.2.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - '@types/react'
+ dev: true
+
+ /@storybook/core-client/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ webpack: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/addons': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/client-api': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/client-logger': 6.3.7
+ '@storybook/core-events': 6.3.7
+ '@storybook/csf': 0.0.1
+ '@storybook/ui': 6.3.7_react-dom@16.14.0+react@16.14.0
+ airbnb-js-shims: 2.2.1
+ ansi-to-html: 0.6.15
+ core-js: 3.16.2
+ global: 4.4.0
+ lodash: 4.17.21
+ qs: 6.10.1
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ unfetch: 4.2.0
+ util-deprecate: 1.0.2
+ transitivePeerDependencies:
+ - '@types/react'
+ dev: true
+
/@storybook/core-client/6.3.7_70d39b49be06a92d1ddadaf2d0a6de02:
resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
peerDependencies:
@@ -5517,6 +6038,73 @@ packages:
- '@types/react'
dev: true
+ /@storybook/core-client/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ webpack: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/addons': 6.3.7
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/client-api': 6.3.7
+ '@storybook/client-logger': 6.3.7
+ '@storybook/core-events': 6.3.7
+ '@storybook/csf': 0.0.1
+ '@storybook/ui': 6.3.7
+ airbnb-js-shims: 2.2.1
+ ansi-to-html: 0.6.15
+ core-js: 3.16.2
+ global: 4.4.0
+ lodash: 4.17.21
+ qs: 6.10.1
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ unfetch: 4.2.0
+ util-deprecate: 1.0.2
+ transitivePeerDependencies:
+ - '@types/react'
+ dev: true
+
+ /@storybook/core-client/6.3.7_typescript@3.9.10+webpack@4.46.0:
+ resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ webpack: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/addons': 6.3.7
+ '@storybook/channel-postmessage': 6.3.7
+ '@storybook/client-api': 6.3.7
+ '@storybook/client-logger': 6.3.7
+ '@storybook/core-events': 6.3.7
+ '@storybook/csf': 0.0.1
+ '@storybook/ui': 6.3.7
+ airbnb-js-shims: 2.2.1
+ ansi-to-html: 0.6.15
+ core-js: 3.16.2
+ global: 4.4.0
+ lodash: 4.17.21
+ qs: 6.10.1
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ unfetch: 4.2.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - '@types/react'
+ dev: true
+
/@storybook/core-client/6.3.7_typescript@4.3.5:
resolution: {integrity: sha512-M/4A65yV+Y4lsCQXX4BtQO/i3BcMPrU5FkDG8qJd3dkcx2fUlFvGWqQPkcTZE+MPVvMEGl/AsEZSADzah9+dAg==}
peerDependencies:
@@ -5584,6 +6172,73 @@ packages:
- '@types/react'
dev: true
+ /@storybook/core-common/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-exLoqRPPsAefwyjbsQBLNFrlPCcv69Q/pclqmIm7FqAPR7f3CKP1rqsHY0PnemizTL/+cLX5S7mY90gI6wpNug==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-proposal-class-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-decorators': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-export-default-from': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-nullish-coalescing-operator': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-proposal-optional-chaining': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-private-methods': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.15.0
+ '@babel/plugin-transform-arrow-functions': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-block-scoping': 7.15.3_@babel+core@7.15.0
+ '@babel/plugin-transform-classes': 7.14.9_@babel+core@7.15.0
+ '@babel/plugin-transform-destructuring': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-transform-for-of': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-parameters': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-shorthand-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-spread': 7.14.6_@babel+core@7.15.0
+ '@babel/preset-env': 7.15.0_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-typescript': 7.15.0_@babel+core@7.15.0
+ '@babel/register': 7.15.3_@babel+core@7.15.0
+ '@storybook/node-logger': 6.3.7
+ '@storybook/semver': 7.3.2
+ '@types/glob-base': 0.3.0
+ '@types/micromatch': 4.0.2
+ '@types/node': 14.17.10
+ '@types/pretty-hrtime': 1.0.1
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ babel-plugin-macros: 3.1.0
+ babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.15.0
+ chalk: 4.1.2
+ core-js: 3.16.2
+ express: 4.17.1
+ file-system-cache: 1.0.5
+ find-up: 5.0.0
+ fork-ts-checker-webpack-plugin: 6.3.2
+ glob: 7.1.7
+ glob-base: 0.3.0
+ interpret: 2.2.0
+ json5: 2.2.0
+ lazy-universal-dotenv: 3.0.1
+ micromatch: 4.0.4
+ pkg-dir: 5.0.0
+ pretty-hrtime: 1.0.3
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ resolve-from: 5.0.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/core-common/6.3.7_8073bd74a106ff14517e8eecceb690e6:
resolution: {integrity: sha512-exLoqRPPsAefwyjbsQBLNFrlPCcv69Q/pclqmIm7FqAPR7f3CKP1rqsHY0PnemizTL/+cLX5S7mY90gI6wpNug==}
peerDependencies:
@@ -5651,6 +6306,71 @@ packages:
- webpack-command
dev: true
+ /@storybook/core-common/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-exLoqRPPsAefwyjbsQBLNFrlPCcv69Q/pclqmIm7FqAPR7f3CKP1rqsHY0PnemizTL/+cLX5S7mY90gI6wpNug==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-proposal-class-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-decorators': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-export-default-from': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-nullish-coalescing-operator': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-proposal-optional-chaining': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-proposal-private-methods': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.15.0
+ '@babel/plugin-transform-arrow-functions': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-block-scoping': 7.15.3_@babel+core@7.15.0
+ '@babel/plugin-transform-classes': 7.14.9_@babel+core@7.15.0
+ '@babel/plugin-transform-destructuring': 7.14.7_@babel+core@7.15.0
+ '@babel/plugin-transform-for-of': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-parameters': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-shorthand-properties': 7.14.5_@babel+core@7.15.0
+ '@babel/plugin-transform-spread': 7.14.6_@babel+core@7.15.0
+ '@babel/preset-env': 7.15.0_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-typescript': 7.15.0_@babel+core@7.15.0
+ '@babel/register': 7.15.3_@babel+core@7.15.0
+ '@storybook/node-logger': 6.3.7
+ '@storybook/semver': 7.3.2
+ '@types/glob-base': 0.3.0
+ '@types/micromatch': 4.0.2
+ '@types/node': 14.17.10
+ '@types/pretty-hrtime': 1.0.1
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ babel-plugin-macros: 3.1.0
+ babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.15.0
+ chalk: 4.1.2
+ core-js: 3.16.2
+ express: 4.17.1
+ file-system-cache: 1.0.5
+ find-up: 5.0.0
+ fork-ts-checker-webpack-plugin: 6.3.2
+ glob: 7.1.7
+ glob-base: 0.3.0
+ interpret: 2.2.0
+ json5: 2.2.0
+ lazy-universal-dotenv: 3.0.1
+ micromatch: 4.0.4
+ pkg-dir: 5.0.0
+ pretty-hrtime: 1.0.3
+ resolve-from: 5.0.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/core-common/6.3.7_typescript@4.3.5:
resolution: {integrity: sha512-exLoqRPPsAefwyjbsQBLNFrlPCcv69Q/pclqmIm7FqAPR7f3CKP1rqsHY0PnemizTL/+cLX5S7mY90gI6wpNug==}
peerDependencies:
@@ -5716,12 +6436,136 @@ packages:
- webpack-command
dev: true
+ /@storybook/core-events/6.3.12:
+ resolution: {integrity: sha512-SXfD7xUUMazaeFkB92qOTUV8Y/RghE4SkEYe5slAdjeocSaH7Nz2WV0rqNEgChg0AQc+JUI66no8L9g0+lw4Gw==}
+ dependencies:
+ core-js: 3.16.2
+ dev: true
+
/@storybook/core-events/6.3.7:
resolution: {integrity: sha512-l5Hlhe+C/dqxjobemZ6DWBhTOhQoFF3F1Y4kjFGE7pGZl/mas4M72I5I/FUcYCmbk2fbLfZX8hzKkUqS1hdyLA==}
dependencies:
core-js: 3.16.2
dev: true
+ /@storybook/core-server/6.3.7_36f75bb62e0c484c1a06658ad2872463:
+ resolution: {integrity: sha512-m5OPD/rmZA7KFewkXzXD46/i1ngUoFO4LWOiAY/wR6RQGjYXGMhSa5UYFF6MNwSbiGS5YieHkR5crB1HP47AhQ==}
+ peerDependencies:
+ '@storybook/builder-webpack5': 6.3.7
+ '@storybook/manager-webpack5': 6.3.7
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ '@storybook/builder-webpack5':
+ optional: true
+ '@storybook/manager-webpack5':
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/builder-webpack4': 6.3.7_typescript@3.9.10
+ '@storybook/core-client': 6.3.7_typescript@3.9.10+webpack@4.46.0
+ '@storybook/core-common': 6.3.7_typescript@3.9.10
+ '@storybook/csf-tools': 6.3.7_@babel+core@7.15.0
+ '@storybook/manager-webpack4': 6.3.7_typescript@3.9.10
+ '@storybook/node-logger': 6.3.7
+ '@storybook/semver': 7.3.2
+ '@types/node': 14.17.10
+ '@types/node-fetch': 2.5.12
+ '@types/pretty-hrtime': 1.0.1
+ '@types/webpack': 4.41.30
+ better-opn: 2.1.1
+ boxen: 4.2.0
+ chalk: 4.1.2
+ cli-table3: 0.6.0
+ commander: 6.2.1
+ compression: 1.7.4
+ core-js: 3.16.2
+ cpy: 8.1.2
+ detect-port: 1.3.0
+ express: 4.17.1
+ file-system-cache: 1.0.5
+ fs-extra: 9.1.0
+ globby: 11.0.4
+ ip: 1.1.5
+ node-fetch: 2.6.1
+ pretty-hrtime: 1.0.3
+ prompts: 2.4.1
+ regenerator-runtime: 0.13.9
+ serve-favicon: 2.5.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
+ /@storybook/core-server/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-m5OPD/rmZA7KFewkXzXD46/i1ngUoFO4LWOiAY/wR6RQGjYXGMhSa5UYFF6MNwSbiGS5YieHkR5crB1HP47AhQ==}
+ peerDependencies:
+ '@storybook/builder-webpack5': 6.3.7
+ '@storybook/manager-webpack5': 6.3.7
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ '@storybook/builder-webpack5':
+ optional: true
+ '@storybook/manager-webpack5':
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/builder-webpack4': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/core-client': 6.3.7_3c33386fd9b1d5f07f48f07869b17b73
+ '@storybook/core-common': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/csf-tools': 6.3.7
+ '@storybook/manager-webpack4': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/node-logger': 6.3.7
+ '@storybook/semver': 7.3.2
+ '@types/node': 14.17.10
+ '@types/node-fetch': 2.5.12
+ '@types/pretty-hrtime': 1.0.1
+ '@types/webpack': 4.41.30
+ better-opn: 2.1.1
+ boxen: 4.2.0
+ chalk: 4.1.2
+ cli-table3: 0.6.0
+ commander: 6.2.1
+ compression: 1.7.4
+ core-js: 3.16.2
+ cpy: 8.1.2
+ detect-port: 1.3.0
+ express: 4.17.1
+ file-system-cache: 1.0.5
+ fs-extra: 9.1.0
+ globby: 11.0.4
+ ip: 1.1.5
+ node-fetch: 2.6.1
+ pretty-hrtime: 1.0.3
+ prompts: 2.4.1
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ regenerator-runtime: 0.13.9
+ serve-favicon: 2.5.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/core-server/6.3.7_f0b419a7e119055c71dcaf6063a7ba7a:
resolution: {integrity: sha512-m5OPD/rmZA7KFewkXzXD46/i1ngUoFO4LWOiAY/wR6RQGjYXGMhSa5UYFF6MNwSbiGS5YieHkR5crB1HP47AhQ==}
peerDependencies:
@@ -5840,6 +6684,60 @@ packages:
- webpack-command
dev: true
+ /@storybook/core/6.3.7_36f75bb62e0c484c1a06658ad2872463:
+ resolution: {integrity: sha512-YTVLPXqgyBg7TALNxQ+cd+GtCm/NFjxr/qQ1mss1T9GCMR0IjE0d0trgOVHHLAO8jCVlK8DeuqZCCgZFTXulRw==}
+ peerDependencies:
+ '@storybook/builder-webpack5': 6.3.7
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ '@storybook/builder-webpack5':
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/core-client': 6.3.7_typescript@3.9.10
+ '@storybook/core-server': 6.3.7_36f75bb62e0c484c1a06658ad2872463
+ typescript: 3.9.10
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@storybook/manager-webpack5'
+ - '@types/react'
+ - supports-color
+ - webpack
+ - webpack-cli
+ - webpack-command
+ dev: true
+
+ /@storybook/core/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-YTVLPXqgyBg7TALNxQ+cd+GtCm/NFjxr/qQ1mss1T9GCMR0IjE0d0trgOVHHLAO8jCVlK8DeuqZCCgZFTXulRw==}
+ peerDependencies:
+ '@storybook/builder-webpack5': 6.3.7
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ '@storybook/builder-webpack5':
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@storybook/core-client': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/core-server': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ typescript: 3.9.10
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@storybook/manager-webpack5'
+ - '@types/react'
+ - supports-color
+ - webpack
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/core/6.3.7_f0b419a7e119055c71dcaf6063a7ba7a:
resolution: {integrity: sha512-YTVLPXqgyBg7TALNxQ+cd+GtCm/NFjxr/qQ1mss1T9GCMR0IjE0d0trgOVHHLAO8jCVlK8DeuqZCCgZFTXulRw==}
peerDependencies:
@@ -5894,6 +6792,28 @@ packages:
- webpack-command
dev: true
+ /@storybook/csf-tools/6.3.7:
+ resolution: {integrity: sha512-A7yGsrYwh+vwVpmG8dHpEimX021RbZd9VzoREcILH56u8atssdh/rseljyWlRes3Sr4QgtLvDB7ggoJ+XDZH7w==}
+ dependencies:
+ '@babel/generator': 7.15.0
+ '@babel/parser': 7.15.3
+ '@babel/plugin-transform-react-jsx': 7.14.9
+ '@babel/preset-env': 7.15.0
+ '@babel/traverse': 7.15.0
+ '@babel/types': 7.15.0
+ '@mdx-js/mdx': 1.6.22
+ '@storybook/csf': 0.0.1
+ core-js: 3.16.2
+ fs-extra: 9.1.0
+ js-string-escape: 1.0.1
+ lodash: 4.17.21
+ prettier: 2.2.1
+ regenerator-runtime: 0.13.9
+ transitivePeerDependencies:
+ - '@babel/core'
+ - supports-color
+ dev: true
+
/@storybook/csf-tools/6.3.7_@babel+core@7.13.16:
resolution: {integrity: sha512-A7yGsrYwh+vwVpmG8dHpEimX021RbZd9VzoREcILH56u8atssdh/rseljyWlRes3Sr4QgtLvDB7ggoJ+XDZH7w==}
dependencies:
@@ -5944,6 +6864,63 @@ packages:
lodash: 4.17.21
dev: true
+ /@storybook/manager-webpack4/6.3.7_6b8328ae33be7bccbaedcbeca6bc1253:
+ resolution: {integrity: sha512-cwUdO3oklEtx6y+ZOl2zHvflICK85emiXBQGgRcCsnwWQRBZOMh+tCgOSZj4jmISVpT52RtT9woG4jKe15KBig==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-transform-template-literals': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@storybook/addons': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/core-client': 6.3.7_3c33386fd9b1d5f07f48f07869b17b73
+ '@storybook/core-common': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/node-logger': 6.3.7
+ '@storybook/theming': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/ui': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@types/node': 14.17.10
+ '@types/webpack': 4.41.30
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ case-sensitive-paths-webpack-plugin: 2.4.0
+ chalk: 4.1.2
+ core-js: 3.16.2
+ css-loader: 3.6.0_webpack@4.46.0
+ dotenv-webpack: 1.8.0_webpack@4.46.0
+ express: 4.17.1
+ file-loader: 6.2.0_webpack@4.46.0
+ file-system-cache: 1.0.5
+ find-up: 5.0.0
+ fs-extra: 9.1.0
+ html-webpack-plugin: 4.5.2_webpack@4.46.0
+ node-fetch: 2.6.1
+ pnp-webpack-plugin: 1.6.4_typescript@3.9.10
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ read-pkg-up: 7.0.1
+ regenerator-runtime: 0.13.9
+ resolve-from: 5.0.0
+ style-loader: 1.3.0_webpack@4.46.0
+ telejson: 5.3.3
+ terser-webpack-plugin: 4.2.3_webpack@4.46.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ url-loader: 4.1.1_file-loader@6.2.0+webpack@4.46.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ webpack-dev-middleware: 3.7.3_webpack@4.46.0
+ webpack-virtual-modules: 0.2.2
+ transitivePeerDependencies:
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/manager-webpack4/6.3.7_8073bd74a106ff14517e8eecceb690e6:
resolution: {integrity: sha512-cwUdO3oklEtx6y+ZOl2zHvflICK85emiXBQGgRcCsnwWQRBZOMh+tCgOSZj4jmISVpT52RtT9woG4jKe15KBig==}
peerDependencies:
@@ -6001,6 +6978,61 @@ packages:
- webpack-command
dev: true
+ /@storybook/manager-webpack4/6.3.7_typescript@3.9.10:
+ resolution: {integrity: sha512-cwUdO3oklEtx6y+ZOl2zHvflICK85emiXBQGgRcCsnwWQRBZOMh+tCgOSZj4jmISVpT52RtT9woG4jKe15KBig==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@babel/core': 7.15.0
+ '@babel/plugin-transform-template-literals': 7.14.5_@babel+core@7.15.0
+ '@babel/preset-react': 7.14.5_@babel+core@7.15.0
+ '@storybook/addons': 6.3.7
+ '@storybook/core-client': 6.3.7_typescript@3.9.10+webpack@4.46.0
+ '@storybook/core-common': 6.3.7_typescript@3.9.10
+ '@storybook/node-logger': 6.3.7
+ '@storybook/theming': 6.3.7
+ '@storybook/ui': 6.3.7
+ '@types/node': 14.17.10
+ '@types/webpack': 4.41.30
+ babel-loader: 8.2.2_be352a5a80662835a7707f972edfcfde
+ case-sensitive-paths-webpack-plugin: 2.4.0
+ chalk: 4.1.2
+ core-js: 3.16.2
+ css-loader: 3.6.0_webpack@4.46.0
+ dotenv-webpack: 1.8.0_webpack@4.46.0
+ express: 4.17.1
+ file-loader: 6.2.0_webpack@4.46.0
+ file-system-cache: 1.0.5
+ find-up: 5.0.0
+ fs-extra: 9.1.0
+ html-webpack-plugin: 4.5.2_webpack@4.46.0
+ node-fetch: 2.6.1
+ pnp-webpack-plugin: 1.6.4_typescript@3.9.10
+ read-pkg-up: 7.0.1
+ regenerator-runtime: 0.13.9
+ resolve-from: 5.0.0
+ style-loader: 1.3.0_webpack@4.46.0
+ telejson: 5.3.3
+ terser-webpack-plugin: 4.2.3_webpack@4.46.0
+ ts-dedent: 2.2.0
+ typescript: 3.9.10
+ url-loader: 4.1.1_file-loader@6.2.0+webpack@4.46.0
+ util-deprecate: 1.0.2
+ webpack: 4.46.0
+ webpack-dev-middleware: 3.7.3_webpack@4.46.0
+ webpack-virtual-modules: 0.2.2
+ transitivePeerDependencies:
+ - '@types/react'
+ - supports-color
+ - webpack-cli
+ - webpack-command
+ dev: true
+
/@storybook/manager-webpack4/6.3.7_typescript@4.3.5:
resolution: {integrity: sha512-cwUdO3oklEtx6y+ZOl2zHvflICK85emiXBQGgRcCsnwWQRBZOMh+tCgOSZj4jmISVpT52RtT9woG4jKe15KBig==}
peerDependencies:
@@ -6105,6 +7137,66 @@ packages:
- webpack-command
dev: true
+ /@storybook/preact/6.3.7_preact@10.5.14+typescript@3.9.10:
+ resolution: {integrity: sha512-mP6+e1toCd59ALUNsiJWQN0CuOVV7faaMcAs21T+GJeU5igEWbRpe/ixKdMdu7RqHA9jAHOeMZfjSNhBkvnwAw==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ '@babel/core': '*'
+ preact: ^8.0.0||^10.0.0
+ webpack: '*'
+ dependencies:
+ '@babel/plugin-transform-react-jsx': 7.14.9
+ '@storybook/addons': 6.3.7_react-dom@16.14.0+react@16.14.0
+ '@storybook/core': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@storybook/core-common': 6.3.7_6b8328ae33be7bccbaedcbeca6bc1253
+ '@types/webpack-env': 1.16.2
+ core-js: 3.16.2
+ global: 4.4.0
+ preact: 10.5.14
+ react: 16.14.0
+ react-dom: 16.14.0_react@16.14.0
+ read-pkg-up: 7.0.1
+ regenerator-runtime: 0.13.9
+ ts-dedent: 2.2.0
+ transitivePeerDependencies:
+ - '@storybook/builder-webpack5'
+ - '@storybook/manager-webpack5'
+ - '@types/react'
+ - supports-color
+ - typescript
+ - webpack-cli
+ - webpack-command
+ dev: true
+
+ /@storybook/preset-scss/1.0.3_sass-loader@10.2.0:
+ resolution: {integrity: sha512-o9Iz6wxPeNENrQa2mKlsDKynBfqU2uWaRP80HeWp4TkGgf7/x3DVF2O7yi9N0x/PI1qzzTTpxlQ90D62XmpiTw==}
+ peerDependencies:
+ css-loader: '*'
+ sass-loader: '*'
+ style-loader: '*'
+ dependencies:
+ sass-loader: 10.2.0_sass@1.43.2
+ dev: true
+
+ /@storybook/router/6.3.12:
+ resolution: {integrity: sha512-G/pNGCnrJRetCwyEZulHPT+YOcqEj/vkPVDTUfii2qgqukup6K0cjwgd7IukAURnAnnzTi1gmgFuEKUi8GE/KA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ dependencies:
+ '@reach/router': 1.3.4
+ '@storybook/client-logger': 6.3.12
+ '@types/reach__router': 1.3.9
+ core-js: 3.16.2
+ fast-deep-equal: 3.1.3
+ global: 4.4.0
+ lodash: 4.17.21
+ memoizerific: 1.11.3
+ qs: 6.10.1
+ ts-dedent: 2.2.0
+ dev: true
+
/@storybook/router/6.3.7:
resolution: {integrity: sha512-6tthN8op7H0NoYoE1SkQFJKC42pC4tGaoPn7kEql8XGeUJnxPtVFjrnywlTrRnKuxZKIvbilQBAwDml97XH23Q==}
peerDependencies:
@@ -6170,6 +7262,26 @@ packages:
regenerator-runtime: 0.13.9
dev: true
+ /@storybook/theming/6.3.12:
+ resolution: {integrity: sha512-wOJdTEa/VFyFB2UyoqyYGaZdym6EN7RALuQOAMT6zHA282FBmKw8nL5DETHEbctpnHdcrMC/391teK4nNSrdOA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ dependencies:
+ '@emotion/core': 10.1.1
+ '@emotion/is-prop-valid': 0.8.8
+ '@emotion/styled': 10.0.27_@emotion+core@10.1.1
+ '@storybook/client-logger': 6.3.12
+ core-js: 3.16.2
+ deep-object-diff: 1.1.0
+ emotion-theming: 10.0.27_@emotion+core@10.1.1
+ global: 4.4.0
+ memoizerific: 1.11.3
+ polished: 4.1.3
+ resolve-from: 5.0.0
+ ts-dedent: 2.2.0
+ dev: true
+
/@storybook/theming/6.3.7:
resolution: {integrity: sha512-GXBdw18JJd5jLLcRonAZWvGGdwEXByxF1IFNDSOYCcpHWsMgTk4XoLjceu9MpXET04pVX51LbVPLCvMdggoohg==}
peerDependencies:
@@ -7709,7 +8821,7 @@ packages:
/axios/0.21.1:
resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==}
dependencies:
- follow-redirects: 1.14.2_debug@4.3.2
+ follow-redirects: 1.14.2
transitivePeerDependencies:
- debug
@@ -11506,7 +12618,7 @@ packages:
readable-stream: 2.3.7
dev: true
- /follow-redirects/1.14.2_debug@4.3.2:
+ /follow-redirects/1.14.2:
resolution: {integrity: sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==}
engines: {node: '>=4.0'}
peerDependencies:
@@ -11514,8 +12626,6 @@ packages:
peerDependenciesMeta:
debug:
optional: true
- dependencies:
- debug: 4.3.2_supports-color@6.1.0
/for-each/0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -12550,7 +13660,7 @@ packages:
engines: {node: '>=8.0.0'}
dependencies:
eventemitter3: 4.0.7
- follow-redirects: 1.14.2_debug@4.3.2
+ follow-redirects: 1.14.2
requires-port: 1.0.0
transitivePeerDependencies:
- debug
@@ -16025,6 +17135,15 @@ packages:
resolution: {integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==}
dev: true
+ /pnp-webpack-plugin/1.6.4_typescript@3.9.10:
+ resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==}
+ engines: {node: '>=6'}
+ dependencies:
+ ts-pnp: 1.2.0_typescript@3.9.10
+ transitivePeerDependencies:
+ - typescript
+ dev: true
+
/pnp-webpack-plugin/1.6.4_typescript@4.3.5:
resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==}
engines: {node: '>=6'}
@@ -16038,7 +17157,7 @@ packages:
resolution: {integrity: sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==}
engines: {node: '>=6'}
dependencies:
- ts-pnp: 1.2.0_typescript@4.4.3
+ ts-pnp: 1.2.0_typescript@4.3.5
transitivePeerDependencies:
- typescript
dev: true
@@ -19791,7 +20910,7 @@ packages:
resolution: {integrity: sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==}
dev: true
- /ts-pnp/1.2.0_typescript@4.3.5:
+ /ts-pnp/1.2.0_typescript@3.9.10:
resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
engines: {node: '>=6'}
peerDependencies:
@@ -19800,10 +20919,10 @@ packages:
typescript:
optional: true
dependencies:
- typescript: 4.3.5
+ typescript: 3.9.10
dev: true
- /ts-pnp/1.2.0_typescript@4.4.3:
+ /ts-pnp/1.2.0_typescript@4.3.5:
resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
engines: {node: '>=6'}
peerDependencies:
@@ -19812,7 +20931,7 @@ packages:
typescript:
optional: true
dependencies:
- typescript: 4.4.3
+ typescript: 4.3.5
dev: true
/tsconfig-paths/3.9.0: