fix: 1875 & 1876 fix deal ticket fees display and remove insignificant trailing zeros (#1898)
This commit is contained in:
parent
082683a541
commit
3e970f7023
@ -7,7 +7,7 @@ import {
|
|||||||
calcCandleVolume,
|
calcCandleVolume,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsNormalizeNumber,
|
||||||
PriceCell,
|
PriceCell,
|
||||||
signedNumberCssClass,
|
signedNumberCssClass,
|
||||||
t,
|
t,
|
||||||
@ -236,7 +236,7 @@ export const columns = (
|
|||||||
value: market.data?.markPrice ? (
|
value: market.data?.markPrice ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(market.data?.markPrice)}
|
value={Number(market.data?.markPrice)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
market.data?.markPrice.toString(),
|
market.data?.markPrice.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -300,7 +300,7 @@ export const columns = (
|
|||||||
value: candleHigh ? (
|
value: candleHigh ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(candleHigh)}
|
value={Number(candleHigh)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
candleHigh.toString(),
|
candleHigh.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -317,7 +317,7 @@ export const columns = (
|
|||||||
value: candleLow ? (
|
value: candleLow ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(candleLow)}
|
value={Number(candleLow)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
candleLow.toString(),
|
candleLow.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -332,7 +332,7 @@ export const columns = (
|
|||||||
{
|
{
|
||||||
kind: ColumnKind.Volume,
|
kind: ColumnKind.Volume,
|
||||||
value: candleVolume
|
value: candleVolume
|
||||||
? addDecimalsFormatNumber(
|
? addDecimalsNormalizeNumber(
|
||||||
candleVolume.toString(),
|
candleVolume.toString(),
|
||||||
market.positionDecimalPlaces,
|
market.positionDecimalPlaces,
|
||||||
2
|
2
|
||||||
@ -411,7 +411,7 @@ export const columnsPositionMarkets = (
|
|||||||
value: market.data?.markPrice ? (
|
value: market.data?.markPrice ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(market.data.markPrice)}
|
value={Number(market.data.markPrice)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
market.data.markPrice.toString(),
|
market.data.markPrice.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -475,7 +475,7 @@ export const columnsPositionMarkets = (
|
|||||||
value: candleHigh ? (
|
value: candleHigh ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(candleHigh)}
|
value={Number(candleHigh)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
candleHigh.toString(),
|
candleHigh.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -492,7 +492,7 @@ export const columnsPositionMarkets = (
|
|||||||
value: candleLow ? (
|
value: candleLow ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(candleLow)}
|
value={Number(candleLow)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsNormalizeNumber(
|
||||||
candleLow.toString(),
|
candleLow.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
@ -507,7 +507,7 @@ export const columnsPositionMarkets = (
|
|||||||
{
|
{
|
||||||
kind: ColumnKind.Volume,
|
kind: ColumnKind.Volume,
|
||||||
value: candleVolume
|
value: candleVolume
|
||||||
? addDecimalsFormatNumber(
|
? addDecimalsNormalizeNumber(
|
||||||
candleVolume.toString(),
|
candleVolume.toString(),
|
||||||
market.positionDecimalPlaces,
|
market.positionDecimalPlaces,
|
||||||
2
|
2
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
|
||||||
import { formatNumber, t } from '@vegaprotocol/react-helpers';
|
|
||||||
import { Button, Dialog } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { DepositContainer } from '@vegaprotocol/deposits';
|
import { DepositContainer } from '@vegaprotocol/deposits';
|
||||||
|
import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||||
|
import { Button, Dialog } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import React from 'react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
margin: string;
|
margin: string;
|
||||||
@ -30,9 +30,11 @@ export const ValidateMargin = ({
|
|||||||
{t("You don't have enough margin available to open this position.")}
|
{t("You don't have enough margin available to open this position.")}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{`${formatNumber(margin, decimals)} ${symbol} ${t(
|
{`${normalizeFormatNumber(margin, decimals)} ${symbol} ${t(
|
||||||
'currently required'
|
'currently required'
|
||||||
)}, ${formatNumber(balance, decimals)} ${symbol} ${t('available')}`}
|
)}, ${normalizeFormatNumber(balance, decimals)} ${symbol} ${t(
|
||||||
|
'available'
|
||||||
|
)}`}
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
className="center mt-2"
|
className="center mt-2"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
interface DealTicketFeeDetailsProps {
|
interface DealTicketFeeDetailsProps {
|
||||||
@ -20,7 +21,7 @@ export const DealTicketFeeDetails = ({
|
|||||||
{details.map(({ label, value, labelDescription, quoteName }) => (
|
{details.map(({ label, value, labelDescription, quoteName }) => (
|
||||||
<div
|
<div
|
||||||
key={label}
|
key={label}
|
||||||
className="text-sm mt-2 flex justify-between items-center gap-4 flex-wrap"
|
className="text-xs mt-2 flex justify-between items-center gap-4 flex-wrap"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<Tooltip description={labelDescription}>
|
<Tooltip description={labelDescription}>
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { useCallback, useEffect } from 'react';
|
import { addDecimal, removeDecimal, t } from '@vegaprotocol/react-helpers';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
|
||||||
import { t, removeDecimal, addDecimal } from '@vegaprotocol/react-helpers';
|
|
||||||
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { TypeSelector } from './type-selector';
|
|
||||||
import { SideSelector } from './side-selector';
|
|
||||||
import { DealTicketAmount } from './deal-ticket-amount';
|
|
||||||
import { TimeInForceSelector } from './time-in-force-selector';
|
|
||||||
import type { DealTicketMarketFragment } from './__generated___/DealTicket';
|
|
||||||
import { ExpirySelector } from './expiry-selector';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
|
||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
|
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getFeeDetailsValues,
|
||||||
|
useFeeDealTicketDetails,
|
||||||
|
} from '../../hooks/use-fee-deal-ticket-details';
|
||||||
import { getDefaultOrder } from '../deal-ticket-validation';
|
import { getDefaultOrder } from '../deal-ticket-validation';
|
||||||
import {
|
import {
|
||||||
isMarketInAuction,
|
isMarketInAuction,
|
||||||
useOrderValidation,
|
useOrderValidation,
|
||||||
} from '../deal-ticket-validation/use-order-validation';
|
} from '../deal-ticket-validation/use-order-validation';
|
||||||
|
import { DealTicketAmount } from './deal-ticket-amount';
|
||||||
import { DealTicketFeeDetails } from './deal-ticket-fee-details';
|
import { DealTicketFeeDetails } from './deal-ticket-fee-details';
|
||||||
import {
|
import { ExpirySelector } from './expiry-selector';
|
||||||
useFeeDealTicketDetails,
|
import { SideSelector } from './side-selector';
|
||||||
getFeeDetailsValues,
|
import { TimeInForceSelector } from './time-in-force-selector';
|
||||||
} from '../../hooks/use-fee-deal-ticket-details';
|
import { TypeSelector } from './type-selector';
|
||||||
|
|
||||||
|
import type { DealTicketMarketFragment } from './__generated___/DealTicket';
|
||||||
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
export type TransactionStatus = 'default' | 'pending';
|
export type TransactionStatus = 'default' | 'pending';
|
||||||
|
|
||||||
export interface DealTicketProps {
|
export interface DealTicketProps {
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
import { FeesBreakdown } from '@vegaprotocol/market-info';
|
import { FeesBreakdown } from '@vegaprotocol/market-info';
|
||||||
import { formatNumber, t } from '@vegaprotocol/react-helpers';
|
import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { DealTicketMarketFragment } from '../components';
|
|
||||||
import {
|
import {
|
||||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
|
||||||
EST_MARGIN_TOOLTIP_TEXT,
|
|
||||||
EST_CLOSEOUT_TOOLTIP_TEXT,
|
EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||||
|
EST_MARGIN_TOOLTIP_TEXT,
|
||||||
|
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||||
} from '../components/constants';
|
} from '../components/constants';
|
||||||
|
import { usePartyBalanceQuery } from './__generated__/PartyBalance';
|
||||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
import { useOrderCloseOut } from './use-order-closeout';
|
||||||
import type { OrderMargin } from './use-order-margin';
|
|
||||||
import { useOrderMargin } from './use-order-margin';
|
import { useOrderMargin } from './use-order-margin';
|
||||||
import { usePartyBalanceQuery } from './__generated__/PartyBalance';
|
|
||||||
|
|
||||||
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
|
import type { DealTicketMarketFragment } from '../components';
|
||||||
|
import type { OrderMargin } from './use-order-margin';
|
||||||
export const useFeeDealTicketDetails = (
|
export const useFeeDealTicketDetails = (
|
||||||
order: OrderSubmissionBody['orderSubmission'],
|
order: OrderSubmissionBody['orderSubmission'],
|
||||||
market: DealTicketMarketFragment
|
market: DealTicketMarketFragment
|
||||||
@ -97,12 +98,12 @@ export const getFeeDetailsValues = ({
|
|||||||
}: FeeDetails) => {
|
}: FeeDetails) => {
|
||||||
const formatValue = (value: string | number | null | undefined): string => {
|
const formatValue = (value: string | number | null | undefined): string => {
|
||||||
return value && !isNaN(Number(value))
|
return value && !isNaN(Number(value))
|
||||||
? formatNumber(value, market.decimalPlaces)
|
? normalizeFormatNumber(value, market.decimalPlaces)
|
||||||
: '-';
|
: '-';
|
||||||
};
|
};
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: t('Notional value'),
|
label: t('Notional'),
|
||||||
value: formatValue(notionalSize),
|
value: formatValue(notionalSize),
|
||||||
quoteName,
|
quoteName,
|
||||||
labelDescription: NOTIONAL_SIZE_TOOLTIP_TEXT,
|
labelDescription: NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||||
@ -127,14 +128,14 @@ export const getFeeDetailsValues = ({
|
|||||||
quoteName,
|
quoteName,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('Margin required'),
|
label: t('Margin'),
|
||||||
value: estMargin?.margin && `~${formatValue(estMargin?.margin)}`,
|
value: estMargin?.margin && `~${formatValue(estMargin?.margin)}`,
|
||||||
quoteName,
|
quoteName,
|
||||||
labelDescription: EST_MARGIN_TOOLTIP_TEXT,
|
labelDescription: EST_MARGIN_TOOLTIP_TEXT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('Liquidation price (variable)'),
|
label: t('Liquidation'),
|
||||||
value: formatValue(estCloseOut),
|
value: estCloseOut && `~${formatValue(estCloseOut)}`,
|
||||||
quoteName,
|
quoteName,
|
||||||
labelDescription: EST_CLOSEOUT_TOOLTIP_TEXT,
|
labelDescription: EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,45 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
addDecimalsNormalizeNumber,
|
||||||
|
compactNumber,
|
||||||
formatNumber,
|
formatNumber,
|
||||||
formatNumberPercentage,
|
formatNumberPercentage,
|
||||||
toNumberParts,
|
|
||||||
isNumeric,
|
isNumeric,
|
||||||
compactNumber,
|
normalizeFormatNumber,
|
||||||
|
toNumberParts,
|
||||||
} from './number';
|
} from './number';
|
||||||
|
|
||||||
describe('formatNumber and formatNumberPercentage', () => {
|
describe('number react-helpers', () => {
|
||||||
|
it.each([
|
||||||
|
{ v: new BigNumber(123000), d: 5, o: '1.23' },
|
||||||
|
{ v: new BigNumber(123000), d: 3, o: '123' },
|
||||||
|
{ v: new BigNumber(123000), d: 1, o: '12,300.0' },
|
||||||
|
{ v: new BigNumber(123001), d: 2, o: '1,230.01' },
|
||||||
|
{ v: new BigNumber(123001000), d: 2, o: '1,230,010.00' },
|
||||||
|
])(
|
||||||
|
'formats with addDecimalsNormalizeNumber given number correctly',
|
||||||
|
({ v, d, o }) => {
|
||||||
|
expect(addDecimalsNormalizeNumber(v.toString(), d)).toStrictEqual(o);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{ v: new BigNumber(123.0), d: 3, o: '123' },
|
||||||
|
{ v: new BigNumber(123.123), d: 3, o: '123.123' },
|
||||||
|
{ v: new BigNumber(123.6666), d: 3, o: '123.667' },
|
||||||
|
{ v: new BigNumber(123.003), d: 6, o: '123.003' },
|
||||||
|
{ v: new BigNumber(123.003), d: 0, o: '123' },
|
||||||
|
{ v: new BigNumber(123), d: undefined, o: '123' },
|
||||||
|
{ v: new BigNumber(30000), d: undefined, o: '30,000' },
|
||||||
|
{ v: new BigNumber(3.000001), d: undefined, o: '3' },
|
||||||
|
])(
|
||||||
|
`formats with normalizeFormatNumber given number correctly`,
|
||||||
|
({ v, d, o }) => {
|
||||||
|
expect(normalizeFormatNumber(v, d)).toStrictEqual(o);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
{ v: new BigNumber(123), d: 3, o: '123.000' },
|
{ v: new BigNumber(123), d: 3, o: '123.000' },
|
||||||
{ v: new BigNumber(123.123), d: 3, o: '123.123' },
|
{ v: new BigNumber(123.123), d: 3, o: '123.123' },
|
||||||
@ -17,7 +49,7 @@ describe('formatNumber and formatNumberPercentage', () => {
|
|||||||
{ v: new BigNumber(123), d: undefined, o: '123' },
|
{ v: new BigNumber(123), d: undefined, o: '123' },
|
||||||
{ v: new BigNumber(30000), d: undefined, o: '30,000' },
|
{ v: new BigNumber(30000), d: undefined, o: '30,000' },
|
||||||
{ v: new BigNumber(3.000001), d: undefined, o: '3' },
|
{ v: new BigNumber(3.000001), d: undefined, o: '3' },
|
||||||
])('formats given number correctly', ({ v, d, o }) => {
|
])('formats with formatNumber given number correctly', ({ v, d, o }) => {
|
||||||
expect(formatNumber(v, d)).toStrictEqual(o);
|
expect(formatNumber(v, d)).toStrictEqual(o);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { BigNumber as EthersBigNumber } from 'ethers';
|
|||||||
import isNil from 'lodash/isNil';
|
import isNil from 'lodash/isNil';
|
||||||
import memoize from 'lodash/memoize';
|
import memoize from 'lodash/memoize';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { getUserLocale } from './utils';
|
import { getUserLocale } from './utils';
|
||||||
|
|
||||||
const MAX_FRACTION_DIGITS = 20;
|
const MAX_FRACTION_DIGITS = 20;
|
||||||
@ -55,6 +56,10 @@ export const getDecimalSeparator = memoize(
|
|||||||
.find((part) => part.type === 'decimal')?.value
|
.find((part) => part.type === 'decimal')?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** formatNumber will format the number with fixed decimals
|
||||||
|
* @param rawValue - should be a number that is not outside the safe range fail as in https://mikemcl.github.io/bignumber.js/#toN
|
||||||
|
* @param formatDecimals - number of decimals to use
|
||||||
|
*/
|
||||||
export const formatNumber = (
|
export const formatNumber = (
|
||||||
rawValue: string | number | BigNumber,
|
rawValue: string | number | BigNumber,
|
||||||
formatDecimals = 0
|
formatDecimals = 0
|
||||||
@ -62,6 +67,23 @@ export const formatNumber = (
|
|||||||
return getNumberFormat(formatDecimals).format(Number(rawValue));
|
return getNumberFormat(formatDecimals).format(Number(rawValue));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** normalizeFormatNumber will format the number with fixed decimals, but without insignificant trailing zeros
|
||||||
|
* @param rawValue - should be a number that is not outside the safe range fail as in https://mikemcl.github.io/bignumber.js/#toN
|
||||||
|
* @param formatDecimals - number of decimals to use
|
||||||
|
*/
|
||||||
|
export const normalizeFormatNumber = (
|
||||||
|
rawValue: string | number | BigNumber,
|
||||||
|
formatDecimals = 0
|
||||||
|
): string => {
|
||||||
|
const numberToFormat = getNumberFormat(formatDecimals).format(
|
||||||
|
Number(rawValue)
|
||||||
|
);
|
||||||
|
// Multiplying by 1 safely removes the insignificant trailing zeros from the formatted number
|
||||||
|
return !isNaN(Number(numberToFormat))
|
||||||
|
? (Number(numberToFormat) * 1).toString()
|
||||||
|
: numberToFormat;
|
||||||
|
};
|
||||||
|
|
||||||
export const addDecimalsFormatNumber = (
|
export const addDecimalsFormatNumber = (
|
||||||
rawValue: string | number,
|
rawValue: string | number,
|
||||||
decimalPlaces: number,
|
decimalPlaces: number,
|
||||||
@ -72,6 +94,15 @@ export const addDecimalsFormatNumber = (
|
|||||||
return formatNumber(x, formatDecimals);
|
return formatNumber(x, formatDecimals);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addDecimalsNormalizeNumber = (
|
||||||
|
rawValue: string | number,
|
||||||
|
decimalPlaces: number,
|
||||||
|
formatDecimals: number = decimalPlaces
|
||||||
|
) => {
|
||||||
|
const x = addDecimal(rawValue, decimalPlaces);
|
||||||
|
return normalizeFormatNumber(x, formatDecimals);
|
||||||
|
};
|
||||||
|
|
||||||
export const formatNumberPercentage = (value: BigNumber, decimals?: number) => {
|
export const formatNumberPercentage = (value: BigNumber, decimals?: number) => {
|
||||||
const decimalPlaces =
|
const decimalPlaces =
|
||||||
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals;
|
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals;
|
||||||
|
Loading…
Reference in New Issue
Block a user