chore: single position table (1645) (#1749)
* chore: single position table (1645) chore: single position table (1645) * chore: tests fixed * chore: remove unused withSummaryRow arg * chore: use ag grid value formatter type helper * chore: update console-lite to use value formatter params helper * chore: fix e2e test by ignoring pinned row Co-authored-by: Rado <szpiechrados@gmail.com> Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
ce283aeee7
commit
8d2fe118ec
@ -7,10 +7,7 @@ import {
|
||||
signedNumberCssClassRules,
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
PositionsTableValueFormatterParams,
|
||||
Position,
|
||||
} from '@vegaprotocol/positions';
|
||||
import type { Position } from '@vegaprotocol/positions';
|
||||
import { AmountCell } from '@vegaprotocol/positions';
|
||||
import type {
|
||||
CellRendererSelectorResult,
|
||||
@ -20,6 +17,7 @@ import type {
|
||||
ColDef,
|
||||
} from 'ag-grid-community';
|
||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import { Intent, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const EmptyCell = () => '';
|
||||
@ -77,9 +75,7 @@ const useColumnDefinitions = () => {
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['openVolume'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'openVolume'>) => {
|
||||
let ret;
|
||||
if (value && data) {
|
||||
ret = node?.rowPinned
|
||||
@ -107,9 +103,7 @@ const useColumnDefinitions = () => {
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['markPrice'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'markPrice'>) => {
|
||||
if (
|
||||
data &&
|
||||
value &&
|
||||
@ -186,9 +180,8 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['currentLeverage'];
|
||||
}) => (value === undefined ? '' : formatNumber(value.toString(), 1)),
|
||||
}: VegaValueFormatterParams<Position, 'currentLeverage'>) =>
|
||||
value === undefined ? '' : formatNumber(value.toString(), 1),
|
||||
},
|
||||
{
|
||||
colId: 'marginallocated',
|
||||
@ -229,10 +222,8 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
data,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['realisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
}: VegaValueFormatterParams<Position, 'realisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
? ''
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals),
|
||||
cellRenderer: 'PriceFlashCell',
|
||||
@ -249,10 +240,8 @@ const useColumnDefinitions = () => {
|
||||
valueFormatter: ({
|
||||
value,
|
||||
data,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['unrealisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
? ''
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals),
|
||||
cellRenderer: 'PriceFlashCell',
|
||||
@ -266,9 +255,7 @@ const useColumnDefinitions = () => {
|
||||
type: 'rightAligned',
|
||||
valueFormatter: ({
|
||||
value,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['updatedAt'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'updatedAt'>) => {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
@ -31,36 +31,35 @@ describe('positions', { tags: '@smoke' }, () => {
|
||||
cy.wrap($marketSymbol).invoke('text').should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.get('[col-id="openVolume"]').each(($openVolume) => {
|
||||
cy.wrap($openVolume).invoke('text').should('not.be.empty');
|
||||
});
|
||||
cy.get('.ag-center-cols-container [col-id="openVolume"]').each(
|
||||
($openVolume) => {
|
||||
cy.wrap($openVolume).invoke('text').should('not.be.empty');
|
||||
}
|
||||
);
|
||||
|
||||
// includes average entry price, mark price, realised PNL & leverage
|
||||
cy.getByTestId('flash-cell').each(($prices) => {
|
||||
cy.wrap($prices).invoke('text').should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.get('[col-id="averageEntryPrice"]')
|
||||
cy.get('[col-id="liquidationPrice"]')
|
||||
.should('contain.text', '85,093.38') // entry price
|
||||
.should('contain.text', '0.00'); // liquidation price
|
||||
|
||||
cy.get('[col-id="currentLeverage"]').should('contain.text', '0.8');
|
||||
|
||||
cy.get('[col-id="capitalUtilisation"]') // margin allocated
|
||||
.should('contain.text', '0.00%')
|
||||
.should('contain.text', '1,000.01000');
|
||||
cy.get('[col-id="marginAccountBalance"]') // margin allocated
|
||||
.should('contain.text', '1,000.00000');
|
||||
|
||||
cy.get('[col-id="unrealisedPNL"]').each(($unrealisedPnl) => {
|
||||
cy.wrap($unrealisedPnl).invoke('text').should('not.be.empty');
|
||||
});
|
||||
|
||||
cy.getByTestId('flash-cell').should('contain.text', '276,761.40348'); // Total tDAI position
|
||||
cy.getByTestId('flash-cell').should('contain.text', '0.00000'); // Total Realised PNL
|
||||
cy.get('[col-id="notional"]').should('contain.text', '276,761.40348'); // Total tDAI position
|
||||
cy.get('[col-id="realisedPNL"]').should('contain.text', '0.00100'); // Total Realised PNL
|
||||
cy.get('[col-id="unrealisedPNL"]').should('contain.text', '8.95000'); // Total Unrealised PNL
|
||||
});
|
||||
|
||||
cy.getByTestId('balance').eq(1).should('have.text', '1,000.01000'); // Asset balance
|
||||
|
||||
cy.getByTestId('close-position').should('be.visible').and('have.length', 3);
|
||||
}
|
||||
});
|
||||
|
@ -42,6 +42,7 @@ interface PositionRejoined {
|
||||
export interface Position {
|
||||
marketName: string;
|
||||
averageEntryPrice: string;
|
||||
marginAccountBalance: BigNumber;
|
||||
capitalUtilisation: number;
|
||||
currentLeverage: number;
|
||||
decimals: number;
|
||||
@ -151,6 +152,7 @@ export const getMetrics = (
|
||||
metrics.push({
|
||||
marketName: market.tradableInstrument.instrument.name,
|
||||
averageEntryPrice: position.averageEntryPrice,
|
||||
marginAccountBalance,
|
||||
capitalUtilisation: Math.round(capitalUtilisation.toNumber()),
|
||||
currentLeverage: currentLeverage.toNumber(),
|
||||
marketDecimalPlaces,
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import type { Position } from './positions-data-providers';
|
||||
import { Positions } from './positions';
|
||||
import { useClosePosition, usePositionsAssets } from '../';
|
||||
import { PositionsTable, useClosePosition, usePositionsData } from '../';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
|
||||
interface PositionsManagerProps {
|
||||
partyId: string;
|
||||
@ -17,18 +17,20 @@ export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
||||
[submit]
|
||||
);
|
||||
|
||||
const { data, error, loading, assetSymbols } = usePositionsAssets(partyId);
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const { data, error, loading, getRows } = usePositionsData(partyId, gridRef);
|
||||
return (
|
||||
<>
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
{assetSymbols?.map((assetSymbol) => (
|
||||
<Positions
|
||||
partyId={partyId}
|
||||
assetSymbol={assetSymbol}
|
||||
key={assetSymbol}
|
||||
onClose={onClose}
|
||||
/>
|
||||
))}
|
||||
<PositionsTable
|
||||
domLayout="autoHeight"
|
||||
style={{ width: '100%' }}
|
||||
ref={gridRef}
|
||||
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||
rowData={data?.length ? undefined : []}
|
||||
datasource={{ getRows }}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</AsyncRenderer>
|
||||
|
||||
<Dialog>
|
||||
|
@ -3,28 +3,31 @@ import { act, render, screen } from '@testing-library/react';
|
||||
import PositionsTable from './positions-table';
|
||||
import type { Position } from './positions-data-providers';
|
||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React from 'react';
|
||||
|
||||
const singleRow: Position = {
|
||||
marketName: 'ETH/BTC (31 july 2022)',
|
||||
averageEntryPrice: '133', // 13.3
|
||||
capitalUtilisation: 11, // 11.00%
|
||||
averageEntryPrice: '133',
|
||||
capitalUtilisation: 11,
|
||||
currentLeverage: 1.1,
|
||||
marketDecimalPlaces: 1,
|
||||
positionDecimalPlaces: 0,
|
||||
decimals: 2,
|
||||
totalBalance: '123456',
|
||||
assetSymbol: 'BTC',
|
||||
liquidationPrice: '83', // 8.3
|
||||
liquidationPrice: '83',
|
||||
lowMarginLevel: false,
|
||||
marketId: 'string',
|
||||
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
markPrice: '123', // 12.3
|
||||
notional: '12300', // 1230.0
|
||||
openVolume: '100', // 100
|
||||
realisedPNL: '123', // 1.23
|
||||
unrealisedPNL: '456', // 4.56
|
||||
markPrice: '123',
|
||||
notional: '12300',
|
||||
openVolume: '100',
|
||||
realisedPNL: '123',
|
||||
unrealisedPNL: '456',
|
||||
searchPrice: '0',
|
||||
updatedAt: '2022-07-27T15:02:58.400Z',
|
||||
marginAccountBalance: new BigNumber(123456),
|
||||
};
|
||||
|
||||
const singleRowData = [singleRow];
|
||||
@ -42,14 +45,17 @@ it('Render correct columns', async () => {
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
expect(headers).toHaveLength(9);
|
||||
expect(headers).toHaveLength(12);
|
||||
expect(
|
||||
headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim())
|
||||
).toEqual([
|
||||
'Market',
|
||||
'Size',
|
||||
'Notional size',
|
||||
'Open volume',
|
||||
'Mark price',
|
||||
'Settlement asset',
|
||||
'Entry price',
|
||||
'Liquidation price (est)',
|
||||
'Leverage',
|
||||
'Margin allocated',
|
||||
'Realised PNL',
|
||||
@ -84,22 +90,21 @@ it('add color and sign to amount, displays positive notional value', async () =>
|
||||
result = render(<PositionsTable rowData={singleRowData} />);
|
||||
});
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
let values = cells[1].querySelectorAll('.text-right');
|
||||
expect(values[0].classList.contains('text-vega-green-dark')).toBeTruthy();
|
||||
expect(values[0].classList.contains('text-vega-red-dark')).toBeFalsy();
|
||||
expect(values[0].textContent).toEqual('+100');
|
||||
expect(values[1].textContent).toEqual('1,230.0');
|
||||
|
||||
expect(cells[2].classList.contains('text-vega-green-dark')).toBeTruthy();
|
||||
expect(cells[2].classList.contains('text-vega-red-dark')).toBeFalsy();
|
||||
expect(cells[2].textContent).toEqual('+100');
|
||||
expect(cells[1].textContent).toEqual('123.00');
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
<PositionsTable rowData={[{ ...singleRow, openVolume: '-100' }]} />
|
||||
);
|
||||
});
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
values = cells[1].querySelectorAll('.text-right');
|
||||
expect(values[0].classList.contains('text-vega-green-dark')).toBeFalsy();
|
||||
expect(values[0].classList.contains('text-vega-red-dark')).toBeTruthy();
|
||||
expect(values[0].textContent?.startsWith('-100')).toBeTruthy();
|
||||
expect(values[1].textContent).toEqual('1,230.0');
|
||||
expect(cells[2].classList.contains('text-vega-green-dark')).toBeFalsy();
|
||||
expect(cells[2].classList.contains('text-vega-red-dark')).toBeTruthy();
|
||||
expect(cells[2].textContent?.startsWith('-100')).toBeTruthy();
|
||||
expect(cells[1].textContent).toEqual('123.00');
|
||||
});
|
||||
|
||||
it('displays mark price', async () => {
|
||||
@ -109,7 +114,7 @@ it('displays mark price', async () => {
|
||||
});
|
||||
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[2].textContent).toEqual('12.3');
|
||||
expect(cells[3].textContent).toEqual('12.3');
|
||||
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
@ -125,7 +130,7 @@ it('displays mark price', async () => {
|
||||
});
|
||||
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[2].textContent).toEqual('-');
|
||||
expect(cells[3].textContent).toEqual('-');
|
||||
});
|
||||
|
||||
it("displays properly entry, liquidation price and liquidation bar and it's intent", async () => {
|
||||
@ -134,11 +139,10 @@ it("displays properly entry, liquidation price and liquidation bar and it's inte
|
||||
result = render(<PositionsTable rowData={singleRowData} />);
|
||||
});
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
let cell = cells[3];
|
||||
const entryPrice = cell.firstElementChild?.firstElementChild?.textContent;
|
||||
const entryPrice = cells[5].firstElementChild?.firstElementChild?.textContent;
|
||||
const liquidationPrice =
|
||||
cell.firstElementChild?.lastElementChild?.textContent;
|
||||
const progressBarTrack = cell.lastElementChild;
|
||||
cells[6].firstElementChild?.lastElementChild?.textContent;
|
||||
const progressBarTrack = cells[6].lastElementChild;
|
||||
let progressBar = progressBarTrack?.firstElementChild as HTMLElement;
|
||||
const progressBarWidth = progressBar?.style?.width;
|
||||
expect(entryPrice).toEqual('13.3');
|
||||
@ -151,8 +155,7 @@ it("displays properly entry, liquidation price and liquidation bar and it's inte
|
||||
);
|
||||
});
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
cell = cells[3];
|
||||
progressBar = cell.lastElementChild?.firstElementChild as HTMLElement;
|
||||
progressBar = cells[6].lastElementChild?.firstElementChild as HTMLElement;
|
||||
expect(progressBar?.classList.contains('bg-warning')).toEqual(true);
|
||||
});
|
||||
|
||||
@ -161,24 +164,16 @@ it('displays leverage', async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[4].textContent).toEqual('1.1');
|
||||
expect(cells[7].textContent).toEqual('1.1');
|
||||
});
|
||||
|
||||
it('displays allocated margin and margin bar', async () => {
|
||||
it('displays allocated margin', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const cell = cells[5];
|
||||
const capitalUtilisation =
|
||||
cell.firstElementChild?.firstElementChild?.textContent;
|
||||
const totalBalance = cell.firstElementChild?.lastElementChild?.textContent;
|
||||
const progressBarTrack = cell.lastElementChild;
|
||||
const progressBar = progressBarTrack?.firstElementChild as HTMLElement;
|
||||
const progressBarWidth = progressBar?.style?.width;
|
||||
expect(capitalUtilisation).toEqual('11.00%');
|
||||
expect(totalBalance).toEqual('1,234.56');
|
||||
expect(progressBarWidth).toEqual('11%');
|
||||
const cell = cells[8];
|
||||
expect(cell.textContent).toEqual('123,456.00');
|
||||
});
|
||||
|
||||
it('displays realised and unrealised PNL', async () => {
|
||||
@ -186,6 +181,6 @@ it('displays realised and unrealised PNL', async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[6].textContent).toEqual('1.23');
|
||||
expect(cells[7].textContent).toEqual('4.56');
|
||||
expect(cells[9].textContent).toEqual('1.23');
|
||||
expect(cells[10].textContent).toEqual('4.56');
|
||||
});
|
||||
|
@ -2,12 +2,13 @@ import classNames from 'classnames';
|
||||
import { forwardRef } from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import type {
|
||||
ValueFormatterParams,
|
||||
ValueGetterParams,
|
||||
ICellRendererParams,
|
||||
CellRendererSelectorResult,
|
||||
} from 'ag-grid-community';
|
||||
import type { ValueProps as PriceCellProps } from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
ValueProps as PriceCellProps,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { EmptyCell, ProgressBarCell } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
PriceFlashCell,
|
||||
@ -43,13 +44,6 @@ interface Props extends AgGridReactProps {
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export type PositionsTableValueFormatterParams = Omit<
|
||||
ValueFormatterParams,
|
||||
'data' | 'value'
|
||||
> & {
|
||||
data: Position;
|
||||
};
|
||||
|
||||
export interface MarketNameCellProps {
|
||||
valueFormatted?: [string, string];
|
||||
}
|
||||
@ -118,7 +112,7 @@ const ButtonCell = ({
|
||||
const progressBarValueFormatter = ({
|
||||
data,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams):
|
||||
}: VegaValueFormatterParams<Position, 'liquidationPrice'>):
|
||||
| PriceCellProps['valueFormatted']
|
||||
| undefined => {
|
||||
if (!data || node?.rowPinned) {
|
||||
@ -151,7 +145,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
resizable: true,
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
}}
|
||||
components={{ PriceFlashCell, ProgressBarCell }}
|
||||
components={{ AmountCell, PriceFlashCell, ProgressBarCell }}
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
@ -160,9 +154,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
cellRenderer={MarketNameCell}
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['marketName'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'marketName'>) => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
@ -175,33 +167,38 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Size')}
|
||||
field="openVolume"
|
||||
valueGetter={({ node, data }: ValueGetterParams) => {
|
||||
return node?.rowPinned ? data?.notional : data?.openVolume;
|
||||
}}
|
||||
headerName={t('Notional size')}
|
||||
field="notional"
|
||||
type="rightAligned"
|
||||
cellRendererSelector={(
|
||||
params: ICellRendererParams
|
||||
): CellRendererSelectorResult => {
|
||||
return {
|
||||
component: params.node.rowPinned ? PriceFlashCell : AmountCell,
|
||||
};
|
||||
}}
|
||||
cellClass="font-mono text-right"
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['openVolume'];
|
||||
}): AmountCellProps['valueFormatted'] | string => {
|
||||
}: VegaValueFormatterParams<Position, 'notional'>): string => {
|
||||
if (!value || !data) {
|
||||
return '';
|
||||
}
|
||||
return addDecimalsFormatNumber(value, data.decimals);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Open volume')}
|
||||
field="openVolume"
|
||||
type="rightAligned"
|
||||
cellClass="font-mono text-right"
|
||||
cellClassRules={signedNumberCssClassRules}
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: VegaValueFormatterParams<Position, 'openVolume'>):
|
||||
| string
|
||||
| undefined => {
|
||||
if (!value || !data) {
|
||||
return undefined;
|
||||
}
|
||||
if (node?.rowPinned) {
|
||||
return addDecimalsFormatNumber(value, data.decimals);
|
||||
}
|
||||
return data;
|
||||
return volumePrefix(
|
||||
addDecimalsFormatNumber(value, data.positionDecimalPlaces)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
@ -219,9 +216,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
value,
|
||||
data,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['markPrice'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'markPrice'>) => {
|
||||
if (!data || !value || node?.rowPinned) {
|
||||
return undefined;
|
||||
}
|
||||
@ -237,16 +232,34 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn headerName={t('Settlement asset')} field="assetSymbol" />
|
||||
<AgGridColumn
|
||||
headerName={t('Entry price')}
|
||||
field="averageEntryPrice"
|
||||
headerComponentParams={{
|
||||
template:
|
||||
'<div class="ag-cell-label-container" role="presentation">' +
|
||||
` <span>${t('Liquidation price (est)')}</span>` +
|
||||
' <span ref="eText" class="ag-header-cell-text"></span>' +
|
||||
'</div>',
|
||||
type="rightAligned"
|
||||
cellRendererSelector={(
|
||||
params: ICellRendererParams
|
||||
): CellRendererSelectorResult => {
|
||||
return {
|
||||
component: params.node.rowPinned ? EmptyCell : PriceFlashCell,
|
||||
};
|
||||
}}
|
||||
valueFormatter={({
|
||||
data,
|
||||
value,
|
||||
node,
|
||||
}: VegaValueFormatterParams<Position, 'averageEntryPrice'>):
|
||||
| string
|
||||
| undefined => {
|
||||
if (!data || node?.rowPinned || !value) {
|
||||
return undefined;
|
||||
}
|
||||
return addDecimalsFormatNumber(value, data.marketDecimalPlaces);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Liquidation price (est)')}
|
||||
field="liquidationPrice"
|
||||
flex={2}
|
||||
headerTooltip={t(
|
||||
'Liquidation prices are based on the amount of collateral you have available, the risk of your position and the liquidity on the order book. They can change rapidly based on the profit and loss of your positions and any changes to collateral from opening/closing other positions and making deposits/withdrawals.'
|
||||
@ -273,41 +286,32 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
}}
|
||||
valueFormatter={({
|
||||
value,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['currentLeverage'];
|
||||
}) =>
|
||||
}: VegaValueFormatterParams<Position, 'currentLeverage'>) =>
|
||||
value === undefined ? undefined : formatNumber(value.toString(), 1)
|
||||
}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Margin allocated')}
|
||||
field="capitalUtilisation"
|
||||
field="marginAccountBalance"
|
||||
type="rightAligned"
|
||||
flex={2}
|
||||
cellRenderer="ProgressBarCell"
|
||||
cellRendererSelector={(
|
||||
params: ICellRendererParams
|
||||
): CellRendererSelectorResult => {
|
||||
return {
|
||||
component: params.node.rowPinned ? EmptyCell : ProgressBarCell,
|
||||
component: params.node.rowPinned ? EmptyCell : PriceFlashCell,
|
||||
};
|
||||
}}
|
||||
valueFormatter={({
|
||||
data,
|
||||
value,
|
||||
node,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['capitalUtilisation'];
|
||||
}): PriceCellProps['valueFormatted'] | undefined => {
|
||||
if (!data || node?.rowPinned) {
|
||||
}: VegaValueFormatterParams<Position, 'marginAccountBalance'>):
|
||||
| string
|
||||
| undefined => {
|
||||
if (!data || node?.rowPinned || !value) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
low: `${formatNumber(value, 2)}%`,
|
||||
high: addDecimalsFormatNumber(data.totalBalance, data.decimals),
|
||||
value: Number(value),
|
||||
};
|
||||
return formatNumber(value, data.decimals);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
@ -318,10 +322,8 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['realisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
}: VegaValueFormatterParams<Position, 'realisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
? undefined
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals)
|
||||
}
|
||||
@ -338,10 +340,8 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
valueFormatter={({
|
||||
value,
|
||||
data,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['unrealisedPNL'];
|
||||
}) =>
|
||||
value === undefined
|
||||
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
|
||||
value === undefined || data === undefined
|
||||
? undefined
|
||||
: addDecimalsFormatNumber(value.toString(), data.decimals)
|
||||
}
|
||||
@ -356,9 +356,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
type="rightAligned"
|
||||
valueFormatter={({
|
||||
value,
|
||||
}: PositionsTableValueFormatterParams & {
|
||||
value: Position['updatedAt'];
|
||||
}) => {
|
||||
}: VegaValueFormatterParams<Position, 'updatedAt'>) => {
|
||||
if (!value) {
|
||||
return value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user