diff options
Diffstat (limited to 'packages/taler-wallet-webextension')
8 files changed, 337 insertions, 137 deletions
diff --git a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx index 80dc18f49..f9b30907d 100644 --- a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx +++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx @@ -16,6 +16,7 @@ import { AbsoluteTime, Amounts, + ExtendedStatus, NotificationType, Transaction, } from "@gnu-taler/taler-util"; @@ -56,7 +57,9 @@ export function PendingTransactions({ goToTransaction }: Props): VNode { const transactions = !state || state.hasError ? cache.tx - : state.response.transactions.filter((t) => t.pending); + : state.response.transactions.filter( + (t) => t.extendedStatus === ExtendedStatus.Pending, + ); if (state && !state.hasError) { cache.tx = transactions; diff --git a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx index c2c4b52e3..71d7edaf0 100644 --- a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx +++ b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx @@ -22,6 +22,7 @@ import { Transaction, TransactionType, WithdrawalType, + ExtendedStatus, } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; import { useTranslationContext } from "../context/translation.js"; @@ -52,7 +53,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode { timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)} iconPath={"W"} pending={ - tx.pending + tx.extendedStatus === ExtendedStatus.Pending ? tx.withdrawalDetails.type === WithdrawalType.TalerBankIntegrationApi ? !tx.withdrawalDetails.confirmed diff --git a/packages/taler-wallet-webextension/src/context/alert.ts b/packages/taler-wallet-webextension/src/context/alert.ts index e67d94671..8527f30f6 100644 --- a/packages/taler-wallet-webextension/src/context/alert.ts +++ b/packages/taler-wallet-webextension/src/context/alert.ts @@ -48,7 +48,14 @@ type Type = { alerts: Alert[]; pushAlert: (n: Alert) => void; removeAlert: (n: Alert) => void; + /** + * + * @param h + * @returns + * @deprecated use safely + */ pushAlertOnError: <T>(h: (p: T) => Promise<void>) => SafeHandler<T>; + safely: <T>(h: (p: T) => Promise<void>, error: TranslatedString) => SafeHandler<T>; }; const initial: Type = { @@ -56,6 +63,9 @@ const initial: Type = { pushAlertOnError: () => { throw Error("alert context not initialized"); }, + safely: () => { + throw Error("alert context not initialized"); + }, pushAlert: () => { null; }, @@ -100,8 +110,18 @@ export const AlertProvider = ({ children }: Props): VNode => { }); } + function safely<T>( + handler: (p: T) => Promise<void>, + message: TranslatedString + ): SafeHandler<T> { + return withSafe(handler, (e) => { + const a = alertFromError(message, e); + pushAlert(a); + }); + } + return h(Context.Provider, { - value: { alerts, pushAlert, removeAlert, pushAlertOnError }, + value: { alerts, pushAlert, removeAlert, pushAlertOnError, safely }, children, }); }; diff --git a/packages/taler-wallet-webextension/src/mui/Button.tsx b/packages/taler-wallet-webextension/src/mui/Button.tsx index bca0d6231..31e97f008 100644 --- a/packages/taler-wallet-webextension/src/mui/Button.tsx +++ b/packages/taler-wallet-webextension/src/mui/Button.tsx @@ -20,6 +20,7 @@ import { theme, Colors, rippleEnabled, rippleEnabledOutlined } from "./style"; // eslint-disable-next-line import/extensions import { alpha } from "./colors/manipulation"; import { useState } from "preact/hooks"; +import { SafeHandler } from "./handlers.js"; export const buttonBaseStyle = css` display: inline-flex; @@ -55,6 +56,7 @@ interface Props { tooltip?: string; color?: Colors; onClick?: () => Promise<void>; + // onClick?: SafeHandler<void>; } const button = css` diff --git a/packages/taler-wallet-webextension/src/stories.tsx b/packages/taler-wallet-webextension/src/stories.tsx index a7b8a4d06..b5748d962 100644 --- a/packages/taler-wallet-webextension/src/stories.tsx +++ b/packages/taler-wallet-webextension/src/stories.tsx @@ -35,6 +35,7 @@ import * as popup from "./popup/index.stories.js"; import * as wallet from "./wallet/index.stories.js"; import { renderStories } from "@gnu-taler/web-util/lib/index.browser"; +import { AlertProvider } from "./context/alert.js"; function main(): void { renderStories( @@ -56,28 +57,28 @@ function getWrapperForGroup(group: string): FunctionComponent { case "popup": return function PopupWrapper({ children }: any) { return ( - <Fragment> + <AlertProvider> <PopupNavBar /> <PopupBox>{children}</PopupBox> - </Fragment> + </AlertProvider> ); }; case "wallet": return function WalletWrapper({ children }: any) { return ( - <Fragment> + <AlertProvider> <LogoHeader /> <WalletNavBar /> <WalletBox>{children}</WalletBox> - </Fragment> + </AlertProvider> ); }; case "cta": return function WalletWrapper({ children }: any) { return ( - <Fragment> + <AlertProvider> <WalletAction>{children}</WalletAction> - </Fragment> + </AlertProvider> ); }; default: diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 46fe02225..0db06fe08 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -556,9 +556,11 @@ function WalletTemplate({ {goToTransaction ? ( <PendingTransactions goToTransaction={goToTransaction} /> ) : undefined} - <CurrentAlerts /> <WalletBox> - <AlertProvider>{children}</AlertProvider> + <AlertProvider> + <CurrentAlerts /> + {children} + </AlertProvider> </WalletBox> </Fragment> ); diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx index fea96a02c..21e9ee55e 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -39,14 +39,13 @@ import { WithdrawalDetails, WithdrawalType, } from "@gnu-taler/taler-util"; -import { DevContextProviderForTesting } from "../context/devContext.js"; // import { // createExample, // createExampleWithCustomContext as createExampleInCustomContext, // } from "../test-utils.js"; -import { TransactionView as TestedComponent } from "./Transaction.js"; import { tests } from "@gnu-taler/web-util/lib/index.browser"; import beer from "../../static-dev/beer.png"; +import { TransactionView as TestedComponent } from "./Transaction.js"; export default { title: "transaction details", @@ -54,6 +53,7 @@ export default { argTypes: { onRetry: { action: "onRetry" }, onDelete: { action: "onDelete" }, + onCancel: { action: "onCancel" }, onBack: { action: "onBack" }, }, }; @@ -62,10 +62,10 @@ const commonTransaction = { amountRaw: "KUDOS:11", amountEffective: "KUDOS:9.2", extendedStatus: ExtendedStatus.Done, - pending: false, + pending: undefined as any as boolean, //deprecated timestamp: TalerProtocolTimestamp.now(), transactionId: "txn:deposit:12", - frozen: false, + frozen: undefined as any as boolean, //deprecated type: TransactionType.Deposit, } as TransactionCommon; @@ -255,7 +255,7 @@ export const WithdrawFiveMinutesAgoAndPending = tests.createExample( timestamp: TalerProtocolTimestamp.fromSeconds( new Date().getTime() / 1000 - 60 * 5, ), - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }), ); @@ -295,7 +295,7 @@ export const WithdrawPendingManual = tests.createExample( exchangePaytoUris: ["payto://iban/ES8877998399652238"], reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", } as WithdrawalDetails, - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }), ); @@ -311,7 +311,7 @@ export const WithdrawPendingTalerBankUnconfirmed = tests.createExample( reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", bankConfirmationUrl: "http://bank.demo.taler.net", }, - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }, ); @@ -326,7 +326,7 @@ export const WithdrawPendingTalerBankConfirmed = tests.createExample( confirmed: true, reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", }, - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }, ); @@ -443,7 +443,10 @@ export const PaymentWithoutFee = tests.createExample(TestedComponent, { }); export const PaymentPending = tests.createExample(TestedComponent, { - transaction: { ...exampleData.payment, pending: true }, + transaction: { + ...exampleData.payment, + extendedStatus: ExtendedStatus.Pending, + }, }); export const PaymentWithProducts = tests.createExample(TestedComponent, { @@ -540,7 +543,10 @@ export const DepositError = tests.createExample(TestedComponent, { }); export const DepositPending = tests.createExample(TestedComponent, { - transaction: { ...exampleData.deposit, pending: true }, + transaction: { + ...exampleData.deposit, + extendedStatus: ExtendedStatus.Pending, + }, }); export const Refresh = tests.createExample(TestedComponent, { @@ -566,7 +572,7 @@ export const TipError = tests.createExample(TestedComponent, { }); export const TipPending = tests.createExample(TestedComponent, { - transaction: { ...exampleData.tip, pending: true }, + transaction: { ...exampleData.tip, extendedStatus: ExtendedStatus.Pending }, }); export const Refund = tests.createExample(TestedComponent, { @@ -581,7 +587,10 @@ export const RefundError = tests.createExample(TestedComponent, { }); export const RefundPending = tests.createExample(TestedComponent, { - transaction: { ...exampleData.refund, pending: true }, + transaction: { + ...exampleData.refund, + extendedStatus: ExtendedStatus.Pending, + }, }); export const InvoiceCreditComplete = tests.createExample(TestedComponent, { @@ -591,7 +600,7 @@ export const InvoiceCreditComplete = tests.createExample(TestedComponent, { export const InvoiceCreditIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_credit, - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }); @@ -609,6 +618,6 @@ export const TransferDebitComplete = tests.createExample(TestedComponent, { export const TransferDebitIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_debit, - pending: true, + extendedStatus: ExtendedStatus.Pending, }, }); diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index c6fa9ec68..5ed05f87f 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -18,6 +18,7 @@ import { AbsoluteTime, AmountJson, Amounts, + ExtendedStatus, Location, MerchantInfo, NotificationType, @@ -60,11 +61,12 @@ import { WarningBox, } from "../components/styled/index.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 { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; +import { SafeHandler } from "../mui/handlers.js"; import { Pages } from "../NavigationBar.js"; interface Props { @@ -116,6 +118,12 @@ export function TransactionPage({ onSend={async () => { null; }} + onCancel={async () => { + await api.wallet.call(WalletApiOperation.AbortTransaction, { + transactionId, + }); + goToWalletHistory(currency); + }} onDelete={async () => { await api.wallet.call(WalletApiOperation.DeleteTransaction, { transactionId, @@ -141,6 +149,7 @@ export function TransactionPage({ export interface WalletTransactionProps { transaction: Transaction; onSend: () => Promise<void>; + onCancel: () => Promise<void>; onDelete: () => Promise<void>; onRetry: () => Promise<void>; onRefund: (id: string) => Promise<void>; @@ -155,18 +164,29 @@ const PurchaseDetailsTable = styled.table` } `; -export function TransactionView({ +type TransactionTemplateProps = Omit< + Omit<WalletTransactionProps, "onRefund">, + "onBack" +> & { + children: ComponentChildren; +}; + +function TransactionTemplate({ transaction, onDelete, onRetry, onSend, - onRefund, -}: WalletTransactionProps): VNode { + onCancel, + children, +}: TransactionTemplateProps): VNode { + const { i18n } = useTranslationContext(); const [confirmBeforeForget, setConfirmBeforeForget] = useState(false); + const [confirmBeforeCancel, setConfirmBeforeCancel] = useState(false); + const { safely } = useAlertContext(); async function doCheckBeforeForget(): Promise<void> { if ( - transaction.pending && + transaction.extendedStatus === ExtendedStatus.Pending && transaction.type === TransactionType.Withdrawal ) { setConfirmBeforeForget(true); @@ -175,97 +195,64 @@ export function TransactionView({ } } - const SHOWING_RETRY_THRESHOLD_SECS = 30; - - const { i18n } = useTranslationContext(); - - function TransactionTemplate({ - children, - }: { - children: ComponentChildren; - }): VNode { - const showSend = false; - // (transaction.type === TransactionType.PeerPullCredit || - // transaction.type === TransactionType.PeerPushDebit) && - // !transaction.info.completed; - const showRetry = - transaction.error !== undefined || - transaction.timestamp.t_s === "never" || - (transaction.pending && - differenceInSeconds(new Date(), transaction.timestamp.t_s * 1000) > - SHOWING_RETRY_THRESHOLD_SECS); - - return ( - <Fragment> - <section style={{ padding: 8, textAlign: "center" }}> - {transaction?.error ? ( - transaction.error.code === 7025 ? ( - <AlertView - alert={{ - type: "warning", - message: i18n.str`KYC check required for the transaction to complete`, - description: - transaction.error.kycUrl && - typeof transaction.error.kycUrl === "string" ? ( - <div> - <i18n.Translate> - Follow this link to the{` `} - <a href={transaction.error.kycUrl}>KYC verifier</a> - </i18n.Translate> - </div> - ) : ( - i18n.str`No more information has been provided` - ), - }} - /> - ) : ( - <ErrorAlertView - error={alertFromError( - i18n.str`There was an error trying to complete the transaction`, - transaction.error, - )} - /> - ) - ) : undefined} - {transaction.pending && ( - <WarningBox> - <i18n.Translate>This transaction is not completed</i18n.Translate> - </WarningBox> - )} - </section> - <section>{children}</section> - <footer> - <div> - {showSend ? ( - <Button variant="contained" onClick={onSend}> - <i18n.Translate>Send</i18n.Translate> - </Button> - ) : null} - </div> - <div> - {showRetry ? ( - <Button variant="contained" onClick={onRetry}> - <i18n.Translate>Retry</i18n.Translate> - </Button> - ) : null} - <Button - variant="contained" - color="error" - onClick={doCheckBeforeForget} - > - <i18n.Translate>Forget</i18n.Translate> - </Button> - </div> - </footer> - </Fragment> - ); + async function doCheckBeforeCancel(): Promise<void> { + setConfirmBeforeCancel(true); } - if (transaction.type === TransactionType.Withdrawal) { - const total = Amounts.parseOrThrow(transaction.amountEffective); - const chosen = Amounts.parseOrThrow(transaction.amountRaw); - return ( - <TransactionTemplate> + const SHOWING_RETRY_THRESHOLD_SECS = 30; + + const showSend = false; + // (transaction.type === TransactionType.PeerPullCredit || + // transaction.type === TransactionType.PeerPushDebit) && + // !transaction.info.completed; + const showRetry = + transaction.error !== undefined || + transaction.timestamp.t_s === "never" || + (transaction.extendedStatus === ExtendedStatus.Pending && + differenceInSeconds(new Date(), transaction.timestamp.t_s * 1000) > + SHOWING_RETRY_THRESHOLD_SECS); + + const transactionStillActive = + transaction.extendedStatus !== ExtendedStatus.Aborted && + transaction.extendedStatus !== ExtendedStatus.Done && + transaction.extendedStatus !== ExtendedStatus.Failed; + return ( + <Fragment> + <section style={{ padding: 8, textAlign: "center" }}> + {transaction?.error ? ( + transaction.error.code === 7025 ? ( + <AlertView + alert={{ + type: "warning", + message: i18n.str`KYC check required for the transaction to complete`, + description: + transaction.error.kycUrl && + typeof transaction.error.kycUrl === "string" ? ( + <div> + <i18n.Translate> + Follow this link to the{` `} + <a href={transaction.error.kycUrl}>KYC verifier</a> + </i18n.Translate> + </div> + ) : ( + i18n.str`No more information has been provided` + ), + }} + /> + ) : ( + <ErrorAlertView + error={alertFromError( + i18n.str`There was an error trying to complete the transaction`, + transaction.error, + )} + /> + ) + ) : undefined} + {transaction.extendedStatus === ExtendedStatus.Pending && ( + <WarningBox> + <i18n.Translate>This transaction is not completed</i18n.Translate> + </WarningBox> + )} {confirmBeforeForget ? ( <Overlay> <CenteredDialog> @@ -282,18 +269,134 @@ export function TransactionView({ <Button variant="contained" color="secondary" - onClick={async () => setConfirmBeforeForget(false)} + onClick={ + (async () => + setConfirmBeforeForget(false)) as SafeHandler<void> + } > <i18n.Translate>Cancel</i18n.Translate> </Button> - <Button variant="contained" color="error" onClick={onDelete}> + <Button + variant="contained" + color="error" + onClick={safely( + onDelete, + i18n.str`Could not forget transaction`, + )} + > <i18n.Translate>Confirm</i18n.Translate> </Button> </footer> </CenteredDialog> </Overlay> ) : undefined} + {confirmBeforeCancel ? ( + <Overlay> + <CenteredDialog> + <header> + <i18n.Translate>Caution!</i18n.Translate> + </header> + <section> + <i18n.Translate> + Doing a cancelation while the transaction still active might + result in lost coins. Do you still want to cancel the + transaction? + </i18n.Translate> + </section> + <footer> + <Button + variant="contained" + color="secondary" + onClick={ + (async () => + setConfirmBeforeCancel(false)) as SafeHandler<void> + } + > + <i18n.Translate>No</i18n.Translate> + </Button> + + <Button + variant="contained" + color="error" + onClick={safely( + onCancel, + i18n.str`Could not cancel the active transaction`, + )} + > + <i18n.Translate>Yes</i18n.Translate> + </Button> + </footer> + </CenteredDialog> + </Overlay> + ) : undefined} + </section> + <section>{children}</section> + <footer> + <div> + {showSend ? ( + <Button + variant="contained" + onClick={safely(onSend, i18n.str`Could not send`)} + > + <i18n.Translate>Send</i18n.Translate> + </Button> + ) : null} + </div> + <div> + {showRetry ? ( + <Button + variant="contained" + onClick={safely(onRetry, i18n.str`Could not retry`)} + > + <i18n.Translate>Retry</i18n.Translate> + </Button> + ) : null} + {transactionStillActive ? ( + <Button + variant="contained" + color="error" + onClick={doCheckBeforeCancel as SafeHandler<void>} + > + <i18n.Translate>Cancel</i18n.Translate> + </Button> + ) : ( + <Button + variant="contained" + color="error" + onClick={doCheckBeforeForget as SafeHandler<void>} + > + <i18n.Translate>Forget</i18n.Translate> + </Button> + )} + </div> + </footer> + </Fragment> + ); +} + +export function TransactionView({ + transaction, + onDelete, + onRetry, + onSend, + onRefund, + onCancel, +}: WalletTransactionProps): VNode { + const { i18n } = useTranslationContext(); + const { safely } = useAlertContext(); + + if (transaction.type === TransactionType.Withdrawal) { + const total = Amounts.parseOrThrow(transaction.amountEffective); + const chosen = Amounts.parseOrThrow(transaction.amountRaw); + return ( + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Withdrawal`} @@ -303,7 +406,8 @@ export function TransactionView({ {transaction.exchangeBaseUrl} </Header> - {!transaction.pending ? undefined : transaction.withdrawalDetails + {transaction.extendedStatus !== + ExtendedStatus.Pending ? undefined : transaction.withdrawalDetails .type === WithdrawalType.ManualTransfer ? ( <Fragment> <BankDetailsByPaytoType @@ -418,7 +522,13 @@ export function TransactionView({ const total = Amounts.sub(price.effective, refund.effective).amount; return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} total={total} @@ -491,7 +601,10 @@ export function TransactionView({ <div> <Button variant="contained" - onClick={() => onRefund(transaction.proposalId)} + onClick={safely( + () => onRefund(transaction.proposalId), + i18n.str`Could not refund`, + )} > <i18n.Translate>Accept</i18n.Translate> </Button> @@ -529,7 +642,13 @@ export function TransactionView({ const total = Amounts.parseOrThrow(transaction.amountRaw); const payto = parsePaytoUri(transaction.targetPaytoUri); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Deposit`} @@ -567,7 +686,13 @@ export function TransactionView({ ).amount; return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Refresh`} @@ -588,7 +713,13 @@ export function TransactionView({ const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Tip`} @@ -613,7 +744,13 @@ export function TransactionView({ if (transaction.type === TransactionType.Refund) { const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Refund`} @@ -666,10 +803,10 @@ export function TransactionView({ return ( <div> <QR text={text} /> - <Button onClick={copy}> + <Button onClick={copy as SafeHandler<void>}> <i18n.Translate>copy</i18n.Translate> </Button> - <Button onClick={toggle}> + <Button onClick={toggle as SafeHandler<void>}> <i18n.Translate>hide qr</i18n.Translate> </Button> </div> @@ -678,10 +815,10 @@ export function TransactionView({ return ( <div> <div>{text.substring(0, 64)}...</div> - <Button onClick={copy}> + <Button onClick={copy as SafeHandler<void>}> <i18n.Translate>copy</i18n.Translate> </Button> - <Button onClick={toggle}> + <Button onClick={toggle as SafeHandler<void>}> <i18n.Translate>show qr</i18n.Translate> </Button> </div> @@ -691,7 +828,13 @@ export function TransactionView({ if (transaction.type === TransactionType.PeerPullCredit) { const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Credit`} @@ -713,7 +856,8 @@ export function TransactionView({ text={transaction.exchangeBaseUrl as TranslatedString} kind="neutral" /> - {transaction.pending /** pending is not-pay */ && ( + {transaction.extendedStatus === + ExtendedStatus.Pending /** pending is not-pay */ && ( <Part title={i18n.str`URI`} text={<ShowQrWithCopy text={transaction.talerUri} />} @@ -738,7 +882,13 @@ export function TransactionView({ if (transaction.type === TransactionType.PeerPullDebit) { const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Debit`} @@ -777,7 +927,13 @@ export function TransactionView({ if (transaction.type === TransactionType.PeerPushDebit) { const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Debit`} @@ -824,7 +980,13 @@ export function TransactionView({ if (transaction.type === TransactionType.PeerPushCredit) { const total = Amounts.parseOrThrow(transaction.amountEffective); return ( - <TransactionTemplate> + <TransactionTemplate + transaction={transaction} + onDelete={onDelete} + onRetry={onRetry} + onSend={onSend} + onCancel={onCancel} + > <Header timestamp={transaction.timestamp} type={i18n.str`Credit`} |