diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
35 files changed, 278 insertions, 407 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts index 9ff3ddd1d..6b228188b 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts @@ -15,12 +15,13 @@ */ import { AmountJson, AmountString } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { talerDepositUri: string | undefined; @@ -37,8 +38,8 @@ export namespace State { error: undefined; } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface Ready { status: "ready"; @@ -57,7 +58,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts index dba435611..4cee7cfd0 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts @@ -16,7 +16,9 @@ import { Amounts } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -38,12 +40,16 @@ export function useComponentState({ }); return { deposit, uri: talerDepositUri, amount }; }); + const { i18n } = useTranslationContext(); if (!info) return { status: "loading", error: undefined }; if (info.hasError) { return { - status: "loading-uri", - error: info, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + info, + ), }; } diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts index 6a896fb7f..031dcffaa 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts @@ -50,12 +50,12 @@ describe("Deposit CTA states", () => { expect(status).equals("loading"); }, ({ status, error }) => { - expect(status).equals("loading-uri"); + expect(status).equals("error"); if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT"); + // if (!error.hasError) expect.fail(); + // if (error.operational) expect.fail(); + expect(error.cause?.message).eq("ERROR_NO-URI-FOR-DEPOSIT"); }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx index 2ec305de5..7fa43f878 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx @@ -17,7 +17,6 @@ import { Amounts } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { Amount } from "../../components/Amount.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; import { SubTitle, WalletAction } from "../../components/styled/index.js"; @@ -30,17 +29,6 @@ import { State } from "./index.js"; * @author sebasjm */ -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load deposit status</i18n.Translate>} - error={error} - /> - ); -} - export function ReadyView(state: State.Ready): VNode { const { i18n } = useTranslationContext(); @@ -55,7 +43,7 @@ export function ReadyView(state: State.Ready): VNode { {Amounts.isNonZero(state.cost) && ( <Part big - title={<i18n.Translate>Cost</i18n.Translate>} + title={i18n.str`Cost`} text={<Amount value={state.cost} />} kind="negative" /> @@ -63,14 +51,14 @@ export function ReadyView(state: State.Ready): VNode { {Amounts.isNonZero(state.fee) && ( <Part big - title={<i18n.Translate>Fee</i18n.Translate>} + title={i18n.str`Fee`} text={<Amount value={state.fee} />} kind="negative" /> )} <Part big - title={<i18n.Translate>To be received</i18n.Translate>} + title={i18n.str`To be received`} text={<Amount value={state.effective} />} kind="positive" /> diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts index 0569e8e5f..f39ab6794 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts @@ -14,16 +14,17 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AmountJson, TalerErrorDetail } from "@gnu-taler/taler-util"; +import { AmountJson } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { amount: string; @@ -45,8 +46,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -63,13 +64,12 @@ export namespace State { requestAmount: AmountJson; exchangeUrl: string; error: undefined; - operationError?: TalerErrorDetail; } } const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, "no-exchange": NoExchangesView, "selecting-exchange": ExchangeSelectionPage, ready: ReadyView, diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts index 998270e53..46b1262b1 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts @@ -23,7 +23,9 @@ import { import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { isFuture, parse } from "date-fns"; import { useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { useSelectedExchange } from "../../hooks/useSelectedExchange.js"; import { RecursiveState } from "../../utils/index.js"; @@ -40,6 +42,7 @@ export function useComponentState({ const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListExchanges, {}), ); + const { i18n } = useTranslationContext(); if (!hook) { return { @@ -49,10 +52,19 @@ export function useComponentState({ } if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; } + // if (hook.hasError) { + // return { + // status: "loading-uri", + // error: hook, + // }; + // } const exchangeList = hook.response.exchanges; @@ -60,10 +72,6 @@ export function useComponentState({ const [subject, setSubject] = useState<string | undefined>(); const [timestamp, setTimestamp] = useState<string | undefined>(); - const [operationError, setOperationError] = useState< - TalerErrorDetail | undefined - >(undefined); - const selectedExchange = useSelectedExchange({ currency: amount.currency, defaultExchange: undefined, @@ -93,11 +101,19 @@ export function useComponentState({ error: undefined, }; } + if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; + // return { + // status: "loading-uri", + // error: hook, + // }; } const { amountEffective, amountRaw } = hook.response; @@ -160,8 +176,8 @@ export function useComponentState({ subject === undefined ? undefined : !subject - ? "Can't be empty" - : undefined, + ? "Can't be empty" + : undefined, value: subject ?? "", onInput: async (e) => setSubject(e), }, @@ -183,7 +199,6 @@ export function useComponentState({ requestAmount, toBeReceived, error: undefined, - operationError, }; }; } diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx index 0ef5c697e..10e0e68d5 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx @@ -17,41 +17,24 @@ import { format } from "date-fns"; import { h, VNode } from "preact"; import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; -import { QR } from "../../components/QR.js"; import { - Link, SubTitle, SvgIcon, WalletAction, } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; -import { Grid } from "../../mui/Grid.js"; import { TextField } from "../../mui/TextField.js"; import editIcon from "../../svg/edit_24px.svg"; import { ExchangeDetails, InvoiceDetails } from "../../wallet/Transaction.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load</i18n.Translate>} - error={error} - /> - ); -} - export function ReadyView({ exchangeUrl, subject, expiration, - cancel, - operationError, create, toBeReceived, requestAmount, @@ -59,7 +42,7 @@ export function ReadyView({ }: State.Ready): VNode { const { i18n } = useTranslationContext(); - async function oneDayExpiration() { + async function oneDayExpiration(): Promise<void> { if (expiration.onInput) { expiration.onInput( format(new Date().getTime() + 1000 * 60 * 60 * 24, "dd/MM/yyyy"), @@ -67,14 +50,14 @@ export function ReadyView({ } } - async function oneWeekExpiration() { + async function oneWeekExpiration(): Promise<void> { if (expiration.onInput) { expiration.onInput( format(new Date().getTime() + 1000 * 60 * 60 * 24 * 7, "dd/MM/yyyy"), ); } } - async function _20DaysExpiration() { + async function _20DaysExpiration(): Promise<void> { if (expiration.onInput) { expiration.onInput( format(new Date().getTime() + 1000 * 60 * 60 * 24 * 20, "dd/MM/yyyy"), @@ -87,16 +70,6 @@ export function ReadyView({ <SubTitle> <i18n.Translate>Digital invoice</i18n.Translate> </SubTitle> - {operationError && ( - <ErrorTalerOperation - title={ - <i18n.Translate> - Could not finish the invoice creation - </i18n.Translate> - } - error={operationError} - /> - )} <section style={{ textAlign: "left" }}> <Part title={ @@ -125,9 +98,7 @@ export function ReadyView({ label="Subject" variant="filled" error={subject.error} - helperText={ - <i18n.Translate>Short description of the invoice</i18n.Translate> - } + helperText={i18n.str`Short description of the invoice`} required fullWidth value={subject.value} @@ -171,7 +142,7 @@ export function ReadyView({ </p> <Part - title={<i18n.Translate>Details</i18n.Translate>} + title={i18n.str`Details`} text={ <InvoiceDetails amount={{ @@ -187,11 +158,6 @@ export function ReadyView({ <i18n.Translate>Create</i18n.Translate> </Button> </section> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts index f3de0885d..82b2c7af5 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts @@ -20,12 +20,13 @@ import { PreparePayResult, TalerErrorDetail, } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { talerPayPullUri: string; @@ -48,8 +49,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -83,7 +84,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, "no-balance-for-currency": ReadyView, "no-enough-balance": ReadyView, ready: ReadyView, diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts index c0b97c106..9c4a3162e 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -25,7 +25,9 @@ import { } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -36,6 +38,7 @@ export function useComponentState({ onSuccess, }: Props): State { const api = useBackendContext(); + const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(async () => { const p2p = await api.wallet.call(WalletApiOperation.CheckPeerPullPayment, { talerUri: talerPayPullUri, @@ -63,10 +66,19 @@ export function useComponentState({ } if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; } + // if (hook.hasError) { + // return { + // status: "loading-uri", + // error: hook, + // }; + // } const { contractTerms, peerPullPaymentIncomingId } = hook.response.p2p; diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx index a53fa881a..6a9ab3cf7 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx @@ -17,26 +17,14 @@ import { Fragment, h, VNode } from "preact"; import { Amount } from "../../components/Amount.js"; import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; +import { PaymentButtons } from "../../components/PaymentButtons.js"; import { Link, SubTitle, WalletAction } from "../../components/styled/index.js"; import { Time } from "../../components/Time.js"; import { useTranslationContext } from "../../context/translation.js"; -import { PaymentButtons } from "../../components/PaymentButtons"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load</i18n.Translate>} - error={error} - /> - ); -} - export function ReadyView( state: State.Ready | State.NoBalanceForCurrency | State.NoEnoughBalance, ): VNode { @@ -60,25 +48,15 @@ export function ReadyView( </SubTitle> {operationError && ( <ErrorTalerOperation - title={ - <i18n.Translate> - Could not finish the payment operation - </i18n.Translate> - } + title={i18n.str`Could not finish the payment operation`} error={operationError} /> )} <section style={{ textAlign: "left" }}> + <Part title={i18n.str`Subject`} text={<div>{summary}</div>} /> + <Part title={i18n.str`Amount`} text={<Amount value={amount} />} /> <Part - title={<i18n.Translate>Subject</i18n.Translate>} - text={<div>{summary}</div>} - /> - <Part - title={<i18n.Translate>Amount</i18n.Translate>} - text={<Amount value={amount} />} - /> - <Part - title={<i18n.Translate>Valid until</i18n.Translate>} + title={i18n.str`Valid until`} text={<Time timestamp={expiration} format="dd MMMM yyyy, HH:mm" />} kind="neutral" /> @@ -91,11 +69,6 @@ export function ReadyView( payHandler={status === "ready" ? state.accept : undefined} goToWalletManualWithdraw={state.goToWalletManualWithdraw} /> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts index 2dc6b6741..e844c1706 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/index.ts @@ -21,12 +21,13 @@ import { PreparePayResultInsufficientBalance, PreparePayResultPaymentPossible, } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { BaseView, LoadingUriView } from "./views.js"; +import { BaseView } from "./views.js"; export interface Props { talerPayUri?: string; @@ -49,8 +50,8 @@ export namespace State { error: undefined; } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } interface BaseInfo { @@ -86,7 +87,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, "no-balance-for-currency": BaseView, "no-enough-balance": BaseView, confirmed: BaseView, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts index d4adf4bcb..6d7ef6b20 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -23,7 +23,9 @@ import { } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { Props, State } from "./index.js"; @@ -36,6 +38,7 @@ export function useComponentState({ }: Props): State { const [payErrMsg, setPayErrMsg] = useState<TalerError | undefined>(undefined); const api = useBackendContext(); + const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(async () => { if (!talerPayUri) throw Error("ERROR_NO-URI-FOR-PAYMENT"); @@ -80,10 +83,19 @@ export function useComponentState({ if (!hook) return { status: "loading", error: undefined }; if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; } + // if (hook.hasError) { + // return { + // status: "loading-uri", + // error: hook, + // }; + // } const { payStatus } = hook.response; const amount = Amounts.parseOrThrow(payStatus.amountRaw); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts index 077930972..123e95a87 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -54,10 +54,10 @@ describe("Payment CTA states", () => { expect(error).undefined; }, ({ status, error }) => { - expect(status).equals("loading-uri"); + expect(status).equals("error"); if (error === undefined) expect.fail(); - expect(error.hasError).true; - expect(error.operational).false; + // expect(error.hasError).true; + // expect(error.operational).false; }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx index efc8bcfc4..244ac5886 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx @@ -19,28 +19,17 @@ import { Amounts, MerchantContractTerms as ContractTerms, PreparePayResultType, + TranslatedString, } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; -import { LoadingError } from "../../components/LoadingError.js"; import { Part } from "../../components/Part.js"; import { PaymentButtons } from "../../components/PaymentButtons.js"; -import { Link, SuccessBox, WarningBox } from "../../components/styled/index.js"; +import { SuccessBox, WarningBox } from "../../components/styled/index.js"; import { Time } from "../../components/Time.js"; import { useTranslationContext } from "../../context/translation.js"; import { MerchantDetails, PurchaseDetails } from "../../wallet/Transaction.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load pay status</i18n.Translate>} - error={error} - /> - ); -} - type SupportedStates = | State.Ready | State.Confirmed @@ -66,17 +55,17 @@ export function BaseView(state: SupportedStates): VNode { <section style={{ textAlign: "left" }}> <Part - title={<i18n.Translate>Purchase</i18n.Translate>} - text={contractTerms.summary} + title={i18n.str`Purchase`} + text={contractTerms.summary as TranslatedString} kind="neutral" /> <Part - title={<i18n.Translate>Merchant</i18n.Translate>} + title={i18n.str`Merchant`} text={<MerchantDetails merchant={contractTerms.merchant} />} kind="neutral" /> <Part - title={<i18n.Translate>Details</i18n.Translate>} + title={i18n.str`Details`} text={ <PurchaseDetails price={price} @@ -93,14 +82,14 @@ export function BaseView(state: SupportedStates): VNode { /> {contractTerms.order_id && ( <Part - title={<i18n.Translate>Receipt</i18n.Translate>} - text={`#${contractTerms.order_id}`} + title={i18n.str`Receipt`} + text={`#${contractTerms.order_id}` as TranslatedString} kind="neutral" /> )} {contractTerms.pay_deadline && ( <Part - title={<i18n.Translate>Valid until</i18n.Translate>} + title={i18n.str`Valid until`} text={ <Time timestamp={AbsoluteTime.fromTimestamp( @@ -121,11 +110,6 @@ export function BaseView(state: SupportedStates): VNode { payHandler={state.status === "ready" ? state.payHandler : undefined} goToWalletManualWithdraw={state.goToWalletManualWithdraw} /> - <section> - <Link upperCased onClick={state.cancel}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </Fragment> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts index 4a6fc79c9..79056c15b 100644 --- a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts @@ -14,12 +14,13 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { talerRecoveryUri?: string; @@ -36,8 +37,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -53,7 +54,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts index 4fef2c862..078e53bf9 100644 --- a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts @@ -16,7 +16,9 @@ import { parseRecoveryUri } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { Alert } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { Props, State } from "./index.js"; export function useComponentState({ @@ -25,13 +27,16 @@ export function useComponentState({ onSuccess, }: Props): State { const api = useBackendContext(); + const { i18n } = useTranslationContext(); if (!talerRecoveryUri) { return { - status: "loading-uri", + status: "error", error: { - operational: false, - hasError: true, - message: "Missing URI", + type: "error", + message: i18n.str`Missing URI`, + description: i18n.str``, + cause: new Error("something"), + context: {}, }, }; } @@ -39,11 +44,13 @@ export function useComponentState({ if (!info) { return { - status: "loading-uri", + status: "error", error: { - operational: false, - hasError: true, - message: "Could not be read", + type: "error", + message: i18n.str`Could not parse the recovery URI`, + description: i18n.str``, + cause: new Error("something"), + context: {}, }, }; } diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx b/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx index 371516932..858349ef3 100644 --- a/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx @@ -15,28 +15,12 @@ */ import { Fragment, h, VNode } from "preact"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { SubTitle, WalletAction } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={ - <i18n.Translate> - Could not load backup recovery information - </i18n.Translate> - } - error={error} - /> - ); -} - export function ReadyView({ accept, cancel }: State.Ready): VNode { const { i18n } = useTranslationContext(); return ( diff --git a/packages/taler-wallet-webextension/src/cta/Refund/index.ts b/packages/taler-wallet-webextension/src/cta/Refund/index.ts index f79a77680..e90f770ff 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/index.ts @@ -15,17 +15,13 @@ */ import { AmountJson, Product } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { - IgnoredView, - InProgressView, - LoadingUriView, - ReadyView, -} from "./views.js"; +import { IgnoredView, InProgressView, ReadyView } from "./views.js"; export interface Props { talerRefundUri?: string; @@ -47,8 +43,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } interface BaseInfo { @@ -81,7 +77,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, "in-progress": InProgressView, ignored: IgnoredView, ready: ReadyView, diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts index 9e3311b65..5a5073ba3 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/state.ts @@ -17,7 +17,9 @@ import { Amounts, NotificationType } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -27,6 +29,7 @@ export function useComponentState({ onSuccess, }: Props): State { const api = useBackendContext(); + const { i18n } = useTranslationContext(); const [ignored, setIgnored] = useState(false); const info = useAsyncAsHook(async () => { @@ -49,10 +52,19 @@ export function useComponentState({ } if (info.hasError) { return { - status: "loading-uri", - error: info, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + info, + ), }; } + // if (info.hasError) { + // return { + // status: "loading-uri", + // error: info, + // }; + // } const { refund, uri } = info.response; diff --git a/packages/taler-wallet-webextension/src/cta/Refund/test.ts b/packages/taler-wallet-webextension/src/cta/Refund/test.ts index 24d483a9a..8c4daa4d2 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/test.ts @@ -53,11 +53,11 @@ describe("Refund CTA states", () => { expect(error).undefined; }, ({ status, error }) => { - expect(status).equals("loading-uri"); + expect(status).equals("error"); if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-REFUND"); + // if (!error.hasError) expect.fail(); + // if (error.operational) expect.fail(); + expect(error.cause?.message).eq("ERROR_NO-URI-FOR-REFUND"); }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx index a55bc43dd..16e1c519c 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx @@ -17,26 +17,14 @@ import { Amounts } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { Amount } from "../../components/Amount.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; +import { ProductList } from "../../components/ProductList.js"; import { Link, SubTitle, WalletAction } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; -import { ProductList } from "../../components/ProductList.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load refund status</i18n.Translate>} - error={error} - /> - ); -} - export function IgnoredView(state: State.Ignored): VNode { const { i18n } = useTranslationContext(); @@ -73,13 +61,13 @@ export function InProgressView(state: State.InProgress): VNode { <section> <Part big - title={<i18n.Translate>Total to refund</i18n.Translate>} + title={i18n.str`Total to refund`} text={<Amount value={state.awaitingAmount} />} kind="negative" /> <Part big - title={<i18n.Translate>Refunded</i18n.Translate>} + title={i18n.str`Refunded`} text={<Amount value={state.amount} />} kind="negative" /> @@ -112,21 +100,21 @@ export function ReadyView(state: State.Ready): VNode { <section> <Part big - title={<i18n.Translate>Order amount</i18n.Translate>} + title={i18n.str`Order amount`} text={<Amount value={state.amount} />} kind="neutral" /> {Amounts.isNonZero(state.granted) && ( <Part big - title={<i18n.Translate>Already refunded</i18n.Translate>} + title={i18n.str`Already refunded`} text={<Amount value={state.granted} />} kind="neutral" /> )} <Part big - title={<i18n.Translate>Refund offered</i18n.Translate>} + title={i18n.str`Refund offered`} text={<Amount value={state.awaitingAmount} />} kind="positive" /> @@ -147,11 +135,6 @@ export function ReadyView(state: State.Ready): VNode { </i18n.Translate> </Button> </section> - <section> - <Link upperCased onClick={state.cancel}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Tip/index.ts b/packages/taler-wallet-webextension/src/cta/Tip/index.ts index 62e0688be..5e56db7bc 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/index.ts @@ -15,17 +15,13 @@ */ import { AmountJson } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { - AcceptedView, - IgnoredView, - LoadingUriView, - ReadyView, -} from "./views.js"; +import { AcceptedView, IgnoredView, ReadyView } from "./views.js"; export interface Props { talerTipUri?: string; @@ -48,8 +44,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -75,7 +71,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, accepted: AcceptedView, ignored: IgnoredView, ready: ReadyView, diff --git a/packages/taler-wallet-webextension/src/cta/Tip/state.ts b/packages/taler-wallet-webextension/src/cta/Tip/state.ts index e83755119..29a9c4c71 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/state.ts @@ -16,7 +16,9 @@ import { Amounts } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -26,6 +28,7 @@ export function useComponentState({ onSuccess, }: Props): State { const api = useBackendContext(); + const { i18n } = useTranslationContext(); const tipInfo = useAsyncAsHook(async () => { if (!talerTipUri) throw Error("ERROR_NO-URI-FOR-TIP"); const tip = await api.wallet.call(WalletApiOperation.PrepareTip, { @@ -42,10 +45,19 @@ export function useComponentState({ } if (tipInfo.hasError) { return { - status: "loading-uri", - error: tipInfo, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + tipInfo, + ), }; } + // if (tipInfo.hasError) { + // return { + // status: "loading-uri", + // error: tipInfo, + // }; + // } const { tip } = tipInfo.response; diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Tip/test.ts index 5688d82a9..2cc95f424 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/test.ts @@ -23,8 +23,7 @@ import { Amounts } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { expect } from "chai"; import { tests } from "../../../../web-util/src/index.browser.js"; -import { mountHook, nullFunction } from "../../test-utils.js"; -import { createWalletApiMock } from "../../test-utils.js"; +import { createWalletApiMock, nullFunction } from "../../test-utils.js"; import { Props } from "./index.js"; import { useComponentState } from "./state.js"; @@ -47,11 +46,9 @@ describe("Tip CTA states", () => { expect(error).undefined; }, ({ status, error }) => { - expect(status).equals("loading-uri"); + expect(status).equals("error"); if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-TIP"); + expect(error.cause?.message).eq("ERROR_NO-URI-FOR-TIP"); }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/cta/Tip/views.tsx b/packages/taler-wallet-webextension/src/cta/Tip/views.tsx index fbc93c5ab..000daf19e 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Tip/views.tsx @@ -14,9 +14,9 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +import { TranslatedString } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { Amount } from "../../components/Amount.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; import { Link, SubTitle, WalletAction } from "../../components/styled/index.js"; @@ -24,17 +24,6 @@ import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load tip status</i18n.Translate>} - error={error} - /> - ); -} - export function IgnoredView(state: State.Ignored): VNode { const { i18n } = useTranslationContext(); return ( @@ -66,18 +55,18 @@ export function ReadyView(state: State.Ready): VNode { <i18n.Translate>The merchant is offering you a tip</i18n.Translate> </p> <Part - title={<i18n.Translate>Amount</i18n.Translate>} + title={i18n.str`Amount`} text={<Amount value={state.amount} />} kind="positive" /> <Part - title={<i18n.Translate>Merchant URL</i18n.Translate>} - text={state.merchantBaseUrl} + title={i18n.str`Merchant URL`} + text={state.merchantBaseUrl as TranslatedString} kind="neutral" /> <Part - title={<i18n.Translate>Exchange</i18n.Translate>} - text={state.exchangeBaseUrl} + title={i18n.str`Exchange`} + text={state.exchangeBaseUrl as TranslatedString} kind="neutral" /> </section> @@ -92,11 +81,6 @@ export function ReadyView(state: State.Ready): VNode { </i18n.Translate> </Button> </section> - <section> - <Link upperCased onClick={state.cancel.onClick}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts index 0715bb60e..b191b4efa 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts @@ -15,12 +15,13 @@ */ import { AmountJson, TalerErrorDetail } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { amount: string; @@ -37,8 +38,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -59,7 +60,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts index c09a524c8..ecea53848 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts @@ -22,7 +22,9 @@ import { import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { isFuture, parse } from "date-fns"; import { useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -33,6 +35,7 @@ export function useComponentState({ }: Props): State { const api = useBackendContext(); const amount = Amounts.parseOrThrow(amountStr); + const { i18n } = useTranslationContext(); const [subject, setSubject] = useState<string | undefined>(); const [timestamp, setTimestamp] = useState<string | undefined>(); @@ -59,10 +62,19 @@ export function useComponentState({ } if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; } + // if (hook.hasError) { + // return { + // status: "loading-uri", + // error: hook, + // }; + // } const { amountEffective, amountRaw } = hook.response; const debitAmount = Amounts.parseOrThrow(amountRaw); diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx index 0b034e3fb..cee61b3b8 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx @@ -17,10 +17,8 @@ import { format } from "date-fns"; import { h, VNode } from "preact"; import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; -import { QR } from "../../components/QR.js"; import { Link, SubTitle, WalletAction } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; @@ -28,17 +26,6 @@ import { TextField } from "../../mui/TextField.js"; import { TransferDetails } from "../../wallet/Transaction.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load</i18n.Translate>} - error={error} - /> - ); -} - export function ReadyView({ subject, expiration, @@ -80,11 +67,7 @@ export function ReadyView({ </SubTitle> {operationError && ( <ErrorTalerOperation - title={ - <i18n.Translate> - Could not finish the transfer creation - </i18n.Translate> - } + title={i18n.str`Could not finish the transfer creation`} error={operationError} /> )} @@ -93,9 +76,7 @@ export function ReadyView({ <TextField label="Subject" variant="filled" - helperText={ - <i18n.Translate>Short description of the transfer</i18n.Translate> - } + helperText={i18n.str`Short description of the transfer`} error={subject.error} required fullWidth @@ -138,7 +119,7 @@ export function ReadyView({ </p> </p> <Part - title={<i18n.Translate>Details</i18n.Translate>} + title={i18n.str`Details`} text={ <TransferDetails amount={{ @@ -154,13 +135,6 @@ export function ReadyView({ <i18n.Translate>Create</i18n.Translate> </Button> </section> - <section> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts index fe6fb2ada..7bb8785d7 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts @@ -19,12 +19,13 @@ import { AmountJson, TalerErrorDetail, } from "@gnu-taler/taler-util"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView } from "./views.js"; +import { ReadyView } from "./views.js"; export interface Props { talerPayPushUri: string; @@ -41,8 +42,8 @@ export namespace State { } export interface LoadingUriError { - status: "loading-uri"; - error: HookError; + status: "error"; + error: ErrorAlert; } export interface BaseInfo { @@ -62,7 +63,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "loading-uri": LoadingUriView, + error: ErrorAlertView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts index 82c95b0c6..04fc0e0a7 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts @@ -22,7 +22,9 @@ import { } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; @@ -32,6 +34,7 @@ export function useComponentState({ onSuccess, }: Props): State { const api = useBackendContext(); + const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(async () => { return await api.wallet.call(WalletApiOperation.CheckPeerPushPayment, { talerUri: talerPayPushUri, @@ -49,10 +52,19 @@ export function useComponentState({ } if (hook.hasError) { return { - status: "loading-uri", - error: hook, + status: "error", + error: alertFromError( + i18n.str`Could not load the status of the term of service`, + hook, + ), }; } + // if (hook.hasError) { + // return { + // status: "loading-uri", + // error: hook, + // }; + // } const { contractTerms, peerPushPaymentIncomingId } = hook.response; diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx index c43b0ff52..d2402db3a 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx @@ -17,7 +17,6 @@ import { h, VNode } from "preact"; import { Amount } from "../../components/Amount.js"; import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { LogoHeader } from "../../components/LogoHeader.js"; import { Part } from "../../components/Part.js"; import { Link, SubTitle, WalletAction } from "../../components/styled/index.js"; @@ -26,17 +25,6 @@ import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not load</i18n.Translate>} - error={error} - /> - ); -} - export function ReadyView({ accept, summary, @@ -54,25 +42,15 @@ export function ReadyView({ </SubTitle> {operationError && ( <ErrorTalerOperation - title={ - <i18n.Translate> - Could not finish the pickup operation - </i18n.Translate> - } + title={i18n.str`Could not finish the pickup operation`} error={operationError} /> )} <section style={{ textAlign: "left" }}> + <Part title={i18n.str`Subject`} text={<div>{summary}</div>} /> + <Part title={i18n.str`Amount`} text={<Amount value={amount} />} /> <Part - title={<i18n.Translate>Subject</i18n.Translate>} - text={<div>{summary}</div>} - /> - <Part - title={<i18n.Translate>Amount</i18n.Translate>} - text={<Amount value={amount} />} - /> - <Part - title={<i18n.Translate>Valid until</i18n.Translate>} + title={i18n.str`Valid until`} text={<Time timestamp={expiration} format="dd MMMM yyyy, HH:mm" />} kind="neutral" /> @@ -84,11 +62,6 @@ export function ReadyView({ </i18n.Translate> </Button> </section> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 25d4e44e5..7dfc7c141 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -27,7 +27,9 @@ import { import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js"; -import { LoadingInfoView, LoadingUriView, SuccessView } from "./views.js"; +import { SuccessView } from "./views.js"; +import { ErrorAlert } from "../../context/alert.js"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; export interface PropsFromURI { talerWithdrawUri: string | undefined; @@ -44,7 +46,6 @@ export interface PropsFromParams { export type State = | State.Loading | State.LoadingUriError - | State.LoadingInfoError | SelectExchangeState.NoExchange | SelectExchangeState.Selecting | State.Success; @@ -55,12 +56,8 @@ export namespace State { error: undefined; } export interface LoadingUriError { - status: "uri-error"; - error: HookError; - } - export interface LoadingInfoError { - status: "amount-error"; - error: HookError; + status: "error"; + error: ErrorAlert; } export type Success = { @@ -86,8 +83,7 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, - "uri-error": LoadingUriView, - "amount-error": LoadingInfoView, + error: ErrorAlertView, "no-exchange": NoExchangesView, "selecting-exchange": ExchangeSelectionPage, success: SuccessView, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index d1853442b..18c467aae 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -23,7 +23,9 @@ import { } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; +import { alertFromError } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { useSelectedExchange } from "../../hooks/useSelectedExchange.js"; import { RecursiveState } from "../../utils/index.js"; @@ -35,6 +37,7 @@ export function useComponentStateFromParams({ onSuccess, }: PropsFromParams): RecursiveState<State> { const api = useBackendContext(); + const { i18n } = useTranslationContext(); const uriInfoHook = useAsyncAsHook(async () => { const exchanges = await api.wallet.call( WalletApiOperation.ListExchanges, @@ -47,8 +50,11 @@ export function useComponentStateFromParams({ if (uriInfoHook.hasError) { return { - status: "uri-error", - error: uriInfoHook, + status: "error", + error: alertFromError( + i18n.str`Could not load the list of exchanges`, + uriInfoHook, + ), }; } @@ -95,6 +101,7 @@ export function useComponentStateFromURI({ onSuccess, }: PropsFromURI): RecursiveState<State> { const api = useBackendContext(); + const { i18n } = useTranslationContext(); /** * Ask the wallet about the withdraw URI */ @@ -123,8 +130,11 @@ export function useComponentStateFromURI({ if (uriInfoHook.hasError) { return { - status: "uri-error", - error: uriInfoHook, + status: "error", + error: alertFromError( + i18n.str`Could not load info from URI`, + uriInfoHook, + ), }; } @@ -194,6 +204,7 @@ function exchangeSelectionState( } return () => { + const { i18n } = useTranslationContext(); const [ageRestricted, setAgeRestricted] = useState(0); const currentExchange = selectedExchange.selected; const tosNeedToBeAccepted = @@ -255,8 +266,11 @@ function exchangeSelectionState( } if (amountHook.hasError) { return { - status: "amount-error", - error: amountHook, + status: "error", + error: alertFromError( + i18n.str`Could not load the withdrawal details`, + amountHook, + ), }; } if (!amountHook.response) { diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts index 3277ac18d..2caa50dca 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts @@ -84,11 +84,11 @@ describe("Withdraw CTA states", () => { expect(status).equals("loading"); }, ({ status, error }) => { - if (status != "uri-error") expect.fail(); + if (status != "error") expect.fail(); if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL"); + // if (!error.hasError) expect.fail(); + // if (error.operational) expect.fail(); + expect(error.cause?.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL"); }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx index 9dbe24b7e..cf87b35bb 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -19,16 +19,10 @@ import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { Amount } from "../../components/Amount.js"; import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js"; -import { LoadingError } from "../../components/LoadingError.js"; import { Part } from "../../components/Part.js"; import { QR } from "../../components/QR.js"; import { SelectList } from "../../components/SelectList.js"; -import { - Input, - Link, - LinkSuccess, - SvgIcon, -} from "../../components/styled/index.js"; +import { Input, LinkSuccess, SvgIcon } from "../../components/styled/index.js"; import { TermsOfService } from "../../components/TermsOfService/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; @@ -36,30 +30,6 @@ import editIcon from "../../svg/edit_24px.svg"; import { ExchangeDetails, WithdrawDetails } from "../../wallet/Transaction.js"; import { State } from "./index.js"; -export function LoadingUriView({ error }: State.LoadingUriError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={ - <i18n.Translate>Could not get the info from the URI</i18n.Translate> - } - error={error} - /> - ); -} - -export function LoadingInfoView({ error }: State.LoadingInfoError): VNode { - const { i18n } = useTranslationContext(); - - return ( - <LoadingError - title={<i18n.Translate>Could not get info of withdrawal</i18n.Translate>} - error={error} - /> - ); -} - export function SuccessView(state: State.Success): VNode { const { i18n } = useTranslationContext(); const currentTosVersionIsAccepted = @@ -68,11 +38,7 @@ export function SuccessView(state: State.Success): VNode { <Fragment> {state.doWithdrawal.error && ( <ErrorTalerOperation - title={ - <i18n.Translate> - Could not finish the withdrawal operation - </i18n.Translate> - } + title={i18n.str`Could not finish the withdrawal operation`} error={state.doWithdrawal.error.errorDetail} /> )} @@ -103,7 +69,7 @@ export function SuccessView(state: State.Success): VNode { big /> <Part - title={<i18n.Translate>Details</i18n.Translate>} + title={i18n.str`Details`} text={ <WithdrawDetails amount={{ @@ -116,7 +82,7 @@ export function SuccessView(state: State.Success): VNode { {state.ageRestriction && ( <Input> <SelectList - label={<i18n.Translate>Age restriction</i18n.Translate>} + label={i18n.str`Age restriction`} list={state.ageRestriction.list} name="age" value={state.ageRestriction.value} @@ -148,11 +114,6 @@ export function SuccessView(state: State.Success): VNode { {state.talerWithdrawUri ? ( <WithdrawWithMobile talerWithdrawUri={state.talerWithdrawUri} /> ) : undefined} - <section> - <Link upperCased onClick={state.cancel}> - <i18n.Translate>Cancel</i18n.Translate> - </Link> - </section> </Fragment> ); } @@ -168,11 +129,7 @@ function WithdrawWithMobile({ return ( <section> <LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}> - {!showQR ? ( - <i18n.Translate>Withdraw to a mobile phone</i18n.Translate> - ) : ( - <i18n.Translate>Hide QR</i18n.Translate> - )} + {!showQR ? i18n.str`Withdraw to a mobile phone` : i18n.str`Hide QR`} </LinkSuccess> {showQR && ( <div> |