diff --git a/apps/trading/client-pages/markets/markets.tsx b/apps/trading/client-pages/markets/markets.tsx index ffdf3eb94..0606077d1 100644 --- a/apps/trading/client-pages/markets/markets.tsx +++ b/apps/trading/client-pages/markets/markets.tsx @@ -2,6 +2,7 @@ import { useCallback } from 'react'; import { MarketsContainer } from '@vegaprotocol/market-list'; import { useNavigate } from 'react-router-dom'; import { Links, Routes } from '../../pages/client-router'; +import { MarketNameCell } from '../../components/market-name-cell'; export const Markets = () => { const navigate = useNavigate(); @@ -12,5 +13,10 @@ export const Markets = () => { [navigate] ); - return ; + return ( + + ); }; diff --git a/apps/trading/components/market-name-cell.tsx b/apps/trading/components/market-name-cell.tsx new file mode 100644 index 000000000..f2645c3d2 --- /dev/null +++ b/apps/trading/components/market-name-cell.tsx @@ -0,0 +1,54 @@ +import { useGlobalStore } from '../stores'; +import type { VegaICellRendererParams } from '@vegaprotocol/datagrid'; +import type { MarketMaybeWithData } from '@vegaprotocol/market-list'; +import { useEffect, useRef, useState } from 'react'; +import { ExternalLink, Icon } from '@vegaprotocol/ui-toolkit'; +import { Links, Routes } from '../pages/client-router'; +import { Link } from 'react-router-dom'; + +export const MarketNameCell = ({ + value, + data, +}: VegaICellRendererParams< + MarketMaybeWithData, + 'tradableInstrument.instrument.code' +>) => { + const holdingKey = useGlobalStore((store) => store.holdingKey); + const ref = useRef(null); + const [on, setOn] = useState(false); + const [externalKeyDown, setExternalKeyDown] = useState(false); + + useEffect(() => { + setExternalKeyDown(['Meta', 'Control'].includes(holdingKey) && on); + if (on) { + ref.current?.focus(); + } else { + ref.current?.blur(); + } + }, [on, holdingKey]); + + if (!data) return null; + + const linkContent = externalKeyDown ? ( + e.stopPropagation()} + > + {value} + + ) : ( + {value} + ); + return ( +
setOn(true)} + onMouseLeave={() => setOn(false)} + > + {linkContent} +
+ ); +}; diff --git a/apps/trading/components/select-market/select-market-columns.tsx b/apps/trading/components/select-market/select-market-columns.tsx index 021e06e56..61602da14 100644 --- a/apps/trading/components/select-market/select-market-columns.tsx +++ b/apps/trading/components/select-market/select-market-columns.tsx @@ -1,5 +1,5 @@ import type { ReactNode, RefObject, MouseEvent, KeyboardEvent } from 'react'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { FeesCell } from '@vegaprotocol/market-info'; import { calcCandleHigh, @@ -189,7 +189,6 @@ const MarketExternalLink = ({ const handleOnClick = useCallback( (e: MouseEvent) => { - console.log('test'); e.preventDefault(); onSelect(marketId); }, @@ -430,30 +429,14 @@ export const columnsPositionMarkets = ( .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 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, diff --git a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx index 358c1daa3..0fc2d6fdb 100644 --- a/libs/market-list/src/lib/components/markets-container/market-list-table.tsx +++ b/libs/market-list/src/lib/components/markets-container/market-list-table.tsx @@ -1,3 +1,4 @@ +import type { ReactNode } from 'react'; import { forwardRef } from 'react'; import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils'; import { t } from '@vegaprotocol/i18n'; @@ -17,15 +18,28 @@ import type { AgGridReact } from 'ag-grid-react'; import * as Schema from '@vegaprotocol/types'; import type { MarketMaybeWithData, MarketFieldsFragment } from '../../'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; +import type { MarketNameCellPropsRenderer } from './markets-container'; const { MarketTradingMode, AuctionTrigger } = Schema; export const getRowId = ({ data }: { data: { id: string } }) => data.id; +const DefaultMarketNameCellRenderer = ({ + value, + data, +}: VegaICellRendererParams< + MarketMaybeWithData, + 'tradableInstrument.instrument.code' +>) => { + if (!data) return null; + return {value}; +}; + export const MarketListTable = forwardRef< AgGridReact, - TypedDataAgGrid ->((props, ref) => { + TypedDataAgGrid & MarketNameCellPropsRenderer +>(({ MarketNameCell, ...props }, ref) => { + MarketNameCell = MarketNameCell || DefaultMarketNameCellRenderer; const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); return ( ) => { - if (!data) return null; - return {value}; - }} + cellRenderer="MarketNameCell" /> ) => JSX.Element | null; +} + +interface MarketsContainerProps extends MarketNameCellPropsRenderer { onSelect: (marketId: string) => void; } -export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => { +export const MarketsContainer = ({ + onSelect, + MarketNameCell, +}: MarketsContainerProps) => { const { data, error, loading, reload } = useDataProvider({ dataProvider, skipUpdates: true, @@ -21,16 +36,20 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => { rowData={error ? [] : data} suppressLoadingOverlay suppressNoRowsOverlay - onRowClicked={(rowEvent: RowClickedEvent) => { - const { data, event } = rowEvent; - // filters out clicks on the symbol column because it should display asset details + onCellClicked={(cellEvent: CellClickedEvent) => { + const { data, column } = cellEvent; + const colId = column.getColId(); if ( - (event?.target as HTMLElement).tagName.toUpperCase() === 'BUTTON' + [ + 'tradableInstrument.instrument.code', + 'tradableInstrument.instrument.product.settlementAsset', + ].includes(colId) ) { return; } onSelect((data as MarketMaybeWithData).id); }} + MarketNameCell={MarketNameCell} />