tx state ui
This commit is contained in:
parent
699a7b453b
commit
4f726b73e6
@ -39,7 +39,7 @@ import {
|
|||||||
} from "./styled/index.js";
|
} from "./styled/index.js";
|
||||||
import { Time } from "./Time.js";
|
import { Time } from "./Time.js";
|
||||||
|
|
||||||
export function TransactionItem(props: { tx: Transaction }): VNode {
|
export function HistoryItem(props: { tx: Transaction }): VNode {
|
||||||
const tx = props.tx;
|
const tx = props.tx;
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
/**
|
/**
|
||||||
@ -48,14 +48,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
switch (tx.type) {
|
switch (tx.type) {
|
||||||
case TransactionType.Withdrawal:
|
case TransactionType.Withdrawal:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={new URL(tx.exchangeBaseUrl).hostname}
|
title={new URL(tx.exchangeBaseUrl).hostname}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"W"}
|
iconPath={"W"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? tx.withdrawalDetails.type ===
|
? tx.withdrawalDetails.type ===
|
||||||
WithdrawalType.TalerBankIntegrationApi
|
WithdrawalType.TalerBankIntegrationApi
|
||||||
@ -71,14 +72,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.InternalWithdrawal:
|
case TransactionType.InternalWithdrawal:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={new URL(tx.exchangeBaseUrl).hostname}
|
title={new URL(tx.exchangeBaseUrl).hostname}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"I"}
|
iconPath={"I"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? tx.withdrawalDetails.type ===
|
? tx.withdrawalDetails.type ===
|
||||||
WithdrawalType.TalerBankIntegrationApi
|
WithdrawalType.TalerBankIntegrationApi
|
||||||
@ -94,7 +96,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.Payment:
|
case TransactionType.Payment:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"debit"}
|
debitCreditIndicator={"debit"}
|
||||||
@ -102,7 +104,8 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
subtitle={tx.info.summary}
|
subtitle={tx.info.summary}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"P"}
|
iconPath={"P"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Payment in progress`
|
? i18n.str`Payment in progress`
|
||||||
: undefined
|
: undefined
|
||||||
@ -111,7 +114,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.Refund:
|
case TransactionType.Refund:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
@ -123,7 +126,8 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
} //FIXME: DD37 wallet-core is not returning this value
|
} //FIXME: DD37 wallet-core is not returning this value
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"R"}
|
iconPath={"R"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Executing refund...`
|
? i18n.str`Executing refund...`
|
||||||
: undefined
|
: undefined
|
||||||
@ -132,14 +136,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.Tip:
|
case TransactionType.Tip:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={new URL(tx.merchantBaseUrl).hostname}
|
title={new URL(tx.merchantBaseUrl).hostname}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"T"}
|
iconPath={"T"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Grabbing the tipping...`
|
? i18n.str`Grabbing the tipping...`
|
||||||
: undefined
|
: undefined
|
||||||
@ -148,14 +153,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.Refresh:
|
case TransactionType.Refresh:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={"Refresh"}
|
title={"Refresh"}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"R"}
|
iconPath={"R"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Refreshing coins...`
|
? i18n.str`Refreshing coins...`
|
||||||
: undefined
|
: undefined
|
||||||
@ -164,14 +170,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.Deposit:
|
case TransactionType.Deposit:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"debit"}
|
debitCreditIndicator={"debit"}
|
||||||
title={tx.targetPaytoUri}
|
title={tx.targetPaytoUri}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"D"}
|
iconPath={"D"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Deposit in progress`
|
? i18n.str`Deposit in progress`
|
||||||
: undefined
|
: undefined
|
||||||
@ -180,14 +187,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.PeerPullCredit:
|
case TransactionType.PeerPullCredit:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={tx.info.summary || "Invoice"}
|
title={tx.info.summary || "Invoice"}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"I"}
|
iconPath={"I"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Waiting to be paid`
|
? i18n.str`Waiting to be paid`
|
||||||
: undefined
|
: undefined
|
||||||
@ -196,14 +204,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.PeerPullDebit:
|
case TransactionType.PeerPullDebit:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"debit"}
|
debitCreditIndicator={"debit"}
|
||||||
title={tx.info.summary || "Invoice"}
|
title={tx.info.summary || "Invoice"}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"I"}
|
iconPath={"I"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Payment in progress`
|
? i18n.str`Payment in progress`
|
||||||
: undefined
|
: undefined
|
||||||
@ -212,14 +221,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.PeerPushCredit:
|
case TransactionType.PeerPushCredit:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"credit"}
|
debitCreditIndicator={"credit"}
|
||||||
title={tx.info.summary || "Transfer"}
|
title={tx.info.summary || "Transfer"}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"T"}
|
iconPath={"T"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Receiving the transfer`
|
? i18n.str`Receiving the transfer`
|
||||||
: undefined
|
: undefined
|
||||||
@ -228,14 +238,15 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
);
|
);
|
||||||
case TransactionType.PeerPushDebit:
|
case TransactionType.PeerPushDebit:
|
||||||
return (
|
return (
|
||||||
<TransactionLayout
|
<Layout
|
||||||
id={tx.transactionId}
|
id={tx.transactionId}
|
||||||
amount={tx.amountEffective}
|
amount={tx.amountEffective}
|
||||||
debitCreditIndicator={"debit"}
|
debitCreditIndicator={"debit"}
|
||||||
title={tx.info.summary || "Transfer"}
|
title={tx.info.summary || "Transfer"}
|
||||||
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
timestamp={AbsoluteTime.fromPreciseTimestamp(tx.timestamp)}
|
||||||
iconPath={"T"}
|
iconPath={"T"}
|
||||||
pending={
|
currentState={tx.txState.major}
|
||||||
|
description={
|
||||||
tx.txState.major === TransactionMajorState.Pending
|
tx.txState.major === TransactionMajorState.Pending
|
||||||
? i18n.str`Waiting to be received`
|
? i18n.str`Waiting to be received`
|
||||||
: undefined
|
: undefined
|
||||||
@ -248,13 +259,22 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function TransactionLayout(props: TransactionLayoutProps): VNode {
|
function Layout(props: LayoutProps): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
return (
|
return (
|
||||||
<HistoryRow
|
<HistoryRow
|
||||||
href={Pages.balanceTransaction({ tid: props.id })}
|
href={Pages.balanceTransaction({ tid: props.id })}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: props.pending ? "lightcyan" : "inherit",
|
backgroundColor:
|
||||||
|
props.currentState === TransactionMajorState.Pending ||
|
||||||
|
props.currentState === TransactionMajorState.Dialog
|
||||||
|
? "lightcyan"
|
||||||
|
: props.currentState === TransactionMajorState.Failed
|
||||||
|
? "#ff000040"
|
||||||
|
: props.currentState === TransactionMajorState.Aborted ||
|
||||||
|
props.currentState === TransactionMajorState.Aborting
|
||||||
|
? "#00000010"
|
||||||
|
: "inherit",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -276,9 +296,9 @@ function TransactionLayout(props: TransactionLayoutProps): VNode {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</LargeText>
|
</LargeText>
|
||||||
{props.pending && (
|
{props.description && (
|
||||||
<LightText style={{ marginTop: 5, marginBottom: 5 }}>
|
<LightText style={{ marginTop: 5, marginBottom: 5 }}>
|
||||||
<i18n.Translate>{props.pending}</i18n.Translate>
|
<i18n.Translate>{props.description}</i18n.Translate>
|
||||||
</LightText>
|
</LightText>
|
||||||
)}
|
)}
|
||||||
<SmallLightText style={{ marginTop: 5 }}>
|
<SmallLightText style={{ marginTop: 5 }}>
|
||||||
@ -286,7 +306,7 @@ function TransactionLayout(props: TransactionLayoutProps): VNode {
|
|||||||
</SmallLightText>
|
</SmallLightText>
|
||||||
</Column>
|
</Column>
|
||||||
<TransactionAmount
|
<TransactionAmount
|
||||||
pending={props.pending !== undefined}
|
currentState={props.currentState}
|
||||||
amount={Amounts.parseOrThrow(props.amount)}
|
amount={Amounts.parseOrThrow(props.amount)}
|
||||||
debitCreditIndicator={props.debitCreditIndicator}
|
debitCreditIndicator={props.debitCreditIndicator}
|
||||||
/>
|
/>
|
||||||
@ -294,7 +314,7 @@ function TransactionLayout(props: TransactionLayoutProps): VNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TransactionLayoutProps {
|
interface LayoutProps {
|
||||||
debitCreditIndicator: "debit" | "credit" | "unknown";
|
debitCreditIndicator: "debit" | "credit" | "unknown";
|
||||||
amount: AmountString | "unknown";
|
amount: AmountString | "unknown";
|
||||||
timestamp: AbsoluteTime;
|
timestamp: AbsoluteTime;
|
||||||
@ -302,13 +322,14 @@ interface TransactionLayoutProps {
|
|||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
id: string;
|
id: string;
|
||||||
iconPath: string;
|
iconPath: string;
|
||||||
pending?: string;
|
currentState: TransactionMajorState;
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TransactionAmountProps {
|
interface TransactionAmountProps {
|
||||||
debitCreditIndicator: "debit" | "credit" | "unknown";
|
debitCreditIndicator: "debit" | "credit" | "unknown";
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
pending: boolean;
|
currentState: TransactionMajorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TransactionAmount(props: TransactionAmountProps): VNode {
|
function TransactionAmount(props: TransactionAmountProps): VNode {
|
||||||
@ -328,24 +349,43 @@ function TransactionAmount(props: TransactionAmountProps): VNode {
|
|||||||
<Column
|
<Column
|
||||||
style={{
|
style={{
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
color: props.pending
|
color:
|
||||||
? "gray"
|
props.currentState !== TransactionMajorState.Done
|
||||||
: sign === "+"
|
? "gray"
|
||||||
? "darkgreen"
|
: sign === "+"
|
||||||
: sign === "-"
|
? "darkgreen"
|
||||||
? "darkred"
|
: sign === "-"
|
||||||
: undefined,
|
? "darkred"
|
||||||
|
: undefined,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ExtraLargeText>
|
<ExtraLargeText>
|
||||||
{sign}
|
{sign}
|
||||||
{Amounts.stringifyValue(props.amount, 2)}
|
{Amounts.stringifyValue(props.amount, 2)}
|
||||||
</ExtraLargeText>
|
</ExtraLargeText>
|
||||||
{props.pending && (
|
{props.currentState === TransactionMajorState.Aborted ? (
|
||||||
<div>
|
<div
|
||||||
<i18n.Translate>PENDING</i18n.Translate>
|
style={{
|
||||||
|
color: "black",
|
||||||
|
border: "1px black solid",
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i18n.Translate>ABORTED</i18n.Translate>
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : props.currentState === TransactionMajorState.Failed ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
color: "red",
|
||||||
|
border: "1px darkred solid",
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i18n.Translate>FAILED</i18n.Translate>
|
||||||
|
</div>
|
||||||
|
) : undefined}
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="manifest" href="manifest.json" />
|
<link rel="manifest" href="./manifest.json" />
|
||||||
<style>
|
<style>
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -54,8 +54,9 @@ justify-content: center;
|
|||||||
width="1000"
|
width="1000"
|
||||||
height="100%"
|
height="100%"
|
||||||
>
|
>
|
||||||
<input id="page-url" type="text" />
|
</iframe>
|
||||||
<button onclick="openPage()">open</button>
|
<!-- <input id="page-url" type="text" />
|
||||||
|
<button onclick="openPage()">open</button> -->
|
||||||
<!-- <a
|
<!-- <a
|
||||||
href='javascript:void(window.frames["other"].location = "http://bank.taler:5882")'
|
href='javascript:void(window.frames["other"].location = "http://bank.taler:5882")'
|
||||||
>open local bank</a
|
>open local bank</a
|
||||||
@ -77,17 +78,13 @@ justify-content: center;
|
|||||||
src="about:blank"
|
src="about:blank"
|
||||||
width="500"
|
width="500"
|
||||||
height="325"
|
height="325"
|
||||||
>
|
>
|
||||||
</iframe>
|
</iframe>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
|
||||||
</iframe>
|
|
||||||
<!-- <hr />
|
<!-- <hr />
|
||||||
<iframe src="tests.html" name="wallet" width="800" height="100%"> </iframe> -->
|
<iframe src="tests.html" name="wallet" width="800" height="100%"> </iframe> -->
|
||||||
<!-- <hr />
|
<!-- <hr />
|
||||||
<iframe src="stories.html" name="wallet" width="800" height="100%"> -->
|
<iframe src="stories.html" name="wallet" width="800" height="100%"> -->
|
||||||
</iframe>
|
|
||||||
<hr />
|
|
||||||
<script type="module" src="background.dev.js"></script>
|
<script type="module" src="background.dev.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,18 +3,17 @@
|
|||||||
"description": "Privacy preserving and transparent payments",
|
"description": "Privacy preserving and transparent payments",
|
||||||
"author": "GNU Taler Developers",
|
"author": "GNU Taler Developers",
|
||||||
"version": "0.9.3.13",
|
"version": "0.9.3.13",
|
||||||
|
"id": "gnu-taler-wallet-web-spa-development",
|
||||||
"version_name": "0.9.3-dev.13",
|
"version_name": "0.9.3-dev.13",
|
||||||
"icons": {
|
"icons": [{
|
||||||
"16": "static/img/taler-logo-16.png",
|
"src": "static/img/taler-logo-48.png",
|
||||||
"19": "static/img/taler-logo-19.png",
|
"sizes": "48x48"
|
||||||
"32": "static/img/taler-logo-32.png",
|
},{
|
||||||
"38": "static/img/taler-logo-38.png",
|
"src": "static/img/taler-logo-128.png",
|
||||||
"48": "static/img/taler-logo-48.png",
|
"sizes": "128x128"
|
||||||
"64": "static/img/taler-logo-64.png",
|
}],
|
||||||
"128": "static/img/taler-logo-128.png",
|
"display": "minimal-ui",
|
||||||
"256": "static/img/taler-logo-256.png",
|
"start_url": "http://localhost:8080/app/index.html",
|
||||||
"512": "static/img/taler-logo-512.png"
|
|
||||||
},
|
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"minimum_chrome_version": "88",
|
"minimum_chrome_version": "88",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
@ -75,8 +74,5 @@
|
|||||||
},
|
},
|
||||||
"default_title": "GNU Taler Wallet",
|
"default_title": "GNU Taler Wallet",
|
||||||
"default_popup": "static/popup.html"
|
"default_popup": "static/popup.html"
|
||||||
},
|
|
||||||
"background": {
|
|
||||||
"service_worker": "service_worker.js"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
@ -43,7 +43,7 @@ import { HistoryView as TestedComponent } from "./History.js";
|
|||||||
import * as tests from "@gnu-taler/web-util/testing";
|
import * as tests from "@gnu-taler/web-util/testing";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "balance",
|
title: "history",
|
||||||
component: TestedComponent,
|
component: TestedComponent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,6 +291,100 @@ export const SomeTransactions = tests.createExample(TestedComponent, {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const SomeTransactionsInDifferentStates = tests.createExample(
|
||||||
|
TestedComponent,
|
||||||
|
{
|
||||||
|
transactions: [
|
||||||
|
exampleData.withdraw,
|
||||||
|
{
|
||||||
|
...exampleData.withdraw,
|
||||||
|
exchangeBaseUrl: "https://aborted/withdrawal",
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Aborted,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.withdraw,
|
||||||
|
exchangeBaseUrl: "https://pending/withdrawal",
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.withdraw,
|
||||||
|
exchangeBaseUrl: "https://failed/withdrawal",
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Failed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.payment,
|
||||||
|
info: {
|
||||||
|
...exampleData.payment.info,
|
||||||
|
summary: "normal payment",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.payment,
|
||||||
|
info: {
|
||||||
|
...exampleData.payment.info,
|
||||||
|
summary: "aborting in progress",
|
||||||
|
},
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Aborting,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.payment,
|
||||||
|
info: {
|
||||||
|
...exampleData.payment.info,
|
||||||
|
summary: "aborted payment",
|
||||||
|
},
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Aborted,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.payment,
|
||||||
|
info: {
|
||||||
|
...exampleData.payment.info,
|
||||||
|
summary: "pending payment",
|
||||||
|
},
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...exampleData.payment,
|
||||||
|
info: {
|
||||||
|
...exampleData.payment.info,
|
||||||
|
summary: "failed payment",
|
||||||
|
},
|
||||||
|
txState: {
|
||||||
|
major: TransactionMajorState.Failed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
exampleData.refund,
|
||||||
|
exampleData.tip,
|
||||||
|
exampleData.deposit,
|
||||||
|
],
|
||||||
|
balances: [
|
||||||
|
{
|
||||||
|
available: "USD:10",
|
||||||
|
pendingIncoming: "USD:0",
|
||||||
|
pendingOutgoing: "USD:0",
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
requiresUserInput: false,
|
||||||
|
scopeInfo: {
|
||||||
|
currency: "Ásd",
|
||||||
|
type: ScopeType.Auditor,
|
||||||
|
url: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export const SomeTransactionsWithTwoCurrencies = tests.createExample(
|
export const SomeTransactionsWithTwoCurrencies = tests.createExample(
|
||||||
TestedComponent,
|
TestedComponent,
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@ import {
|
|||||||
NiceSelect,
|
NiceSelect,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { Time } from "../components/Time.js";
|
import { Time } from "../components/Time.js";
|
||||||
import { TransactionItem } from "../components/TransactionItem.js";
|
import { HistoryItem } from "../components/HistoryItem.js";
|
||||||
import { alertFromError, useAlertContext } from "../context/alert.js";
|
import { alertFromError, useAlertContext } from "../context/alert.js";
|
||||||
import { useBackendContext } from "../context/backend.js";
|
import { useBackendContext } from "../context/backend.js";
|
||||||
import { useTranslationContext } from "@gnu-taler/web-util/browser";
|
import { useTranslationContext } from "@gnu-taler/web-util/browser";
|
||||||
@ -269,7 +269,7 @@ export function HistoryView({
|
|||||||
/>
|
/>
|
||||||
</DateSeparator>
|
</DateSeparator>
|
||||||
{byDate[d].map((tx, i) => (
|
{byDate[d].map((tx, i) => (
|
||||||
<TransactionItem key={i} tx={tx} />
|
<HistoryItem key={i} tx={tx} />
|
||||||
))}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -52,6 +52,7 @@ import { QR } from "../components/QR.js";
|
|||||||
import { ShowFullContractTermPopup } from "../components/ShowFullContractTermPopup.js";
|
import { ShowFullContractTermPopup } from "../components/ShowFullContractTermPopup.js";
|
||||||
import {
|
import {
|
||||||
CenteredDialog,
|
CenteredDialog,
|
||||||
|
ErrorBox,
|
||||||
InfoBox,
|
InfoBox,
|
||||||
ListOfProducts,
|
ListOfProducts,
|
||||||
Overlay,
|
Overlay,
|
||||||
@ -128,7 +129,7 @@ export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
|
|||||||
goToWalletHistory(currency);
|
goToWalletHistory(currency);
|
||||||
}}
|
}}
|
||||||
onResume={async () => {
|
onResume={async () => {
|
||||||
await api.wallet.call(WalletApiOperation.SuspendTransaction, {
|
await api.wallet.call(WalletApiOperation.ResumeTransaction, {
|
||||||
transactionId,
|
transactionId,
|
||||||
});
|
});
|
||||||
goToWalletHistory(currency);
|
goToWalletHistory(currency);
|
||||||
@ -239,6 +240,7 @@ function TransactionTemplate({
|
|||||||
transaction.txState.major === TransactionMajorState.Aborting;
|
transaction.txState.major === TransactionMajorState.Aborting;
|
||||||
|
|
||||||
const showRetry =
|
const showRetry =
|
||||||
|
!isFinalState &&
|
||||||
transaction.txState.major !== TransactionMajorState.Pending &&
|
transaction.txState.major !== TransactionMajorState.Pending &&
|
||||||
transaction.txState.major !== TransactionMajorState.Aborting;
|
transaction.txState.major !== TransactionMajorState.Aborting;
|
||||||
|
|
||||||
@ -289,6 +291,16 @@ function TransactionTemplate({
|
|||||||
<i18n.Translate>This transaction is not completed</i18n.Translate>
|
<i18n.Translate>This transaction is not completed</i18n.Translate>
|
||||||
</WarningBox>
|
</WarningBox>
|
||||||
)}
|
)}
|
||||||
|
{transaction.txState.major === TransactionMajorState.Aborted && (
|
||||||
|
<InfoBox>
|
||||||
|
<i18n.Translate>This transaction was aborted</i18n.Translate>
|
||||||
|
</InfoBox>
|
||||||
|
)}
|
||||||
|
{transaction.txState.major === TransactionMajorState.Failed && (
|
||||||
|
<ErrorBox>
|
||||||
|
<i18n.Translate>This transaction failed</i18n.Translate>
|
||||||
|
</ErrorBox>
|
||||||
|
)}
|
||||||
{confirmBeforeForget ? (
|
{confirmBeforeForget ? (
|
||||||
<Overlay>
|
<Overlay>
|
||||||
<CenteredDialog>
|
<CenteredDialog>
|
||||||
|
Loading…
Reference in New Issue
Block a user