summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-06-28 11:38:29 -0300
committerSebastian <sebasjm@gmail.com>2021-06-28 11:38:38 -0300
commitb43c476590508b5b3b10a5c2da34ac30f1fbdf57 (patch)
treeb37f53fd10b024e119beacf6f1a2bb774674750b /packages
parent42fe57632002e8f6dbf175b4e984b2fa1013bbe9 (diff)
downloadwallet-core-b43c476590508b5b3b10a5c2da34ac30f1fbdf57.tar.gz
wallet-core-b43c476590508b5b3b10a5c2da34ac30f1fbdf57.tar.bz2
wallet-core-b43c476590508b5b3b10a5c2da34ac30f1fbdf57.zip
handler transaction error on details and added retry button
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx54
-rw-r--r--packages/taler-wallet-webextension/src/popup/Transaction.tsx37
-rw-r--r--packages/taler-wallet-webextension/src/popupEntryPoint.tsx5
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts14
-rw-r--r--packages/taler-wallet-webextension/static/style/popup.css15
5 files changed, 107 insertions, 18 deletions
diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
index 48f945783..00108aac6 100644
--- a/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Transaction.stories.tsx
@@ -32,6 +32,11 @@ import { TransactionView as TestedComponent } from './Transaction';
export default {
title: 'popup/transaction/details',
component: TestedComponent,
+ argTypes: {
+ onRetry: { action: 'onRetry' },
+ onDelete: { action: 'onDelete' },
+ onBack: { action: 'onBack' },
+ }
};
const commonTransaction = {
@@ -105,6 +110,13 @@ const exampleData = {
} as TransactionRefund,
}
+const transactionError = {
+ code: 2000,
+ details: "details",
+ hint: "this is a hint for the error",
+ message: 'message'
+}
+
function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) {
const r = (args: any) => <Component {...args} />
r.args = props
@@ -117,6 +129,13 @@ export const Withdraw = createExample(TestedComponent, {
transaction: exampleData.withdraw
});
+export const WithdrawError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.withdraw,
+ error: transactionError,
+ },
+});
+
export const WithdrawPending = createExample(TestedComponent, {
transaction: { ...exampleData.withdraw, pending: true },
});
@@ -126,6 +145,13 @@ export const Payment = createExample(TestedComponent, {
transaction: exampleData.payment
});
+export const PaymentError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.payment,
+ error: transactionError
+ },
+});
+
export const PaymentWithoutFee = createExample(TestedComponent, {
transaction: {
...exampleData.payment,
@@ -191,6 +217,13 @@ export const Deposit = createExample(TestedComponent, {
transaction: exampleData.deposit
});
+export const DepositError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.deposit,
+ error: transactionError
+ },
+});
+
export const DepositPending = createExample(TestedComponent, {
transaction: { ...exampleData.deposit, pending: true }
});
@@ -199,10 +232,24 @@ export const Refresh = createExample(TestedComponent, {
transaction: exampleData.refresh
});
+export const RefreshError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.refresh,
+ error: transactionError
+ },
+});
+
export const Tip = createExample(TestedComponent, {
transaction: exampleData.tip
});
+export const TipError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.tip,
+ error: transactionError
+ },
+});
+
export const TipPending = createExample(TestedComponent, {
transaction: { ...exampleData.tip, pending: true }
});
@@ -211,6 +258,13 @@ export const Refund = createExample(TestedComponent, {
transaction: exampleData.refund
});
+export const RefundError = createExample(TestedComponent, {
+ transaction: {
+ ...exampleData.refund,
+ error: transactionError
+ },
+});
+
export const RefundPending = createExample(TestedComponent, {
transaction: { ...exampleData.refund, pending: true }
});
diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.tsx
index 12245e5be..7a66d7a0e 100644
--- a/packages/taler-wallet-webextension/src/popup/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Transaction.tsx
@@ -44,16 +44,18 @@ export function TransactionPage({ tid }: { tid: string; }): JSX.Element {
return <TransactionView
transaction={transaction}
onDelete={() => wxApi.deleteTransaction(tid).then(_ => history.go(-1))}
+ onRetry={() => wxApi.retryTransaction(tid).then(_ => history.go(-1))}
onBack={() => { history.go(-1); }} />;
}
export interface WalletTransactionProps {
transaction?: Transaction,
onDelete: () => void,
+ onRetry: () => void,
onBack: () => void,
}
-export function TransactionView({ transaction, onDelete, onBack }: WalletTransactionProps) {
+export function TransactionView({ transaction, onDelete, onRetry, onBack }: WalletTransactionProps) {
if (!transaction) {
return <div><i18n.Translate>Loading ...</i18n.Translate></div>;
}
@@ -62,17 +64,28 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
return <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}>
<button onClick={onBack}><i18n.Translate>back</i18n.Translate></button>
<div style={{ width: '100%', flexDirection: 'row', justifyContent: 'flex-end', display: 'flex' }}>
- <button class="pure-button button-destructive" onClick={onDelete}><i18n.Translate>delete</i18n.Translate></button>
+ {transaction?.error ? <button class="pure-button button-secondary" style={{marginRight: 5}} onClick={onRetry}><i18n.Translate>retry</i18n.Translate></button> : null }
+ <button class="pure-button button-destructive" onClick={onDelete}><i18n.Translate>delete</i18n.Translate></button>
</div>
</footer>
}
- function Pending() {
+ function Status() {
+ if (transaction?.error) {
+ return <span style={{ fontWeight: 'normal', fontSize: 16, color: 'red' }}>(failed)</span>
+ }
if (!transaction?.pending) return null
return <span style={{ fontWeight: 'normal', fontSize: 16, color: 'gray' }}>(pending...)</span>
}
+ function Error() {
+ if (!transaction?.error) return null
+ return <div class="errorbox" >
+ <p>{transaction.error.hint}</p>
+ </div>
+ }
+
const Fee = ({ value }: { value: AmountJson }) => Amounts.isNonZero(value) ?
<span style="font-size: 16px;font-weight: normal;color: gray;">(fee {Amounts.stringify(value)})</span> : null
@@ -88,7 +101,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
From <b>{transaction.exchangeBaseUrl}</b>
</span>
- <h3>Withdraw <Pending /></h3>
+ <Error />
+ <h3>Withdraw <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
@@ -113,7 +127,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
To <b>{transaction.info.merchant.name}</b>
</span>
- <h3>Payment <Pending /></h3>
+ <Error />
+ <h3>Payment <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
<span style="font-size:small; color:gray">#{transaction.info.orderId}</span>
<p>
@@ -151,7 +166,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
To <b>{transaction.targetPaytoUri}</b>
</span>
- <h3>Deposit <Pending /></h3>
+ <Error />
+ <h3>Deposit <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
@@ -171,7 +187,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
From <b>{transaction.exchangeBaseUrl}</b>
</span>
- <h3>Refresh <Pending /></h3>
+ <Error />
+ <h3>Refresh <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
@@ -191,7 +208,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
From <b>{transaction.merchantBaseUrl}</b>
</span>
- <h3>Tip <Pending /></h3>
+ <Error />
+ <h3>Tip <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
</section>
<Footer />
@@ -211,7 +229,8 @@ export function TransactionView({ transaction, onDelete, onBack }: WalletTransac
<span style="float: right; font-size:small; color:gray">
From <b>{transaction.info.merchant.name}</b>
</span>
- <h3>Refund <Pending /></h3>
+ <Error />
+ <h3>Refund <Status /></h3>
<h1>{transaction.amountEffective} <Fee value={fee} /></h1>
<span style="font-size:small; color:gray">#{transaction.info.orderId}</span>
<p>
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
index 1c569519c..84501c2d2 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
@@ -25,7 +25,8 @@ import { setupI18n } from "@gnu-taler/taler-util";
import { strings } from "./i18n/strings";
import { useEffect } from "preact/hooks";
import {
- Pages, WalletNavBar} from "./popup/popup";
+ Pages, WalletNavBar
+} from "./popup/popup";
import { HistoryPage } from "./popup/History";
import { DebugPage } from "./popup/Debug";
import { SettingsPage } from "./popup/Settings";
@@ -67,7 +68,7 @@ function TalerActionFound({ url, onDismiss }: Props) {
<h1>Taler Action </h1>
<p>This page has a Taler action.</p>
<p>
- <button onClick={() => { window.open(url, "_blank"); }}>
+ <button onClick={() => { chrome.tabs.create({ "url": url }); }}>
Open
</button>
</p>
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index 3340f27ce..095fabe85 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -36,6 +36,7 @@ import {
PrepareTipResult,
AcceptTipRequest,
DeleteTransactionRequest,
+ RetryTransactionRequest,
} from "@gnu-taler/taler-util";
import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
@@ -132,7 +133,18 @@ export function getTransactions(): Promise<TransactionsResponse> {
}
/**
- * Get balances for all currencies/exchanges.
+ * Retry a transaction
+ * @param transactionId
+ * @returns
+ */
+ export function retryTransaction(transactionId: string): Promise<void> {
+ return callBackend("retryTransaction", {
+ transactionId
+ } as RetryTransactionRequest);
+}
+
+/**
+ * Permanently delete a transaction from the transaction list
*/
export function deleteTransaction(transactionId: string): Promise<void> {
return callBackend("deleteTransaction", {
diff --git a/packages/taler-wallet-webextension/static/style/popup.css b/packages/taler-wallet-webextension/static/style/popup.css
index d0fd5d281..cd885556a 100644
--- a/packages/taler-wallet-webextension/static/style/popup.css
+++ b/packages/taler-wallet-webextension/static/style/popup.css
@@ -234,12 +234,15 @@ button.accept:disabled {
}
.errorbox {
- border: 1px solid;
- display: inline-block;
- margin: 1em;
- padding: 1em;
- font-weight: bold;
- background: #ff8a8a;
+ border: 2px solid #f5c6cb;
+ border-radius: .25em;
+ display: block;
+ /* margin: 0.5em; */
+ padding-left: 1em;
+ padding-right: 1em;
+ width: '100%';
+ color: #721c24;
+ background: #f8d7da;
}
.okaybox {