diff --git a/apps/trading/client-pages/markets/use-column-defs.tsx b/apps/trading/client-pages/markets/use-column-defs.tsx index 6b3cfd0e3..6f9156c9f 100644 --- a/apps/trading/client-pages/markets/use-column-defs.tsx +++ b/apps/trading/client-pages/markets/use-column-defs.tsx @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import type { ColDef } from 'ag-grid-community'; +import type { ColDef, ValueFormatterParams } from 'ag-grid-community'; import { t } from '@vegaprotocol/i18n'; import type { VegaICellRendererParams, @@ -7,19 +7,19 @@ import type { VegaValueGetterParams, } from '@vegaprotocol/datagrid'; import { COL_DEFS, SetFilter } from '@vegaprotocol/datagrid'; -import { - MarketTradingMode, - AuctionTrigger, - MarketTradingModeMapping, - AuctionTriggerMapping, - MarketStateMapping, -} from '@vegaprotocol/types'; +import * as Schema from '@vegaprotocol/types'; import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils'; -import { ButtonLink } from '@vegaprotocol/ui-toolkit'; +import { ButtonLink, Tooltip } from '@vegaprotocol/ui-toolkit'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; +import type { + MarketMaybeWithData, + MarketMaybeWithDataAndCandles, +} from '@vegaprotocol/markets'; import { MarketActionsDropdown } from './market-table-actions'; +import { calcCandleVolume } from '@vegaprotocol/markets'; import { MarketCodeCell } from './market-code-cell'; -import type { MarketMaybeWithData } from '@vegaprotocol/markets'; + +const { MarketTradingMode, AuctionTrigger } = Schema; export const useColumnDefs = () => { const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); @@ -28,6 +28,7 @@ export const useColumnDefs = () => { { headerName: t('Market'), field: 'tradableInstrument.instrument.code', + flex: 2, cellRenderer: ({ value, data, @@ -46,25 +47,44 @@ export const useColumnDefs = () => { /> ), }, + { + headerName: t('Description'), + field: 'tradableInstrument.instrument.name', + flex: 2, + }, { headerName: t('Trading mode'), field: 'tradingMode', - valueFormatter: ({ + cellRenderer: ({ data, - }: VegaValueFormatterParams) => { + }: VegaICellRendererParams) => { if (!data?.data) return '-'; const { trigger, marketTradingMode } = data.data; - return marketTradingMode === - MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && + + const withTriggerInfo = + marketTradingMode === + MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && trigger && - trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED - ? `${MarketTradingModeMapping[marketTradingMode]} - - ${AuctionTriggerMapping[trigger]}` - : MarketTradingModeMapping[marketTradingMode]; + trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED; + + if (withTriggerInfo) { + return ( + + + {Schema.MarketTradingModeMapping[marketTradingMode]} + + + ); + } + + return Schema.MarketTradingModeMapping[marketTradingMode]; }, filter: SetFilter, filterParams: { - set: MarketTradingModeMapping, + set: Schema.MarketTradingModeMapping, }, }, { @@ -73,64 +93,13 @@ export const useColumnDefs = () => { valueFormatter: ({ data, }: VegaValueFormatterParams) => { - return data?.state ? MarketStateMapping[data.state] : '-'; + return data?.state ? Schema.MarketStateMapping[data.state] : '-'; }, filter: SetFilter, filterParams: { - set: MarketStateMapping, + set: Schema.MarketStateMapping, }, }, - { - headerName: t('Best bid'), - field: 'data.bestBidPrice', - type: 'rightAligned', - cellRenderer: 'PriceFlashCell', - filter: 'agNumberColumnFilter', - valueGetter: ({ data }: VegaValueGetterParams) => { - 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) => { - 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', @@ -149,6 +118,30 @@ export const useColumnDefs = () => { ? '-' : addDecimalsFormatNumber(data.data.markPrice, data.decimalPlaces), }, + { + headerName: t('24h volume'), + type: 'rightAligned', + field: 'data.candles', + valueGetter: ({ + data, + }: VegaValueGetterParams) => { + if (!data) return 0; + const candles = data?.candles; + const vol = candles ? calcCandleVolume(candles) : '0'; + return Number(vol); + }, + valueFormatter: ({ + data, + }: ValueFormatterParams) => { + const candles = data?.candles; + const vol = candles ? calcCandleVolume(candles) : '0'; + const volume = + data && vol && vol !== '0' + ? addDecimalsFormatNumber(vol, data.positionDecimalPlaces) + : '0.00'; + return volume; + }, + }, { headerName: t('Settlement asset'), field: 'tradableInstrument.instrument.product.settlementAsset.symbol', @@ -173,6 +166,40 @@ export const useColumnDefs = () => { ); }, }, + { + headerName: t('Spread'), + field: 'data.bestBidPrice', + type: 'rightAligned', + filter: 'agNumberColumnFilter', + cellRenderer: 'PriceFlashCell', + valueGetter: ({ data }: VegaValueGetterParams) => { + if (!data || !data.data?.bestOfferPrice || !data.data?.bestBidPrice) { + return undefined; + } + + const offer = toBigNum(data.data.bestOfferPrice, data.decimalPlaces); + const bid = toBigNum(data.data.bestBidPrice, data.decimalPlaces); + + const spread = offer.minus(bid).toNumber(); + + // The calculation above can result in '-0' being rendered after formatting + // so return Math.abs to remove it and just render '0' + if (spread === 0) { + return Math.abs(spread); + } + + return spread; + }, + valueFormatter: ({ + value, + }: VegaValueFormatterParams< + MarketMaybeWithData, + 'data.bestBidPrice' + >) => { + if (!value) return '-'; + return value.toString(); + }, + }, { colId: 'market-actions', field: 'id', diff --git a/libs/markets/src/lib/components/markets-container/use-column-defs.tsx b/libs/markets/src/lib/components/markets-container/use-column-defs.tsx deleted file mode 100644 index a0511303c..000000000 --- a/libs/markets/src/lib/components/markets-container/use-column-defs.tsx +++ /dev/null @@ -1,231 +0,0 @@ -import { useMemo } from 'react'; -import type { ColDef, ValueFormatterParams } from 'ag-grid-community'; -import compact from 'lodash/compact'; -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, Tooltip } from '@vegaprotocol/ui-toolkit'; -import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; -import type { - MarketMaybeWithData, - MarketMaybeWithDataAndCandles, -} from '../../markets-provider'; -import { MarketActionsDropdown } from './market-table-actions'; -import { calcCandleVolume } from '../../market-utils'; - -interface Props { - onMarketClick: (marketId: string, metaKey?: boolean) => void; -} - -const { MarketTradingMode, AuctionTrigger } = Schema; - -export const useColumnDefs = ({ onMarketClick }: Props) => { - const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); - return useMemo( - () => - compact([ - { - headerName: t('Market'), - field: 'tradableInstrument.instrument.code', - cellRenderer: 'MarketName', - cellRendererParams: { onMarketClick }, - flex: 2, - }, - { - headerName: t('Description'), - field: 'tradableInstrument.instrument.name', - flex: 2, - }, - { - headerName: t('Trading mode'), - field: 'tradingMode', - cellRenderer: ({ - data, - }: VegaICellRendererParams) => { - if (!data?.data) return '-'; - const { trigger, marketTradingMode } = data.data; - - const withTriggerInfo = - marketTradingMode === - MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && - trigger && - trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED; - - if (withTriggerInfo) { - return ( - - - {Schema.MarketTradingModeMapping[marketTradingMode]} - - - ); - } - - return Schema.MarketTradingModeMapping[marketTradingMode]; - }, - filter: SetFilter, - filterParams: { - set: Schema.MarketTradingModeMapping, - }, - }, - { - headerName: t('Status'), - field: 'state', - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => { - return data?.state ? Schema.MarketStateMapping[data.state] : '-'; - }, - filter: SetFilter, - filterParams: { - set: Schema.MarketStateMapping, - }, - }, - { - headerName: t('Mark price'), - field: 'data.markPrice', - type: 'rightAligned', - cellRenderer: 'PriceFlashCell', - filter: 'agNumberColumnFilter', - valueGetter: ({ - data, - }: VegaValueGetterParams) => { - return data?.data?.markPrice === undefined - ? undefined - : toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber(); - }, - valueFormatter: ({ - data, - }: VegaValueFormatterParams) => - data?.data?.bestOfferPrice === undefined - ? '-' - : addDecimalsFormatNumber( - data.data.markPrice, - data.decimalPlaces - ), - }, - { - headerName: t('24h volume'), - type: 'rightAligned', - field: 'data.candles', - valueGetter: ({ - data, - }: VegaValueGetterParams) => { - if (!data) return 0; - const candles = data?.candles; - const vol = candles ? calcCandleVolume(candles) : '0'; - return Number(vol); - }, - valueFormatter: ({ - data, - }: ValueFormatterParams< - MarketMaybeWithDataAndCandles, - 'candles' - >) => { - const candles = data?.candles; - const vol = candles ? calcCandleVolume(candles) : '0'; - const volume = - data && vol && vol !== '0' - ? addDecimalsFormatNumber(vol, data.positionDecimalPlaces) - : '0.00'; - return volume; - }, - }, - { - 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 ? ( - { - openAssetDetailsDialog(value.id, e.target as HTMLElement); - }} - > - {value.symbol} - - ) : ( - '' - ); - }, - }, - { - headerName: t('Spread'), - field: 'data.bestBidPrice', - type: 'rightAligned', - filter: 'agNumberColumnFilter', - cellRenderer: 'PriceFlashCell', - valueGetter: ({ - data, - }: VegaValueGetterParams) => { - if ( - !data || - !data.data?.bestOfferPrice || - !data.data?.bestBidPrice - ) { - return undefined; - } - - const offer = toBigNum( - data.data.bestOfferPrice, - data.decimalPlaces - ); - const bid = toBigNum(data.data.bestBidPrice, data.decimalPlaces); - - const spread = offer.minus(bid).toNumber(); - - // The calculation above can result in '-0' being rendered after formatting - // so return Math.abs to remove it and just render '0' - if (spread === 0) { - return Math.abs(spread); - } - - return spread; - }, - valueFormatter: ({ - value, - }: VegaValueFormatterParams< - MarketMaybeWithData, - 'data.bestBidPrice' - >) => { - if (!value) return '-'; - return value.toString(); - }, - }, - { - colId: 'market-actions', - field: 'id', - ...COL_DEFS.actions, - cellRenderer: ({ - data, - }: VegaICellRendererParams) => { - if (!data) return null; - return ( - - ); - }, - }, - ]), - [onMarketClick, openAssetDetailsDialog] - ); -};