diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/components')
8 files changed, 99 insertions, 65 deletions
diff --git a/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx b/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx index 61c4a7661..f253d1996 100644 --- a/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx +++ b/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx @@ -20,12 +20,10 @@ */ import { AmountJson, Amounts } from "@gnu-taler/taler-util"; -import { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { useTranslationContext } from "../context/translation.js"; -import { Grid } from "../mui/Grid.js"; -import { AmountFieldHandler, TextFieldHandler } from "../mui/handlers.js"; +import { AmountFieldHandler, nullFunction, withSafe } from "../mui/handlers.js"; import { AmountField } from "./AmountField.js"; export default { @@ -39,9 +37,9 @@ function RenderAmount(): VNode { const handler: AmountFieldHandler = { value: value ?? Amounts.zeroOfCurrency("USD"), - onInput: async (e) => { + onInput: withSafe(async (e) => { setValue(e); - }, + }, nullFunction), error, }; const { i18n } = useTranslationContext(); diff --git a/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx b/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx index a56c82dee..47863d73e 100644 --- a/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx +++ b/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx @@ -18,7 +18,6 @@ import { ComponentChildren, Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { useTranslationContext } from "../../../web-util/src/index.browser.js"; import { - ErrorAlert, Alert as AlertNotification, useAlertContext, } from "../context/alert.js"; @@ -37,41 +36,78 @@ function AlertContext({ context: undefined | object; }): VNode { const [more, setMore] = useState(false); + const [wrap, setWrap] = useState(false); const { i18n } = useTranslationContext(); if (!more) { return ( <div style={{ display: "flex", justifyContent: "right" }}> - <a onClick={() => setMore(true)}> + <a + onClick={() => setMore(true)} + style={{ cursor: "pointer", textDecoration: "underline" }} + > <i18n.Translate>more info</i18n.Translate> </a> </div> ); } + const errorInfo = JSON.stringify( + context === undefined ? { cause } : { context, cause }, + undefined, + 2, + ); return ( - <pre style={{ overflow: "overlay" }}> - {JSON.stringify( - context === undefined ? { cause } : { context, cause }, - undefined, - 2, - )} - </pre> + <Fragment> + <div style={{ display: "flex", justifyContent: "right" }}> + <a + onClick={() => setWrap(!wrap)} + style={{ cursor: "pointer", textDecoration: "underline" }} + > + <i18n.Translate>wrap text</i18n.Translate> + </a> + + <a + onClick={() => navigator.clipboard.writeText(errorInfo)} + style={{ cursor: "pointer", textDecoration: "underline" }} + > + <i18n.Translate>copy content</i18n.Translate> + </a> + + <a + onClick={() => setMore(false)} + style={{ cursor: "pointer", textDecoration: "underline" }} + > + <i18n.Translate>less info</i18n.Translate> + </a> + </div> + <pre + style={ + wrap + ? { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + } + : { + overflow: "overlay", + } + } + > + {errorInfo} + </pre> + </Fragment> ); } export function ErrorAlertView({ - error: alert, + error, onClose, }: { - error: ErrorAlert; + error: AlertNotification; onClose?: () => Promise<void>; }): VNode { return ( - <Alert title={alert.message} severity={alert.type} onClose={onClose}> - <div style={{ display: "flex", flexDirection: "column" }}> - <div>{alert.description}</div> - <AlertContext context={alert.context} cause={alert.cause} /> - </div> - </Alert> + <Wrapper> + <AlertView alert={error} onClose={onClose} /> + </Wrapper> ); } @@ -86,6 +122,9 @@ export function AlertView({ <Alert title={alert.message} severity={alert.type} onClose={onClose}> <div style={{ display: "flex", flexDirection: "column" }}> <div>{alert.description}</div> + {alert.type === "error" ? ( + <AlertContext context={alert.context} cause={alert.cause} /> + ) : undefined} </div> </Alert> ); @@ -104,5 +143,5 @@ export function CurrentAlerts(): VNode { } function Wrapper({ children }: { children: ComponentChildren }): VNode { - return <div style={{ margin: "2em" }}>{children}</div>; + return <div style={{ margin: "1em" }}>{children}</div>; } diff --git a/packages/taler-wallet-webextension/src/components/PendingTransactions.stories.tsx b/packages/taler-wallet-webextension/src/components/PendingTransactions.stories.tsx index 2155c7aa6..d54dfe8fc 100644 --- a/packages/taler-wallet-webextension/src/components/PendingTransactions.stories.tsx +++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.stories.tsx @@ -24,7 +24,7 @@ import { Transaction, TransactionType, } from "@gnu-taler/taler-util"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { PendingTransactionsView as TestedComponent } from "./PendingTransactions.js"; export default { @@ -32,7 +32,7 @@ export default { component: TestedComponent, }; -export const OnePendingTransaction = createExample(TestedComponent, { +export const OnePendingTransaction = tests.createExample(TestedComponent, { transactions: [ { amountEffective: "USD:10", @@ -42,7 +42,7 @@ export const OnePendingTransaction = createExample(TestedComponent, { ], }); -export const ThreePendingTransactions = createExample(TestedComponent, { +export const ThreePendingTransactions = tests.createExample(TestedComponent, { transactions: [ { amountEffective: "USD:10", @@ -62,7 +62,7 @@ export const ThreePendingTransactions = createExample(TestedComponent, { ], }); -export const TenPendingTransactions = createExample(TestedComponent, { +export const TenPendingTransactions = tests.createExample(TestedComponent, { transactions: [ { amountEffective: "USD:10", diff --git a/packages/taler-wallet-webextension/src/components/QR.stories.tsx b/packages/taler-wallet-webextension/src/components/QR.stories.tsx index 83365670e..bdaa842f2 100644 --- a/packages/taler-wallet-webextension/src/components/QR.stories.tsx +++ b/packages/taler-wallet-webextension/src/components/QR.stories.tsx @@ -19,13 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { QR } from "./QR.js"; export default { title: "qr", }; -export const Restore = createExample(QR, { +export const Restore = tests.createExample(QR, { text: "taler://restore/6J0RZTJC6AV21WXK87BTE67WTHE9P2QSHF2BZXTP7PDZY2ARYBPG@sync1.demo.taler.net,sync2.demo.taler.net,sync1.demo.taler.net,sync3.demo.taler.net", }); diff --git a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx index 8c94e6e60..ef88d1c28 100644 --- a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx +++ b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx @@ -20,7 +20,7 @@ */ import { WalletContractData } from "@gnu-taler/taler-wallet-core"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ErrorView, HiddenView, @@ -86,10 +86,10 @@ const cd: WalletContractData = { deliveryLocation: undefined, }; -export const ShowingSimpleOrder = createExample(ShowView, { +export const ShowingSimpleOrder = tests.createExample(ShowView, { contractTerms: cd, }); -export const Error = createExample(ErrorView, { +export const Error = tests.createExample(ErrorView, { proposalId: "asd", error: { hasError: true, @@ -103,5 +103,5 @@ export const Error = createExample(ErrorView, { // }, }, }); -export const Loading = createExample(LoadingView, {}); -export const Hidden = createExample(HiddenView, {}); +export const Loading = tests.createExample(LoadingView, {}); +export const Hidden = tests.createExample(HiddenView, {}); diff --git a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx index 9871611f2..3e1f1dbe4 100644 --- a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx +++ b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx @@ -24,14 +24,14 @@ import { useState } from "preact/hooks"; import { Loading } from "../components/Loading.js"; import { Modal } from "../components/Modal.js"; import { Time } from "../components/Time.js"; -import { alertFromError } from "../context/alert.js"; +import { alertFromError, useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; import { useTranslationContext } from "../context/translation.js"; import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { ButtonHandler } from "../mui/handlers.js"; import { compose, StateViewMap } from "../utils/index.js"; import { Amount } from "./Amount.js"; -import { AlertView } from "./CurrentAlerts.js"; +import { ErrorAlertView } from "./CurrentAlerts.js"; import { Link } from "./styled/index.js"; const ContractTermsTable = styled.table` @@ -102,6 +102,7 @@ interface Props { function useComponentState({ proposalId }: Props): State { const api = useBackendContext(); const [show, setShow] = useState(false); + const { pushAlertOnError } = useAlertContext(); const hook = useAsyncAsHook(async () => { if (!show) return undefined; return await api.wallet.call(WalletApiOperation.GetContractTermsDetails, { @@ -110,10 +111,10 @@ function useComponentState({ proposalId }: Props): State { }, [show]); const hideHandler = { - onClick: async () => setShow(false), + onClick: pushAlertOnError(async () => setShow(false)), }; const showHandler = { - onClick: async () => setShow(true), + onClick: pushAlertOnError(async () => setShow(true)), }; if (!show) { return { @@ -161,8 +162,8 @@ export function ErrorView({ const { i18n } = useTranslationContext(); return ( <Modal title="Full detail" onClose={hideHandler}> - <AlertView - alert={alertFromError( + <ErrorAlertView + error={alertFromError( i18n.str`Could not load purchase proposal details`, error, { proposalId }, diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts index c25c0ed13..541b2d39e 100644 --- a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts @@ -28,7 +28,7 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State { const readOnly = !onChange; const [showContent, setShowContent] = useState<boolean>(readOnly); const { i18n } = useTranslationContext(); - const { pushAlert } = useAlertContext(); + const { pushAlertOnError } = useAlertContext(); /** * For the exchange selected, bring the status of the terms of service @@ -67,24 +67,20 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State { async function onUpdate(accepted: boolean): Promise<void> { if (!state) return; - try { - if (accepted) { - await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, { - exchangeBaseUrl: exchangeUrl, - etag: state.version, - }); - } else { - // mark as not accepted - await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, { - exchangeBaseUrl: exchangeUrl, - etag: undefined, - }); - } - // setAccepted(accepted); - if (!readOnly) onChange(accepted); //external update - } catch (e) { - pushAlert(alertFromError(i18n.str`Could not accept terms of service`, e)); + if (accepted) { + await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, { + exchangeBaseUrl: exchangeUrl, + etag: state.version, + }); + } else { + // mark as not accepted + await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, { + exchangeBaseUrl: exchangeUrl, + etag: undefined, + }); } + // setAccepted(accepted); + if (!readOnly) onChange(accepted); //external update } const accepted = state.status === "accepted"; @@ -94,20 +90,20 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State { showingTermsOfService: { value: showContent, button: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setShowContent(!showContent); - }, + }), }, }, terms: state, termsAccepted: { value: accepted, button: { - onClick: async () => { + onClick: pushAlertOnError(async () => { const newValue = !accepted; //toggle - onUpdate(newValue); + await onUpdate(newValue); setShowContent(false); - }, + }), }, }, }; diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx b/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx index 2479274cb..9ef1c4298 100644 --- a/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx @@ -19,11 +19,11 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; // import { ReadyView } from "./views.js"; export default { title: "TermsOfService", }; -// export const Ready = createExample(ReadyView, {}); +// export const Ready = tests.createExample(ReadyView, {}); |