From 7a600514c6d43bbaeba6b962533415e59fc46057 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 8 Aug 2022 14:09:28 -0300 Subject: fixing #6096 merchant details and contract terms details factored out, to be used by other components tests and stories updated payment completed != confirmed (confirmed if paid by someone else) --- .../src/popup/Balance.stories.tsx | 9 ++ .../src/popup/BalancePage.tsx | 152 ++++++++++++++------- .../src/popup/NoBalanceHelp.tsx | 5 +- 3 files changed, 116 insertions(+), 50 deletions(-) (limited to 'packages/taler-wallet-webextension/src/popup') diff --git a/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx b/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx index 89a7cace8..87cc98ea0 100644 --- a/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx +++ b/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx @@ -30,6 +30,7 @@ export default { export const EmptyBalance = createExample(TestedComponent, { balances: [], + goToWalletManualWithdraw: {}, }); export const SomeCoins = createExample(TestedComponent, { @@ -42,6 +43,8 @@ export const SomeCoins = createExample(TestedComponent, { requiresUserInput: false, }, ], + addAction: {}, + goToWalletManualWithdraw: {}, }); export const SomeCoinsInTreeCurrencies = createExample(TestedComponent, { @@ -68,6 +71,8 @@ export const SomeCoinsInTreeCurrencies = createExample(TestedComponent, { requiresUserInput: false, }, ], + goToWalletManualWithdraw: {}, + addAction: {}, }); export const NoCoinsInTreeCurrencies = createExample(TestedComponent, { @@ -94,6 +99,8 @@ export const NoCoinsInTreeCurrencies = createExample(TestedComponent, { requiresUserInput: false, }, ], + goToWalletManualWithdraw: {}, + addAction: {}, }); export const SomeCoinsInFiveCurrencies = createExample(TestedComponent, { @@ -148,4 +155,6 @@ export const SomeCoinsInFiveCurrencies = createExample(TestedComponent, { requiresUserInput: false, }, ], + goToWalletManualWithdraw: {}, + addAction: {}, }); diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx index cdf507cb5..3275a0a07 100644 --- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -23,8 +23,10 @@ import { Loading } from "../components/Loading.js"; import { LoadingError } from "../components/LoadingError.js"; import { MultiActionButton } from "../components/MultiActionButton.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; +import { ButtonHandler } from "../mui/handlers.js"; +import { compose, StateViewMap } from "../utils/index.js"; import { AddNewActionView } from "../wallet/AddNewActionView.js"; import * as wxApi from "../wxApi.js"; import { NoBalanceHelp } from "./NoBalanceHelp.js"; @@ -34,17 +36,46 @@ export interface Props { goToWalletHistory: (currency: string) => Promise; goToWalletManualWithdraw: () => Promise; } -export function BalancePage({ - goToWalletManualWithdraw, - goToWalletDeposit, - goToWalletHistory, -}: Props): VNode { - const { i18n } = useTranslationContext(); + +export type State = State.Loading | State.Error | State.Action | State.Balances; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface Error { + status: "error"; + error: HookError; + } + + export interface Action { + status: "action"; + error: undefined; + cancel: ButtonHandler; + } + + export interface Balances { + status: "balance"; + error: undefined; + balances: Balance[]; + addAction: ButtonHandler; + goToWalletDeposit: (currency: string) => Promise; + goToWalletHistory: (currency: string) => Promise; + goToWalletManualWithdraw: ButtonHandler; + } +} + +function useComponentState( + { goToWalletDeposit, goToWalletHistory, goToWalletManualWithdraw }: Props, + api: typeof wxApi, +): State { const [addingAction, setAddingAction] = useState(false); - const state = useAsyncAsHook(wxApi.getBalance); + const state = useAsyncAsHook(api.getBalance); useEffect(() => { - return wxApi.onUpdateNotification( + return api.onUpdateNotification( [NotificationType.WithdrawGroupFinished], () => { state?.retry(); @@ -52,58 +83,80 @@ export function BalancePage({ ); }); - const balances = !state || state.hasError ? [] : state.response.balances; - if (!state) { - return ; + return { + status: "loading", + error: undefined, + }; } - if (state.hasError) { - return ( - Could not load balance page} - error={state} - /> - ); + return { + status: "error", + error: state, + }; } - if (addingAction) { - return setAddingAction(false)} />; + return { + status: "action", + error: undefined, + cancel: { + onClick: async () => setAddingAction(false), + }, + }; } + return { + status: "balance", + error: undefined, + balances: state.response.balances, + addAction: { + onClick: async () => setAddingAction(true), + }, + goToWalletManualWithdraw: { + onClick: goToWalletManualWithdraw, + }, + goToWalletDeposit, + goToWalletHistory, + }; +} + +const viewMapping: StateViewMap = { + loading: Loading, + error: ErrorView, + action: ActionView, + balance: BalanceView, +}; +export const BalancePage = compose( + "BalancePage", + (p: Props) => useComponentState(p, wxApi), + viewMapping, +); + +function ErrorView({ error }: State.Error): VNode { + const { i18n } = useTranslationContext(); return ( - setAddingAction(true)} + Could not load balance page} + error={error} /> ); } -export interface BalanceViewProps { - balances: Balance[]; - goToWalletManualWithdraw: () => Promise; - goToAddAction: () => Promise; - goToWalletDeposit: (currency: string) => Promise; - goToWalletHistory: (currency: string) => Promise; + +function ActionView({ cancel }: State.Action): VNode { + return ; } -export function BalanceView({ - balances, - goToWalletManualWithdraw, - goToWalletDeposit, - goToWalletHistory, - goToAddAction, -}: BalanceViewProps): VNode { +export function BalanceView(state: State.Balances): VNode { const { i18n } = useTranslationContext(); - const currencyWithNonZeroAmount = balances + const currencyWithNonZeroAmount = state.balances .filter((b) => !Amounts.isZero(b.available)) .map((b) => b.available.split(":")[0]); - if (balances.length === 0) { + if (state.balances.length === 0) { return ( - + ); } @@ -111,23 +164,26 @@ export function BalanceView({