import { FeesCell } from '@vegaprotocol/market-info'; import { calcCandleHigh, calcCandleLow, calcCandleVolume, } from '@vegaprotocol/market-list'; import { addDecimalsFormatNumber, PriceCell, signedNumberCssClass, t, } from '@vegaprotocol/react-helpers'; import { Link as UILink, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit'; import isNil from 'lodash/isNil'; import type { CandleClose } from '@vegaprotocol/types'; import type { MarketWithData, MarketWithCandles, } from '@vegaprotocol/market-list'; import { Link } from 'react-router-dom'; import { MarketMarkPrice } from '../market-mark-price'; import { Last24hPriceChange } from '../last-24h-price-change'; import { MarketTradingMode } from '../market-trading-mode'; import { Last24hVolume } from '../last-24h-volume'; type Market = MarketWithData & MarketWithCandles; 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: React.MouseEvent, kind: ColumnKind, value: string ) => void; export const columns = ( market: Market, onSelect: (id: string) => void, onCellClick: OnCellClickHandler, activeMarketId?: string | null ) => { 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 handleKeyPress = ( event: React.KeyboardEvent, id: string ) => { if (event.key === 'Enter' && onSelect) { return onSelect(id); } }; const noUpdate = !activeMarketId || market.id !== activeMarketId; const selectMarketColumns: Column[] = [ { kind: ColumnKind.Market, value: ( handleKeyPress(event, market.id)} onClick={(e) => { e.preventDefault(); onSelect(market.id); }} > {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; }; export const columnsPositionMarkets = ( market: Market, onSelect: (id: string) => void, openVolume?: string, onCellClick?: OnCellClickHandler, activeMarketId?: string | null ) => { 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 handleKeyPress = ( event: React.KeyboardEvent, id: string ) => { if (event.key === 'Enter' && onSelect) { return onSelect(id); } }; const candleVolume = market.candles && calcCandleVolume(market.candles); const noUpdate = !activeMarketId || market.id !== activeMarketId; const selectMarketColumns: Column[] = [ { kind: ColumnKind.Market, value: ( handleKeyPress(event, market.id)} onClick={(e) => { e.preventDefault(); onSelect(market.id); }} > {market.tradableInstrument.instrument.code} ), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.ProductType, value: market.tradableInstrument.instrument.product.__typename, className: `py-2 first:text-left hidden sm:table-cell`, onlyOnDetailed: false, }, { kind: ColumnKind.LastPrice, value: ( ), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.Change24, value: ( ), className: cellClassNames, onlyOnDetailed: false, }, { kind: ColumnKind.Sparkline, value: candlesClose && ( Number(c))} /> ), className: `${cellClassNames} hidden lg:table-cell`, onlyOnDetailed: false, }, { kind: ColumnKind.Asset, value: ( ), className: `${cellClassNames} hidden sm:table-cell`, 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, }, { kind: ColumnKind.Position, value: (

{openVolume && addDecimalsFormatNumber(openVolume, market.positionDecimalPlaces)}

), className: `${cellClassNames} hidden xxl:table-cell font-mono`, onlyOnDetailed: true, }, ]; return selectMarketColumns; };