fix(markets): back with updating by grid api (#4059)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
37247a504a
commit
9184c2374c
@ -1,29 +1,14 @@
|
|||||||
import { forwardRef } from 'react';
|
import { forwardRef } from 'react';
|
||||||
import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils';
|
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import type {
|
|
||||||
VegaValueGetterParams,
|
|
||||||
VegaValueFormatterParams,
|
|
||||||
VegaICellRendererParams,
|
|
||||||
TypedDataAgGrid,
|
|
||||||
} from '@vegaprotocol/datagrid';
|
|
||||||
import { COL_DEFS } from '@vegaprotocol/datagrid';
|
|
||||||
import {
|
import {
|
||||||
AgGridLazy as AgGrid,
|
AgGridLazy as AgGrid,
|
||||||
PriceFlashCell,
|
PriceFlashCell,
|
||||||
MarketNameCell,
|
MarketNameCell,
|
||||||
SetFilter,
|
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { MarketMaybeWithData } from '../../markets-provider';
|
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||||
import { MarketTableActions } from './market-table-actions';
|
|
||||||
import { OracleStatus } from './oracle-status';
|
import { OracleStatus } from './oracle-status';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useColumnDefs } from './use-column-defs';
|
||||||
|
|
||||||
const { MarketTradingMode, AuctionTrigger } = Schema;
|
|
||||||
|
|
||||||
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
||||||
|
|
||||||
@ -51,199 +36,34 @@ const MarketName = (props: MarketNameCellProps) => (
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const defaultColDef = {
|
||||||
|
resizable: true,
|
||||||
|
sortable: true,
|
||||||
|
filter: true,
|
||||||
|
filterParams: { buttons: ['reset'] },
|
||||||
|
minWidth: 100,
|
||||||
|
};
|
||||||
|
|
||||||
export const MarketListTable = forwardRef<
|
export const MarketListTable = forwardRef<
|
||||||
AgGridReact,
|
AgGridReact,
|
||||||
TypedDataAgGrid<MarketMaybeWithData> & {
|
TypedDataAgGrid<MarketMaybeWithData> & {
|
||||||
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
||||||
}
|
}
|
||||||
>(({ onMarketClick, ...props }, ref) => {
|
>(({ onMarketClick, ...props }, ref) => {
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
const columnDefs = useColumnDefs({ onMarketClick });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
getRowId={getRowId}
|
getRowId={getRowId}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
defaultColDef={{
|
defaultColDef={defaultColDef}
|
||||||
resizable: true,
|
columnDefs={columnDefs}
|
||||||
sortable: true,
|
|
||||||
filter: true,
|
|
||||||
filterParams: { buttons: ['reset'] },
|
|
||||||
minWidth: 100,
|
|
||||||
}}
|
|
||||||
suppressCellFocus
|
suppressCellFocus
|
||||||
components={{ PriceFlashCell, MarketName }}
|
components={{ PriceFlashCell, MarketName }}
|
||||||
storeKey="allMarkets"
|
storeKey="allMarkets"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
/>
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Market')}
|
|
||||||
field="tradableInstrument.instrument.code"
|
|
||||||
cellRenderer="MarketName"
|
|
||||||
cellRendererParams={{ onMarketClick }}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Description')}
|
|
||||||
field="tradableInstrument.instrument.name"
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Trading mode')}
|
|
||||||
field="tradingMode"
|
|
||||||
minWidth={170}
|
|
||||||
valueFormatter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<MarketMaybeWithData, 'data'>) => {
|
|
||||||
if (!data?.data) return undefined;
|
|
||||||
const { trigger, marketTradingMode } = data.data;
|
|
||||||
return marketTradingMode ===
|
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
trigger &&
|
|
||||||
trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
|
||||||
? `${Schema.MarketTradingModeMapping[marketTradingMode]}
|
|
||||||
- ${Schema.AuctionTriggerMapping[trigger]}`
|
|
||||||
: Schema.MarketTradingModeMapping[marketTradingMode];
|
|
||||||
}}
|
|
||||||
filter={SetFilter}
|
|
||||||
filterParams={{
|
|
||||||
set: Schema.MarketTradingModeMapping,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Status')}
|
|
||||||
field="state"
|
|
||||||
valueFormatter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<MarketMaybeWithData, 'state'>) => {
|
|
||||||
return data?.state ? Schema.MarketStateMapping[data.state] : '-';
|
|
||||||
}}
|
|
||||||
filter={SetFilter}
|
|
||||||
filterParams={{
|
|
||||||
set: Schema.MarketStateMapping,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Best bid')}
|
|
||||||
field="data.bestBidPrice"
|
|
||||||
type="rightAligned"
|
|
||||||
cellRenderer="PriceFlashCell"
|
|
||||||
filter="agNumberColumnFilter"
|
|
||||||
valueGetter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueGetterParams<MarketMaybeWithData, 'data.bestBidPrice'>) => {
|
|
||||||
return data?.data?.bestBidPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: toBigNum(data?.data?.bestBidPrice, data.decimalPlaces).toNumber();
|
|
||||||
}}
|
|
||||||
valueFormatter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<
|
|
||||||
MarketMaybeWithData,
|
|
||||||
'data.bestBidPrice'
|
|
||||||
>) =>
|
|
||||||
data?.data?.bestBidPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: addDecimalsFormatNumber(
|
|
||||||
data.data.bestBidPrice,
|
|
||||||
data.decimalPlaces
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Best offer')}
|
|
||||||
field="data.bestOfferPrice"
|
|
||||||
type="rightAligned"
|
|
||||||
cellRenderer="PriceFlashCell"
|
|
||||||
filter="agNumberColumnFilter"
|
|
||||||
valueGetter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueGetterParams<
|
|
||||||
MarketMaybeWithData,
|
|
||||||
'data.bestOfferPrice'
|
|
||||||
>) => {
|
|
||||||
return data?.data?.bestOfferPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: toBigNum(
|
|
||||||
data?.data?.bestOfferPrice,
|
|
||||||
data.decimalPlaces
|
|
||||||
).toNumber();
|
|
||||||
}}
|
|
||||||
valueFormatter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<
|
|
||||||
MarketMaybeWithData,
|
|
||||||
'data.bestOfferPrice'
|
|
||||||
>) =>
|
|
||||||
data?.data?.bestOfferPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: addDecimalsFormatNumber(
|
|
||||||
data.data.bestOfferPrice,
|
|
||||||
data.decimalPlaces
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Mark price')}
|
|
||||||
field="data.markPrice"
|
|
||||||
type="rightAligned"
|
|
||||||
cellRenderer="PriceFlashCell"
|
|
||||||
filter="agNumberColumnFilter"
|
|
||||||
valueGetter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueGetterParams<MarketMaybeWithData, 'data.markPrice'>) => {
|
|
||||||
return data?.data?.markPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber();
|
|
||||||
}}
|
|
||||||
valueFormatter={({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<MarketMaybeWithData, 'data.markPrice'>) =>
|
|
||||||
data?.data?.bestOfferPrice === undefined
|
|
||||||
? undefined
|
|
||||||
: addDecimalsFormatNumber(data.data.markPrice, data.decimalPlaces)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Settlement asset')}
|
|
||||||
field="tradableInstrument.instrument.product.settlementAsset.symbol"
|
|
||||||
cellRenderer={({
|
|
||||||
data,
|
|
||||||
}: VegaICellRendererParams<
|
|
||||||
MarketMaybeWithData,
|
|
||||||
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
|
||||||
>) => {
|
|
||||||
const value =
|
|
||||||
data?.tradableInstrument.instrument.product.settlementAsset;
|
|
||||||
return value ? (
|
|
||||||
<ButtonLink
|
|
||||||
onClick={(e) => {
|
|
||||||
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{value.symbol}
|
|
||||||
</ButtonLink>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
colId="market-actions"
|
|
||||||
field="id"
|
|
||||||
{...COL_DEFS.actions}
|
|
||||||
cellRenderer={({
|
|
||||||
data,
|
|
||||||
}: VegaICellRendererParams<MarketMaybeWithData>) => {
|
|
||||||
if (!data) return null;
|
|
||||||
return (
|
|
||||||
<MarketTableActions
|
|
||||||
marketId={data.id}
|
|
||||||
assetId={
|
|
||||||
data.tradableInstrument.instrument.product.settlementAsset.id
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</AgGrid>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
import { render, screen, act, within } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import * as DataProviders from '@vegaprotocol/data-provider';
|
||||||
|
import { MockedProvider } from '@apollo/react-testing';
|
||||||
|
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||||
|
import { MarketsContainer } from './markets-container';
|
||||||
|
|
||||||
|
const market = {
|
||||||
|
id: 'id-1',
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
product: { settlementAsset: { id: 'assetId-1' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
decimalPlaces: 1,
|
||||||
|
positionDecimalPlaces: 1,
|
||||||
|
state: 'STATE_ACTIVE',
|
||||||
|
tradingMode: 'TRADING_MODE_OPENING_AUCTION',
|
||||||
|
data: {
|
||||||
|
bestBidPrice: 100,
|
||||||
|
},
|
||||||
|
} as unknown as MarketMaybeWithData;
|
||||||
|
|
||||||
|
describe('MarketsContainer', () => {
|
||||||
|
it('context menu should stay open', async () => {
|
||||||
|
const spyOnSelect = jest.fn();
|
||||||
|
jest
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
.spyOn<typeof DataProviders, any>(DataProviders, 'useDataProvider')
|
||||||
|
.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
error: null,
|
||||||
|
reload: jest.fn(),
|
||||||
|
data: [market],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let rerenderRef: (ui: React.ReactElement) => void;
|
||||||
|
await act(async () => {
|
||||||
|
const { rerender } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<MarketsContainer onSelect={spyOnSelect} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
rerenderRef = rerender;
|
||||||
|
});
|
||||||
|
|
||||||
|
// make sure ag grid is finished initializaing
|
||||||
|
const rowContainer = await screen.findByRole('rowgroup', {
|
||||||
|
name: (_name, element) =>
|
||||||
|
element.classList.contains('ag-center-cols-container'),
|
||||||
|
});
|
||||||
|
expect(within(rowContainer).getAllByRole('row')).toHaveLength(1);
|
||||||
|
expect(
|
||||||
|
screen.getByRole('rowgroup', {
|
||||||
|
name: (_name, element) =>
|
||||||
|
element.classList.contains('ag-pinned-right-cols-container'),
|
||||||
|
})
|
||||||
|
).toBeInTheDocument();
|
||||||
|
|
||||||
|
// open the dropdown
|
||||||
|
await userEvent.click(
|
||||||
|
screen.getByRole('button', {
|
||||||
|
name: (_name, element) =>
|
||||||
|
(element.parentNode as Element)?.getAttribute('id') ===
|
||||||
|
'cell-market-actions-8',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await checkDropdown();
|
||||||
|
|
||||||
|
// reset the mock and rerender so the component
|
||||||
|
// updates with new data
|
||||||
|
jest
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
.spyOn<typeof DataProviders, any>(DataProviders, 'useDataProvider')
|
||||||
|
.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
error: null,
|
||||||
|
reload: jest.fn(),
|
||||||
|
data: [{ ...market, state: 'STATE_PENDING' }],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-ignore we await the act above so rerenderRef is definitely defined
|
||||||
|
rerenderRef(
|
||||||
|
<MockedProvider mocks={[]}>
|
||||||
|
<MarketsContainer onSelect={spyOnSelect} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
// make sure dropdown is still open
|
||||||
|
await checkDropdown();
|
||||||
|
|
||||||
|
async function checkDropdown() {
|
||||||
|
const dropdownContent = await screen.findByTestId(
|
||||||
|
'market-actions-content'
|
||||||
|
);
|
||||||
|
expect(dropdownContent).toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
within(dropdownContent).getByRole('menuitem', {
|
||||||
|
name: 'Copy Market ID',
|
||||||
|
})
|
||||||
|
).toBeInTheDocument();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,196 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import type { ColDef } from 'ag-grid-community';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type {
|
||||||
|
VegaICellRendererParams,
|
||||||
|
VegaValueFormatterParams,
|
||||||
|
VegaValueGetterParams,
|
||||||
|
} from '@vegaprotocol/datagrid';
|
||||||
|
import { COL_DEFS, SetFilter } from '@vegaprotocol/datagrid';
|
||||||
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils';
|
||||||
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
|
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||||
|
import { MarketTableActions } from './market-table-actions';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { MarketTradingMode, AuctionTrigger } = Schema;
|
||||||
|
|
||||||
|
export const useColumnDefs = ({ onMarketClick }: Props) => {
|
||||||
|
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||||
|
|
||||||
|
return useMemo<ColDef[]>(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
headerName: t('Market'),
|
||||||
|
field: 'tradableInstrument.instrument.code',
|
||||||
|
cellRenderer: 'MarketName',
|
||||||
|
cellRendererParams: { onMarketClick },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Description'),
|
||||||
|
field: 'tradableInstrument.instrument.name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Trading mode'),
|
||||||
|
field: 'tradingMode',
|
||||||
|
minWidth: 170,
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<MarketMaybeWithData, 'data'>) => {
|
||||||
|
if (!data?.data) return '-';
|
||||||
|
const { trigger, marketTradingMode } = data.data;
|
||||||
|
return marketTradingMode ===
|
||||||
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
|
trigger &&
|
||||||
|
trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
|
? `${Schema.MarketTradingModeMapping[marketTradingMode]}
|
||||||
|
- ${Schema.AuctionTriggerMapping[trigger]}`
|
||||||
|
: Schema.MarketTradingModeMapping[marketTradingMode];
|
||||||
|
},
|
||||||
|
filter: SetFilter,
|
||||||
|
filterParams: {
|
||||||
|
set: Schema.MarketTradingModeMapping,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Status'),
|
||||||
|
field: 'state',
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<MarketMaybeWithData, 'state'>) => {
|
||||||
|
return data?.state ? Schema.MarketStateMapping[data.state] : '-';
|
||||||
|
},
|
||||||
|
filter: SetFilter,
|
||||||
|
filterParams: {
|
||||||
|
set: Schema.MarketStateMapping,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Best bid'),
|
||||||
|
field: 'data.bestBidPrice',
|
||||||
|
type: 'rightAligned',
|
||||||
|
cellRenderer: 'PriceFlashCell',
|
||||||
|
filter: 'agNumberColumnFilter',
|
||||||
|
valueGetter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueGetterParams<MarketMaybeWithData, 'data.bestBidPrice'>) => {
|
||||||
|
return data?.data?.bestBidPrice === undefined
|
||||||
|
? undefined
|
||||||
|
: toBigNum(data?.data?.bestBidPrice, data.decimalPlaces).toNumber();
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestBidPrice'
|
||||||
|
>) =>
|
||||||
|
data?.data?.bestBidPrice === undefined
|
||||||
|
? '-'
|
||||||
|
: addDecimalsFormatNumber(
|
||||||
|
data.data.bestBidPrice,
|
||||||
|
data.decimalPlaces
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Best offer'),
|
||||||
|
field: 'data.bestOfferPrice',
|
||||||
|
type: 'rightAligned',
|
||||||
|
cellRenderer: 'PriceFlashCell',
|
||||||
|
filter: 'agNumberColumnFilter',
|
||||||
|
valueGetter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueGetterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestOfferPrice'
|
||||||
|
>) => {
|
||||||
|
return data?.data?.bestOfferPrice === undefined
|
||||||
|
? undefined
|
||||||
|
: toBigNum(
|
||||||
|
data?.data?.bestOfferPrice,
|
||||||
|
data.decimalPlaces
|
||||||
|
).toNumber();
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestOfferPrice'
|
||||||
|
>) =>
|
||||||
|
data?.data?.bestOfferPrice === undefined
|
||||||
|
? '-'
|
||||||
|
: addDecimalsFormatNumber(
|
||||||
|
data.data.bestOfferPrice,
|
||||||
|
data.decimalPlaces
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Mark price'),
|
||||||
|
field: 'data.markPrice',
|
||||||
|
type: 'rightAligned',
|
||||||
|
cellRenderer: 'PriceFlashCell',
|
||||||
|
filter: 'agNumberColumnFilter',
|
||||||
|
valueGetter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueGetterParams<MarketMaybeWithData, 'data.markPrice'>) => {
|
||||||
|
return data?.data?.markPrice === undefined
|
||||||
|
? undefined
|
||||||
|
: toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber();
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<MarketMaybeWithData, 'data.markPrice'>) =>
|
||||||
|
data?.data?.bestOfferPrice === undefined
|
||||||
|
? '-'
|
||||||
|
: addDecimalsFormatNumber(data.data.markPrice, data.decimalPlaces),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Settlement asset'),
|
||||||
|
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
|
||||||
|
cellRenderer: ({
|
||||||
|
data,
|
||||||
|
}: VegaICellRendererParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
||||||
|
>) => {
|
||||||
|
const value =
|
||||||
|
data?.tradableInstrument.instrument.product.settlementAsset;
|
||||||
|
return value ? (
|
||||||
|
<ButtonLink
|
||||||
|
onClick={(e) => {
|
||||||
|
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{value.symbol}
|
||||||
|
</ButtonLink>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colId: 'market-actions',
|
||||||
|
field: 'id',
|
||||||
|
...COL_DEFS.actions,
|
||||||
|
cellRenderer: ({
|
||||||
|
data,
|
||||||
|
}: VegaICellRendererParams<MarketMaybeWithData>) => {
|
||||||
|
if (!data) return null;
|
||||||
|
return (
|
||||||
|
<MarketTableActions
|
||||||
|
marketId={data.id}
|
||||||
|
assetId={
|
||||||
|
data.tradableInstrument.instrument.product.settlementAsset.id
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[onMarketClick, openAssetDetailsDialog]
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user