aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/components')
-rw-r--r--packages/taler-wallet-webextension/src/components/AmountField.stories.tsx8
-rw-r--r--packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx75
-rw-r--r--packages/taler-wallet-webextension/src/components/PendingTransactions.stories.tsx8
-rw-r--r--packages/taler-wallet-webextension/src/components/QR.stories.tsx4
-rw-r--r--packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx10
-rw-r--r--packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx13
-rw-r--r--packages/taler-wallet-webextension/src/components/TermsOfService/state.ts42
-rw-r--r--packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx4
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>
+ &nbsp;&nbsp;
+ <a
+ onClick={() => navigator.clipboard.writeText(errorInfo)}
+ style={{ cursor: "pointer", textDecoration: "underline" }}
+ >
+ <i18n.Translate>copy content</i18n.Translate>
+ </a>
+ &nbsp;&nbsp;
+ <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, {});