import type { RefObject, MouseEvent } from 'react'; import { FeesCell } from '@vegaprotocol/market-info'; import { calcCandleHigh, calcCandleLow, calcCandleVolume, } from '@vegaprotocol/market-list'; import { addDecimalsFormatNumber } from '@vegaprotocol/utils'; import { t } from '@vegaprotocol/i18n'; import { PriceCell } from '@vegaprotocol/datagrid'; import { Link as UILink, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit'; import isNil from 'lodash/isNil'; import type { CandleClose } from '@vegaprotocol/types'; import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list'; import { Link } from 'react-router-dom'; import { MarketMarkPrice } from '../market-mark-price'; import { Last24hPriceChange, Last24hVolume } from '@vegaprotocol/market-info'; import { MarketTradingMode } from '../market-trading-mode'; import { Links, Routes } from '../../pages/client-router'; const ellipsisClasses = 'whitespace-nowrap overflow-hidden text-ellipsis'; export const cellClassNames = `py-1 first:text-left text-right ${ellipsisClasses}`; const FeesInfo = () => { return ( {t( 'Fees are paid by market takers on aggressive orders only. The fee displayed is made up of:' )} } > {t('Taker fee')} ); }; export enum ColumnKind { Market, LastPrice, Change24, Asset, ProductType, Sparkline, High24, Low24, TradingMode, Volume, Fee, Position, FullName, } export interface Column { kind: ColumnKind; value: string | React.ReactNode; className: string; onlyOnDetailed: boolean; dataTestId?: string; } const headers: Column[] = [ { kind: ColumnKind.Market, value: t('Market'), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.ProductType, value: t('Type'), className: 'py-2 text-left hidden sm:table-cell', onlyOnDetailed: false, }, { kind: ColumnKind.LastPrice, value: t('Last price'), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.Change24, value: t('Change (24h)'), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.Sparkline, value: t(''), className: `${cellClassNames} hidden lg:table-cell`, onlyOnDetailed: false, }, { kind: ColumnKind.Asset, value: t('Settlement asset'), className: `${cellClassNames} hidden sm:table-cell`, onlyOnDetailed: false, }, { kind: ColumnKind.High24, value: t('24h High'), className: `${cellClassNames} hidden xl:table-cell`, onlyOnDetailed: true, }, { kind: ColumnKind.Low24, value: t('24h Low'), className: `${cellClassNames} hidden xl:table-cell`, onlyOnDetailed: true, }, { kind: ColumnKind.Volume, value: t('24h Volume'), className: `${cellClassNames} hidden lg:table-cell`, onlyOnDetailed: true, }, { kind: ColumnKind.TradingMode, value: t('Trading mode'), className: `${cellClassNames} hidden lg:table-cell`, onlyOnDetailed: true, }, { kind: ColumnKind.Fee, value: , className: `${cellClassNames} hidden xl:table-cell`, onlyOnDetailed: true, }, ]; export const columnHeadersPositionMarkets: Column[] = [ ...headers, { kind: ColumnKind.Position, value: t('Position'), className: `${cellClassNames} hidden xxl:table-cell`, onlyOnDetailed: true, }, ]; export const columnHeaders: Column[] = [ ...headers, { kind: ColumnKind.FullName, value: t('Full name'), className: `${cellClassNames} hidden xxl:block`, onlyOnDetailed: true, }, ]; export type OnCellClickHandler = ( e: MouseEvent, kind: ColumnKind, value: string ) => void; export const columns = ( market: MarketMaybeWithDataAndCandles, onSelect: (id: string, metaKey?: boolean) => void, onCellClick: OnCellClickHandler, inViewRoot?: RefObject ) => { const candlesClose = market.candles ?.map((candle) => candle?.close) .filter((c: string | undefined): c is CandleClose => !isNil(c)); const candleLow = market.candles && calcCandleLow(market.candles); const candleHigh = market.candles && calcCandleHigh(market.candles); const candleVolume = market.candles && calcCandleVolume(market.candles); const selectMarketColumns: Column[] = [ { kind: ColumnKind.Market, value: ( { e.preventDefault(); e.stopPropagation(); onSelect(market.id, e.metaKey || e.ctrlKey); }} > {market.tradableInstrument.instrument.code} ), className: `${cellClassNames} max-w-[110px]`, onlyOnDetailed: false, }, { kind: ColumnKind.ProductType, value: market.tradableInstrument.instrument.product.__typename, className: `py-2 text-left hidden sm:table-cell max-w-[50px] ${ellipsisClasses}`, onlyOnDetailed: false, }, { kind: ColumnKind.LastPrice, value: ( ), className: `${cellClassNames} max-w-[100px]`, onlyOnDetailed: false, }, { kind: ColumnKind.Change24, value: ( ), className: `${cellClassNames} max-w-[150px]`, onlyOnDetailed: false, }, { kind: ColumnKind.Sparkline, value: market.candles && ( Number(c)) || []} /> ), className: `${cellClassNames} hidden lg:table-cell max-w-[80px]`, onlyOnDetailed: false && candlesClose, }, { kind: ColumnKind.Asset, value: ( ), dataTestId: 'settlement-asset', className: `${cellClassNames} hidden sm:table-cell max-w-[100px]`, onlyOnDetailed: false, }, { kind: ColumnKind.High24, value: candleHigh ? ( ) : ( '-' ), className: `${cellClassNames} hidden xl:table-cell font-mono`, onlyOnDetailed: true, }, { kind: ColumnKind.Low24, value: candleLow ? ( ) : ( '-' ), className: `${cellClassNames} hidden xl:table-cell font-mono`, onlyOnDetailed: true, }, { kind: ColumnKind.Volume, value: ( ), className: `${cellClassNames} hidden lg:table-cell font-mono`, onlyOnDetailed: true, dataTestId: 'market-volume', }, { kind: ColumnKind.TradingMode, value: ( ), className: `${cellClassNames} hidden lg:table-cell`, onlyOnDetailed: true, dataTestId: 'trading-mode-col', }, { kind: ColumnKind.Fee, value: , className: `${cellClassNames} hidden xl:table-cell font-mono`, onlyOnDetailed: true, dataTestId: 'taker-fee', }, { kind: ColumnKind.FullName, value: market.tradableInstrument.instrument.name, className: `${cellClassNames} hidden xxl:block`, onlyOnDetailed: true, dataTestId: 'market-name', }, ]; return selectMarketColumns; };