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,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
addDecimalsNormalizeNumber,
|
||||
PriceCell,
|
||||
signedNumberCssClass,
|
||||
t,
|
||||
@ -236,7 +236,7 @@ export const columns = (
|
||||
value: market.data?.markPrice ? (
|
||||
<PriceCell
|
||||
value={Number(market.data?.markPrice)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
market.data?.markPrice.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -300,7 +300,7 @@ export const columns = (
|
||||
value: candleHigh ? (
|
||||
<PriceCell
|
||||
value={Number(candleHigh)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
candleHigh.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -317,7 +317,7 @@ export const columns = (
|
||||
value: candleLow ? (
|
||||
<PriceCell
|
||||
value={Number(candleLow)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
candleLow.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -332,7 +332,7 @@ export const columns = (
|
||||
{
|
||||
kind: ColumnKind.Volume,
|
||||
value: candleVolume
|
||||
? addDecimalsFormatNumber(
|
||||
? addDecimalsNormalizeNumber(
|
||||
candleVolume.toString(),
|
||||
market.positionDecimalPlaces,
|
||||
2
|
||||
@ -411,7 +411,7 @@ export const columnsPositionMarkets = (
|
||||
value: market.data?.markPrice ? (
|
||||
<PriceCell
|
||||
value={Number(market.data.markPrice)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
market.data.markPrice.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -475,7 +475,7 @@ export const columnsPositionMarkets = (
|
||||
value: candleHigh ? (
|
||||
<PriceCell
|
||||
value={Number(candleHigh)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
candleHigh.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -492,7 +492,7 @@ export const columnsPositionMarkets = (
|
||||
value: candleLow ? (
|
||||
<PriceCell
|
||||
value={Number(candleLow)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
valueFormatted={addDecimalsNormalizeNumber(
|
||||
candleLow.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
@ -507,7 +507,7 @@ export const columnsPositionMarkets = (
|
||||
{
|
||||
kind: ColumnKind.Volume,
|
||||
value: candleVolume
|
||||
? addDecimalsFormatNumber(
|
||||
? addDecimalsNormalizeNumber(
|
||||
candleVolume.toString(),
|
||||
market.positionDecimalPlaces,
|
||||
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 { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { Button, Dialog } from '@vegaprotocol/ui-toolkit';
|
||||
import React from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
interface Props {
|
||||
margin: string;
|
||||
@ -30,9 +30,11 @@ export const ValidateMargin = ({
|
||||
{t("You don't have enough margin available to open this position.")}
|
||||
</p>
|
||||
<p>
|
||||
{`${formatNumber(margin, decimals)} ${symbol} ${t(
|
||||
{`${normalizeFormatNumber(margin, decimals)} ${symbol} ${t(
|
||||
'currently required'
|
||||
)}, ${formatNumber(balance, decimals)} ${symbol} ${t('available')}`}
|
||||
)}, ${normalizeFormatNumber(balance, decimals)} ${symbol} ${t(
|
||||
'available'
|
||||
)}`}
|
||||
</p>
|
||||
<Button
|
||||
className="center mt-2"
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
interface DealTicketFeeDetailsProps {
|
||||
@ -20,7 +21,7 @@ export const DealTicketFeeDetails = ({
|
||||
{details.map(({ label, value, labelDescription, quoteName }) => (
|
||||
<div
|
||||
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>
|
||||
<Tooltip description={labelDescription}>
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
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 { addDecimal, removeDecimal, t } from '@vegaprotocol/react-helpers';
|
||||
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 {
|
||||
isMarketInAuction,
|
||||
useOrderValidation,
|
||||
} from '../deal-ticket-validation/use-order-validation';
|
||||
import { DealTicketAmount } from './deal-ticket-amount';
|
||||
import { DealTicketFeeDetails } from './deal-ticket-fee-details';
|
||||
import {
|
||||
useFeeDealTicketDetails,
|
||||
getFeeDetailsValues,
|
||||
} from '../../hooks/use-fee-deal-ticket-details';
|
||||
import { ExpirySelector } from './expiry-selector';
|
||||
import { SideSelector } from './side-selector';
|
||||
import { TimeInForceSelector } from './time-in-force-selector';
|
||||
import { TypeSelector } from './type-selector';
|
||||
|
||||
import type { DealTicketMarketFragment } from './__generated___/DealTicket';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
export type TransactionStatus = 'default' | 'pending';
|
||||
|
||||
export interface DealTicketProps {
|
||||
|
@ -1,22 +1,23 @@
|
||||
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 type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useMemo } from 'react';
|
||||
import type { DealTicketMarketFragment } from '../components';
|
||||
|
||||
import {
|
||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||
EST_MARGIN_TOOLTIP_TEXT,
|
||||
EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||
EST_MARGIN_TOOLTIP_TEXT,
|
||||
NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||
} from '../components/constants';
|
||||
import { usePartyBalanceQuery } from './__generated__/PartyBalance';
|
||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||
import { useOrderCloseOut } from './use-order-closeout';
|
||||
import type { OrderMargin } 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 = (
|
||||
order: OrderSubmissionBody['orderSubmission'],
|
||||
market: DealTicketMarketFragment
|
||||
@ -97,12 +98,12 @@ export const getFeeDetailsValues = ({
|
||||
}: FeeDetails) => {
|
||||
const formatValue = (value: string | number | null | undefined): string => {
|
||||
return value && !isNaN(Number(value))
|
||||
? formatNumber(value, market.decimalPlaces)
|
||||
? normalizeFormatNumber(value, market.decimalPlaces)
|
||||
: '-';
|
||||
};
|
||||
return [
|
||||
{
|
||||
label: t('Notional value'),
|
||||
label: t('Notional'),
|
||||
value: formatValue(notionalSize),
|
||||
quoteName,
|
||||
labelDescription: NOTIONAL_SIZE_TOOLTIP_TEXT,
|
||||
@ -127,14 +128,14 @@ export const getFeeDetailsValues = ({
|
||||
quoteName,
|
||||
},
|
||||
{
|
||||
label: t('Margin required'),
|
||||
label: t('Margin'),
|
||||
value: estMargin?.margin && `~${formatValue(estMargin?.margin)}`,
|
||||
quoteName,
|
||||
labelDescription: EST_MARGIN_TOOLTIP_TEXT,
|
||||
},
|
||||
{
|
||||
label: t('Liquidation price (variable)'),
|
||||
value: formatValue(estCloseOut),
|
||||
label: t('Liquidation'),
|
||||
value: estCloseOut && `~${formatValue(estCloseOut)}`,
|
||||
quoteName,
|
||||
labelDescription: EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||
},
|
||||
|
@ -1,13 +1,45 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import {
|
||||
addDecimalsNormalizeNumber,
|
||||
compactNumber,
|
||||
formatNumber,
|
||||
formatNumberPercentage,
|
||||
toNumberParts,
|
||||
isNumeric,
|
||||
compactNumber,
|
||||
normalizeFormatNumber,
|
||||
toNumberParts,
|
||||
} 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([
|
||||
{ v: new BigNumber(123), d: 3, o: '123.000' },
|
||||
{ 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(30000), d: undefined, o: '30,000' },
|
||||
{ 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);
|
||||
});
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { BigNumber as EthersBigNumber } from 'ethers';
|
||||
import isNil from 'lodash/isNil';
|
||||
import memoize from 'lodash/memoize';
|
||||
import React from 'react';
|
||||
|
||||
import { getUserLocale } from './utils';
|
||||
|
||||
const MAX_FRACTION_DIGITS = 20;
|
||||
@ -55,6 +56,10 @@ export const getDecimalSeparator = memoize(
|
||||
.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 = (
|
||||
rawValue: string | number | BigNumber,
|
||||
formatDecimals = 0
|
||||
@ -62,6 +67,23 @@ export const formatNumber = (
|
||||
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 = (
|
||||
rawValue: string | number,
|
||||
decimalPlaces: number,
|
||||
@ -72,6 +94,15 @@ export const addDecimalsFormatNumber = (
|
||||
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) => {
|
||||
const decimalPlaces =
|
||||
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals;
|
||||
|
Loading…
Reference in New Issue
Block a user