format amount so it is align to fractional digitls
This commit is contained in:
parent
eb8bcc9532
commit
ff49e3477e
@ -444,4 +444,28 @@ export class Amounts {
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of fractional digits needed to fully represent the amount
|
||||||
|
* @param a amount
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static maxFractionalDigits(a: AmountJson): number {
|
||||||
|
if (a.fraction === 0) return 0;
|
||||||
|
if (a.fraction < 0) {
|
||||||
|
console.error("amount fraction can not be negative", a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let i = 0;
|
||||||
|
let check = true;
|
||||||
|
let rest = a.fraction;
|
||||||
|
while (rest > 0 && check) {
|
||||||
|
check = rest % 10 === 0;
|
||||||
|
rest = rest / 10;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return amountFractionalLength - i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2022 Taler Systems S.A.
|
||||||
|
|
||||||
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Javier Marchano (sebasjm)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { styled } from "@linaria/react";
|
||||||
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
import { Amount } from "./Amount.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "components/amount",
|
||||||
|
component: Amount,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Table = styled.table`
|
||||||
|
td {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
function ProductTable(
|
||||||
|
prods: string[],
|
||||||
|
AmountRender: (p: { value: string; index: number }) => VNode = Amount,
|
||||||
|
): VNode {
|
||||||
|
return (
|
||||||
|
<Table>
|
||||||
|
<tr>
|
||||||
|
<td>product</td>
|
||||||
|
<td>price</td>
|
||||||
|
</tr>
|
||||||
|
{prods.map((value, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>p{i}</td>
|
||||||
|
<td>
|
||||||
|
<AmountRender value={value} index={i} />
|
||||||
|
{/* <Amount value={value} fracSize={fracSize} /> */}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WithoutFixedSizeDefault = (): VNode =>
|
||||||
|
ProductTable(["ARS:19", "ARS:0.1", "ARS:10.02"]);
|
||||||
|
|
||||||
|
export const WithFixedSizeZero = (): VNode =>
|
||||||
|
ProductTable(["ARS:19", "ARS:0.1", "ARS:10.02"], ({ value }) => {
|
||||||
|
return <Amount value={value} maxFracSize={0} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const WithFixedSizeFour = (): VNode =>
|
||||||
|
ProductTable(
|
||||||
|
["ARS:19", "ARS:0.1", "ARS:10.02", "ARS:10.0123", "ARS:10.0123123"],
|
||||||
|
({ value }) => {
|
||||||
|
return <Amount value={value} maxFracSize={4} />;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const WithFixedSizeFourNegative = (): VNode =>
|
||||||
|
ProductTable(
|
||||||
|
["ARS:19", "ARS:0.1", "ARS:10.02", "ARS:10.0123", "ARS:10.0123123"],
|
||||||
|
({ value, index }) => {
|
||||||
|
return (
|
||||||
|
<Amount value={value} maxFracSize={4} negative={index % 2 === 0} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const WithFixedSizeFourOverflow = (): VNode =>
|
||||||
|
ProductTable(
|
||||||
|
["ARS:19", "ARS:0.1", "ARS:10123123.02", "ARS:10.0123", "ARS:10.0123123"],
|
||||||
|
({ value, index }) => {
|
||||||
|
return (
|
||||||
|
<Amount value={value} maxFracSize={4} negative={index % 2 === 0} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const WithFixedSizeFourAccounting = (): VNode =>
|
||||||
|
ProductTable(
|
||||||
|
["ARS:19", "ARS:0.1", "ARS:10123123.02", "ARS:10.0123", "ARS:10.0123123"],
|
||||||
|
({ value, index }) => {
|
||||||
|
return (
|
||||||
|
<Amount
|
||||||
|
value={value}
|
||||||
|
signType="accounting"
|
||||||
|
maxFracSize={4}
|
||||||
|
negative={index % 2 === 0}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
@ -13,15 +13,95 @@
|
|||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
import { AmountJson, Amounts, AmountString } from "@gnu-taler/taler-util";
|
import {
|
||||||
import { h, VNode, Fragment } from "preact";
|
amountFractionalBase,
|
||||||
|
amountFractionalLength,
|
||||||
|
AmountJson,
|
||||||
|
Amounts,
|
||||||
|
AmountString,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
|
||||||
export function Amount({ value }: { value: AmountJson | AmountString }): VNode {
|
export function Amount({
|
||||||
|
value,
|
||||||
|
maxFracSize,
|
||||||
|
negative,
|
||||||
|
hideCurrency,
|
||||||
|
signType = "standard",
|
||||||
|
signDisplay = "auto",
|
||||||
|
}: {
|
||||||
|
negative?: boolean;
|
||||||
|
value: AmountJson | AmountString;
|
||||||
|
maxFracSize?: number;
|
||||||
|
hideCurrency?: boolean;
|
||||||
|
signType?: "accounting" | "standard";
|
||||||
|
signDisplay?: "auto" | "always" | "never" | "exceptZero";
|
||||||
|
}): VNode {
|
||||||
const aj = Amounts.jsonifyAmount(value);
|
const aj = Amounts.jsonifyAmount(value);
|
||||||
const amount = Amounts.stringifyValue(aj, 2);
|
const minFractional =
|
||||||
|
maxFracSize !== undefined && maxFracSize < 2 ? maxFracSize : 2;
|
||||||
|
const af = aj.fraction % amountFractionalBase;
|
||||||
|
let s = "";
|
||||||
|
if ((af && maxFracSize) || minFractional > 0) {
|
||||||
|
s += ".";
|
||||||
|
let n = af;
|
||||||
|
for (
|
||||||
|
let i = 0;
|
||||||
|
(maxFracSize === undefined || i < maxFracSize) &&
|
||||||
|
i < amountFractionalLength;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
if (!n && i >= minFractional) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = s + Math.floor((n / amountFractionalBase) * 10).toString();
|
||||||
|
n = (n * 10) % amountFractionalBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const fontSize = 18;
|
||||||
|
const letterSpacing = 0;
|
||||||
|
const mult = 0.7;
|
||||||
return (
|
return (
|
||||||
|
<span style={{ textAlign: "right", whiteSpace: "nowrap" }}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
fontSize,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{negative ? (signType === "accounting" ? "(" : "-") : ""}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
textAlign: "right",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
fontSize,
|
||||||
|
letterSpacing,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{aj.value}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
width: !maxFracSize ? undefined : `${(maxFracSize + 1) * mult}em`,
|
||||||
|
textAlign: "left",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
fontSize,
|
||||||
|
letterSpacing,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{s}
|
||||||
|
{negative && signType === "accounting" ? ")" : ""}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
{hideCurrency ? undefined : (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{amount} {aj.currency}
|
|
||||||
|
<span>{aj.currency}</span>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -77,12 +77,16 @@ export function BankDetailsByPaytoType({
|
|||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{payto.targetPath}</td>
|
<td>{payto.targetPath}</td>
|
||||||
<td>{Amounts.stringifyValue(amount)} BTC</td>
|
<td>
|
||||||
|
<Amount value={amount} hideCurrency /> BTC
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{payto.segwitAddrs.map((addr, i) => (
|
{payto.segwitAddrs.map((addr, i) => (
|
||||||
<tr key={i}>
|
<tr key={i}>
|
||||||
<td>{addr}</td>
|
<td>{addr}</td>
|
||||||
<td>{Amounts.stringifyValue(min)} BTC</td>
|
<td>
|
||||||
|
<Amount value={min} hideCurrency /> BTC
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</table>
|
</table>
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
* @author Sebastian Javier Marchano (sebasjm)
|
* @author Sebastian Javier Marchano (sebasjm)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as a1 from "./Banner.stories.js";
|
import * as a1 from "./Banner.stories.js";
|
||||||
import * as a2 from "./PendingTransactions.stories.js";
|
import * as a2 from "./PendingTransactions.stories.js";
|
||||||
|
import * as a3 from "./Amount.stories.js";
|
||||||
|
|
||||||
export default [a1, a2];
|
export default [a1, a2, a3];
|
||||||
|
@ -78,7 +78,11 @@ export const WithSomeBankAccounts = createExample(TestedComponent, {
|
|||||||
value: "10:USD",
|
value: "10:USD",
|
||||||
},
|
},
|
||||||
cancelHandler: {},
|
cancelHandler: {},
|
||||||
depositHandler: {},
|
depositHandler: {
|
||||||
|
onClick: async () => {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
},
|
||||||
totalFee: Amounts.getZero("USD"),
|
totalFee: Amounts.getZero("USD"),
|
||||||
totalToDeposit: Amounts.parseOrThrow("USD:10"),
|
totalToDeposit: Amounts.parseOrThrow("USD:10"),
|
||||||
// onCalculateFee: alwaysReturnFeeToOne,
|
// onCalculateFee: alwaysReturnFeeToOne,
|
||||||
|
@ -18,6 +18,7 @@ import { AmountJson, Amounts, PaytoUri } from "@gnu-taler/taler-util";
|
|||||||
import { DepositGroupFees } from "@gnu-taler/taler-wallet-core/src/operations/deposits";
|
import { DepositGroupFees } from "@gnu-taler/taler-wallet-core/src/operations/deposits";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
|
import { Amount } from "../components/Amount.js";
|
||||||
import { Loading } from "../components/Loading.js";
|
import { Loading } from "../components/Loading.js";
|
||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import { SelectList } from "../components/SelectList.js";
|
import { SelectList } from "../components/SelectList.js";
|
||||||
@ -361,7 +362,7 @@ export function View({ state }: ViewProps): VNode {
|
|||||||
) : (
|
) : (
|
||||||
<Button variant="contained" onClick={state.depositHandler.onClick}>
|
<Button variant="contained" onClick={state.depositHandler.onClick}>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "}
|
Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "}
|
||||||
{state.currency}
|
{state.currency}
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -428,6 +428,8 @@ export const DepositTalerBank = createExample(TestedComponent, {
|
|||||||
export const DepositBitcoin = createExample(TestedComponent, {
|
export const DepositBitcoin = createExample(TestedComponent, {
|
||||||
transaction: {
|
transaction: {
|
||||||
...exampleData.deposit,
|
...exampleData.deposit,
|
||||||
|
amountRaw: "BITCOINBTC:0.0000011",
|
||||||
|
amountEffective: "BITCOINBTC:0.00000092",
|
||||||
targetPaytoUri:
|
targetPaytoUri:
|
||||||
"payto://bitcoin/bcrt1q6ps8qs6v8tkqrnru4xqqqa6rfwcx5ufpdfqht4?amount=BTC:0.1&subject=0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00",
|
"payto://bitcoin/bcrt1q6ps8qs6v8tkqrnru4xqqqa6rfwcx5ufpdfqht4?amount=BTC:0.1&subject=0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00",
|
||||||
},
|
},
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AbsoluteTime,
|
AbsoluteTime,
|
||||||
|
amountFractionalLength,
|
||||||
AmountJson,
|
AmountJson,
|
||||||
Amounts,
|
Amounts,
|
||||||
Location,
|
Location,
|
||||||
@ -749,7 +750,7 @@ function PurchaseDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Refunded</td>
|
<td>Refunded</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.totalRefundRaw} />
|
<Amount value={transaction.totalRefundRaw} negative />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -828,17 +829,20 @@ function RefundDetails({
|
|||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
const fee = Amounts.sub(
|
const r = Amounts.parseOrThrow(transaction.amountRaw);
|
||||||
Amounts.parseOrThrow(transaction.amountRaw),
|
const e = Amounts.parseOrThrow(transaction.amountEffective);
|
||||||
Amounts.parseOrThrow(transaction.amountEffective),
|
const fee = Amounts.sub(r, e).amount;
|
||||||
).amount;
|
|
||||||
|
const maxFrac = [r, e, fee]
|
||||||
|
.map((a) => Amounts.maxFractionalDigits(a))
|
||||||
|
.reduce((c, p) => Math.max(c, p), 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurchaseDetailsTable>
|
<PurchaseDetailsTable>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Amount</td>
|
<td>Amount</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountRaw} />
|
<Amount value={transaction.amountRaw} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -846,7 +850,7 @@ function RefundDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Transaction fees</td>
|
<td>Transaction fees</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={fee} />
|
<Amount value={fee} negative maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -858,7 +862,7 @@ function RefundDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Total</td>
|
<td>Total</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountEffective} />
|
<Amount value={transaction.amountEffective} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</PurchaseDetailsTable>
|
</PurchaseDetailsTable>
|
||||||
@ -871,18 +875,20 @@ function DepositDetails({
|
|||||||
transaction: TransactionDeposit;
|
transaction: TransactionDeposit;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
const r = Amounts.parseOrThrow(transaction.amountRaw);
|
||||||
|
const e = Amounts.parseOrThrow(transaction.amountEffective);
|
||||||
|
const fee = Amounts.sub(r, e).amount;
|
||||||
|
|
||||||
const fee = Amounts.sub(
|
const maxFrac = [r, e, fee]
|
||||||
Amounts.parseOrThrow(transaction.amountRaw),
|
.map((a) => Amounts.maxFractionalDigits(a))
|
||||||
Amounts.parseOrThrow(transaction.amountEffective),
|
.reduce((c, p) => Math.max(c, p), 0);
|
||||||
).amount;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurchaseDetailsTable>
|
<PurchaseDetailsTable>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Amount</td>
|
<td>Amount</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountRaw} />
|
<Amount value={transaction.amountRaw} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -890,7 +896,7 @@ function DepositDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Transaction fees</td>
|
<td>Transaction fees</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={fee} />
|
<Amount value={fee} negative maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -902,7 +908,7 @@ function DepositDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Total transfer</td>
|
<td>Total transfer</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountEffective} />
|
<Amount value={transaction.amountEffective} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</PurchaseDetailsTable>
|
</PurchaseDetailsTable>
|
||||||
@ -915,17 +921,26 @@ function RefreshDetails({
|
|||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
const fee = Amounts.sub(
|
const r = Amounts.parseOrThrow(transaction.amountRaw);
|
||||||
Amounts.parseOrThrow(transaction.amountRaw),
|
const e = Amounts.parseOrThrow(transaction.amountEffective);
|
||||||
Amounts.parseOrThrow(transaction.amountEffective),
|
const fee = Amounts.sub(r, e).amount;
|
||||||
).amount;
|
|
||||||
|
const maxFrac = [r, e, fee]
|
||||||
|
.map((a) => Amounts.maxFractionalDigits(a))
|
||||||
|
.reduce((c, p) => Math.max(c, p), 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurchaseDetailsTable>
|
<PurchaseDetailsTable>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Amount</td>
|
<td>Amount</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountRaw} />
|
<Amount value={transaction.amountRaw} maxFracSize={maxFrac} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Transaction fees</td>
|
||||||
|
<td>
|
||||||
|
<Amount value={fee} negative maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -934,9 +949,9 @@ function RefreshDetails({
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Transaction fees</td>
|
<td>Total</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={fee} />
|
<Amount value={transaction.amountEffective} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</PurchaseDetailsTable>
|
</PurchaseDetailsTable>
|
||||||
@ -946,17 +961,20 @@ function RefreshDetails({
|
|||||||
function TipDetails({ transaction }: { transaction: TransactionTip }): VNode {
|
function TipDetails({ transaction }: { transaction: TransactionTip }): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
const fee = Amounts.sub(
|
const r = Amounts.parseOrThrow(transaction.amountRaw);
|
||||||
Amounts.parseOrThrow(transaction.amountRaw),
|
const e = Amounts.parseOrThrow(transaction.amountEffective);
|
||||||
Amounts.parseOrThrow(transaction.amountEffective),
|
const fee = Amounts.sub(r, e).amount;
|
||||||
).amount;
|
|
||||||
|
const maxFrac = [r, e, fee]
|
||||||
|
.map((a) => Amounts.maxFractionalDigits(a))
|
||||||
|
.reduce((c, p) => Math.max(c, p), 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurchaseDetailsTable>
|
<PurchaseDetailsTable>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Amount</td>
|
<td>Amount</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountRaw} />
|
<Amount value={transaction.amountRaw} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -964,7 +982,7 @@ function TipDetails({ transaction }: { transaction: TransactionTip }): VNode {
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Transaction fees</td>
|
<td>Transaction fees</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={fee} />
|
<Amount value={fee} negative maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -976,7 +994,7 @@ function TipDetails({ transaction }: { transaction: TransactionTip }): VNode {
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Total</td>
|
<td>Total</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountEffective} />
|
<Amount value={transaction.amountEffective} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</PurchaseDetailsTable>
|
</PurchaseDetailsTable>
|
||||||
@ -990,17 +1008,20 @@ function WithdrawDetails({
|
|||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
const fee = Amounts.sub(
|
const r = Amounts.parseOrThrow(transaction.amountRaw);
|
||||||
Amounts.parseOrThrow(transaction.amountRaw),
|
const e = Amounts.parseOrThrow(transaction.amountEffective);
|
||||||
Amounts.parseOrThrow(transaction.amountEffective),
|
const fee = Amounts.sub(r, e).amount;
|
||||||
).amount;
|
|
||||||
|
const maxFrac = [r, e, fee]
|
||||||
|
.map((a) => Amounts.maxFractionalDigits(a))
|
||||||
|
.reduce((c, p) => Math.max(c, p), 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PurchaseDetailsTable>
|
<PurchaseDetailsTable>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Withdraw</td>
|
<td>Withdraw</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountRaw} />
|
<Amount value={transaction.amountRaw} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -1008,7 +1029,7 @@ function WithdrawDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Transaction fees</td>
|
<td>Transaction fees</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={fee} />
|
<Amount value={fee} negative maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
@ -1020,7 +1041,7 @@ function WithdrawDetails({
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Total</td>
|
<td>Total</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={transaction.amountEffective} />
|
<Amount value={transaction.amountEffective} maxFracSize={maxFrac} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</PurchaseDetailsTable>
|
</PurchaseDetailsTable>
|
||||||
@ -1059,9 +1080,8 @@ function Header({
|
|||||||
<SubTitle>
|
<SubTitle>
|
||||||
<Part
|
<Part
|
||||||
title={type}
|
title={type}
|
||||||
text={<Amount value={total} />}
|
text={<Amount value={total} negative={kind === "negative"} />}
|
||||||
kind={kind}
|
kind={kind}
|
||||||
showSign
|
|
||||||
/>
|
/>
|
||||||
</SubTitle>
|
</SubTitle>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user