chore(trading): add "holding CMD + click" external link (#3273)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
2bfc3abd15
commit
82e5128ba1
@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { addDecimalsFormatNumber, titlefy } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
@ -13,6 +13,7 @@ import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
import { TradeGrid, TradePanels } from './trade-grid';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||
return markPrice && decimalPlaces
|
||||
@ -66,14 +67,7 @@ export const MarketPage = () => {
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const lastMarketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
const onSelect = useCallback(
|
||||
(id: string) => {
|
||||
if (id && id !== marketId) {
|
||||
navigate(Links[Routes.MARKET](id));
|
||||
}
|
||||
},
|
||||
[marketId, navigate]
|
||||
);
|
||||
const onSelect = useMarketClickHandler();
|
||||
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider: marketProvider,
|
||||
|
@ -8,7 +8,7 @@ import { TradesContainer } from '@vegaprotocol/trades';
|
||||
import { LayoutPriority } from 'allotment';
|
||||
import classNames from 'classnames';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { memo, useCallback, useState } from 'react';
|
||||
import { memo, useState } from 'react';
|
||||
import type { ReactNode, ComponentProps } from 'react';
|
||||
import { DepthChartContainer } from '@vegaprotocol/market-depth';
|
||||
import { CandlesChartContainer } from '@vegaprotocol/candles-chart';
|
||||
@ -27,9 +27,9 @@ import { TradeMarketHeader } from './trade-market-header';
|
||||
import { NO_MARKET } from './constants';
|
||||
import { LiquidityContainer } from '../liquidity/liquidity';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import type { PinnedAsset } from '@vegaprotocol/accounts';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
type MarketDependantView =
|
||||
| typeof CandlesChartContainer
|
||||
@ -66,7 +66,7 @@ type TradingView = keyof typeof TradingViews;
|
||||
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}
|
||||
|
||||
@ -78,15 +78,7 @@ interface BottomPanelProps {
|
||||
const MarketBottomPanel = memo(
|
||||
({ marketId, pinnedAsset }: BottomPanelProps) => {
|
||||
const { screenSize } = useScreenDimensions();
|
||||
const navigate = useNavigate();
|
||||
const onMarketClick = useCallback(
|
||||
(marketId: string) => {
|
||||
navigate(Links[Routes.MARKET](marketId), {
|
||||
replace: true,
|
||||
});
|
||||
},
|
||||
[navigate]
|
||||
);
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
|
||||
return 'xxxl' === screenSize ? (
|
||||
<ResizableGrid proportionalLayout minSize={200}>
|
||||
@ -189,7 +181,7 @@ const MainGrid = memo(
|
||||
pinnedAsset,
|
||||
}: {
|
||||
marketId: string;
|
||||
onSelect?: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
@ -230,12 +222,7 @@ const MainGrid = memo(
|
||||
/>
|
||||
</Tab>
|
||||
<Tab id="info" name={t('Info')}>
|
||||
<TradingViews.Info
|
||||
marketId={marketId}
|
||||
onSelect={(id: string) => {
|
||||
onSelect?.(id);
|
||||
}}
|
||||
/>
|
||||
<TradingViews.Info marketId={marketId} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
@ -304,7 +291,7 @@ const TradeGridChild = ({ children }: TradeGridChildProps) => {
|
||||
|
||||
interface TradePanelsProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
@ -320,7 +307,7 @@ export const TradePanels = ({
|
||||
const renderView = () => {
|
||||
const Component = memo<{
|
||||
marketId: string;
|
||||
onSelect: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onClickCollateral: () => void;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
|
@ -22,7 +22,7 @@ import { MarketState as State } from '@vegaprotocol/types';
|
||||
|
||||
interface TradeMarketHeaderProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
}
|
||||
|
||||
export const TradeMarketHeader = ({
|
||||
@ -91,7 +91,6 @@ export const TradeMarketHeader = ({
|
||||
</HeaderStat>
|
||||
<HeaderStatMarketTradingMode
|
||||
marketId={market?.id}
|
||||
onSelect={onSelect}
|
||||
initialTradingMode={market?.tradingMode}
|
||||
/>
|
||||
<MarketState market={market} />
|
||||
|
@ -1,16 +1,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 { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const Markets = () => {
|
||||
const navigate = useNavigate();
|
||||
const handleOnSelect = useCallback(
|
||||
(marketId: string) => {
|
||||
navigate(Links[Routes.MARKET](marketId));
|
||||
},
|
||||
[navigate]
|
||||
);
|
||||
|
||||
const handleOnSelect = useMarketClickHandler();
|
||||
return <MarketsContainer onSelect={handleOnSelect} />;
|
||||
};
|
||||
|
@ -19,25 +19,18 @@ import { usePageTitleStore } from '../../stores';
|
||||
import { LedgerContainer } from '@vegaprotocol/ledger';
|
||||
import { AccountsContainer } from '../../components/accounts-container';
|
||||
import { AccountHistoryContainer } from './account-history-container';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const Portfolio = () => {
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
updateTitle(titlefy([t('Portfolio')]));
|
||||
}, [updateTitle]);
|
||||
|
||||
const onMarketClick = (marketId: string) => {
|
||||
navigate(Links[Routes.MARKET](marketId), {
|
||||
replace: true,
|
||||
});
|
||||
};
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
|
||||
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
||||
return (
|
||||
|
@ -25,7 +25,7 @@ const getTradingModeLabel = (
|
||||
|
||||
interface HeaderStatMarketTradingModeProps {
|
||||
marketId?: string;
|
||||
onSelect?: (marketId: string) => void;
|
||||
onSelect?: (marketId: string, metaKey?: boolean) => void;
|
||||
initialTradingMode?: Schema.MarketTradingMode;
|
||||
initialTrigger?: Schema.AuctionTrigger;
|
||||
}
|
||||
@ -66,7 +66,9 @@ export const MarketTradingMode = ({
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
description={<TradingModeTooltip marketId={marketId} skip={!inView} />}
|
||||
description={
|
||||
<TradingModeTooltip marketId={marketId} skip={!inView} skipGrid />
|
||||
}
|
||||
>
|
||||
<span ref={ref}>
|
||||
{getTradingModeLabel(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { RefObject } from 'react';
|
||||
import type { RefObject, MouseEvent } from 'react';
|
||||
import { FeesCell } from '@vegaprotocol/market-info';
|
||||
import {
|
||||
calcCandleHigh,
|
||||
@ -157,14 +157,14 @@ export const columnHeaders: Column[] = [
|
||||
];
|
||||
|
||||
export type OnCellClickHandler = (
|
||||
e: React.MouseEvent,
|
||||
e: MouseEvent,
|
||||
kind: ColumnKind,
|
||||
value: string
|
||||
) => void;
|
||||
|
||||
export const columns = (
|
||||
market: MarketMaybeWithDataAndCandles,
|
||||
onSelect: (id: string) => void,
|
||||
onSelect: (id: string, metaKey?: boolean) => void,
|
||||
onCellClick: OnCellClickHandler,
|
||||
inViewRoot?: RefObject<HTMLElement>
|
||||
) => {
|
||||
@ -174,14 +174,7 @@ export const columns = (
|
||||
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<HTMLAnchorElement>,
|
||||
id: string
|
||||
) => {
|
||||
if (event.key === 'Enter' && onSelect) {
|
||||
return onSelect(id);
|
||||
}
|
||||
};
|
||||
|
||||
const selectMarketColumns: Column[] = [
|
||||
{
|
||||
kind: ColumnKind.Market,
|
||||
@ -189,10 +182,10 @@ export const columns = (
|
||||
<Link
|
||||
to={Links[Routes.MARKET](market.id)}
|
||||
data-testid={`market-link-${market.id}`}
|
||||
onKeyPress={(event) => handleKeyPress(event, market.id)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onSelect(market.id);
|
||||
e.stopPropagation();
|
||||
onSelect(market.id, e.metaKey);
|
||||
}}
|
||||
>
|
||||
<UILink>{market.tradableInstrument.instrument.code}</UILink>
|
||||
@ -352,7 +345,7 @@ export const columns = (
|
||||
|
||||
export const columnsPositionMarkets = (
|
||||
market: MarketMaybeWithDataAndCandles,
|
||||
onSelect: (id: string) => void,
|
||||
onSelect: (id: string, metaKey?: boolean) => void,
|
||||
inViewRoot?: RefObject<HTMLElement>,
|
||||
openVolume?: string,
|
||||
onCellClick?: OnCellClickHandler
|
||||
@ -362,14 +355,6 @@ 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<HTMLSpanElement>,
|
||||
id: string
|
||||
) => {
|
||||
if (event.key === 'Enter' && onSelect) {
|
||||
return onSelect(id);
|
||||
}
|
||||
};
|
||||
const candleVolume = market.candles && calcCandleVolume(market.candles);
|
||||
const selectMarketColumns: Column[] = [
|
||||
{
|
||||
@ -378,10 +363,10 @@ export const columnsPositionMarkets = (
|
||||
<Link
|
||||
to={Links[Routes.MARKET](market.id)}
|
||||
data-testid={`market-link-${market.id}`}
|
||||
onKeyPress={(event) => handleKeyPress(event, market.id)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onSelect(market.id);
|
||||
e.stopPropagation();
|
||||
onSelect(market.id, e.metaKey);
|
||||
}}
|
||||
>
|
||||
<UILink>{market.tradableInstrument.instrument.code}</UILink>
|
||||
|
@ -37,14 +37,14 @@ export const SelectMarketTableRow = ({
|
||||
}: {
|
||||
detailed?: boolean;
|
||||
columns: Column[];
|
||||
onSelect: (id: string) => void;
|
||||
onSelect: (id: string, metaKey?: boolean) => void;
|
||||
marketId: string;
|
||||
}) => {
|
||||
return (
|
||||
<tr
|
||||
className={`hover:bg-neutral-200 dark:hover:bg-neutral-700 cursor-pointer relative h-[34px]`}
|
||||
onClick={() => {
|
||||
onSelect(marketId);
|
||||
onClick={(ev) => {
|
||||
onSelect(marketId, ev.metaKey);
|
||||
}}
|
||||
data-testid={`market-link-${marketId}`}
|
||||
>
|
||||
|
@ -178,6 +178,6 @@ describe('SelectMarket', () => {
|
||||
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
||||
expect(container).toHaveTextContent(/1,000/); // volume
|
||||
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||
expect(onSelect).toHaveBeenCalledWith('1');
|
||||
expect(onSelect).toHaveBeenCalledWith('1', false);
|
||||
});
|
||||
});
|
||||
|
@ -40,7 +40,7 @@ export const SelectAllMarketsTableBody = ({
|
||||
markets?: MarketMaybeWithDataAndCandles[] | null;
|
||||
positions?: PositionFieldsFragment[];
|
||||
title?: string;
|
||||
onSelect: (id: string) => void;
|
||||
onSelect: (id: string, metaKey?: boolean) => void;
|
||||
onCellClick: OnCellClickHandler;
|
||||
headers?: Column[];
|
||||
tableColumns?: (
|
||||
@ -95,7 +95,7 @@ export const SelectMarketPopover = ({
|
||||
}: {
|
||||
marketCode: string;
|
||||
marketName: string;
|
||||
onSelect: (id: string) => void;
|
||||
onSelect: (id: string, metaKey?: boolean) => void;
|
||||
onCellClick: OnCellClickHandler;
|
||||
}) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
@ -116,8 +116,8 @@ export const SelectMarketPopover = ({
|
||||
skip: !pubKey,
|
||||
});
|
||||
const onSelectMarket = useCallback(
|
||||
(marketId: string) => {
|
||||
onSelect(marketId);
|
||||
(marketId: string, metaKey?: boolean) => {
|
||||
onSelect(marketId, metaKey);
|
||||
setOpen(false);
|
||||
},
|
||||
[onSelect]
|
||||
|
21
apps/trading/lib/hooks/use-market-click-handler.ts
Normal file
21
apps/trading/lib/hooks/use-market-click-handler.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { useNavigate, useParams, useLocation } from 'react-router-dom';
|
||||
import { useCallback } from 'react';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
|
||||
export const useMarketClickHandler = (replace = false) => {
|
||||
const navigate = useNavigate();
|
||||
const { marketId } = useParams();
|
||||
const { pathname } = useLocation();
|
||||
const isMarketPage = pathname.match(/^\/markets\/(.+)/);
|
||||
return useCallback(
|
||||
(selectedId: string, metaKey?: boolean) => {
|
||||
const link = Links[Routes.MARKET](selectedId);
|
||||
if (metaKey) {
|
||||
window.open(`/#${link}`, '_blank');
|
||||
} else if (selectedId !== marketId || !isMarketPage) {
|
||||
navigate(link, { replace });
|
||||
}
|
||||
},
|
||||
[navigate, marketId, replace, isMarketPage]
|
||||
);
|
||||
};
|
@ -1,3 +1,5 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import Head from 'next/head';
|
||||
import type { AppProps } from 'next/app';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
@ -23,14 +25,12 @@ import {
|
||||
import './styles.css';
|
||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
||||
import { Footer } from '../components/footer';
|
||||
import { useMemo, useState } from 'react';
|
||||
import DialogsContainer from './dialogs-container';
|
||||
import ToastsManager from './toasts-manager';
|
||||
import { HashRouter, useLocation, useSearchParams } from 'react-router-dom';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { ViewingBanner } from '../components/viewing-banner';
|
||||
import { Banner } from '../components/banner';
|
||||
import classNames from 'classnames';
|
||||
import { AppLoader, DynamicLoader } from '../components/app-loader';
|
||||
import { Navbar } from '../components/navbar';
|
||||
|
||||
@ -57,7 +57,7 @@ const Title = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const TransactionsHandler = () => {
|
||||
const InitializeHandlers = () => {
|
||||
useVegaTransactionManager();
|
||||
useVegaTransactionUpdater();
|
||||
useEthTransactionManager();
|
||||
@ -93,7 +93,7 @@ function AppBody({ Component }: AppProps) {
|
||||
</div>
|
||||
<DialogsContainer />
|
||||
<ToastsManager />
|
||||
<TransactionsHandler />
|
||||
<InitializeHandlers />
|
||||
<MaybeConnectEagerly />
|
||||
</div>
|
||||
);
|
||||
|
@ -9,6 +9,7 @@ export * from './lib/cells/price-change-cell';
|
||||
export * from './lib/cells/price-flash-cell';
|
||||
export * from './lib/cells/vol-cell';
|
||||
export * from './lib/cells/centered-grid-cell';
|
||||
export * from './lib/cells/market-name-cell';
|
||||
|
||||
export * from './lib/filters/date-range-filter';
|
||||
export * from './lib/filters/set-filter';
|
||||
|
35
libs/datagrid/src/lib/cells/market-name-cell.tsx
Normal file
35
libs/datagrid/src/lib/cells/market-name-cell.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import type { MouseEvent } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import get from 'lodash/get';
|
||||
|
||||
interface MarketNameCellProps {
|
||||
value?: string;
|
||||
data?: { id?: string; marketId?: string; market?: { id: string } };
|
||||
idPath?: string;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
}
|
||||
|
||||
export const MarketNameCell = ({
|
||||
value,
|
||||
data,
|
||||
idPath,
|
||||
onMarketClick,
|
||||
}: MarketNameCellProps) => {
|
||||
const id = data ? get(data, idPath ?? 'id', 'all') : '';
|
||||
const handleOnClick = useCallback(
|
||||
(ev: MouseEvent<HTMLButtonElement>) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
if (onMarketClick) {
|
||||
onMarketClick(id, ev.metaKey);
|
||||
}
|
||||
},
|
||||
[id, onMarketClick]
|
||||
);
|
||||
if (!data) return null;
|
||||
return (
|
||||
<button onClick={handleOnClick} tabIndex={0}>
|
||||
{value}
|
||||
</button>
|
||||
);
|
||||
};
|
@ -26,7 +26,7 @@ export const compileGridData = (
|
||||
| 'targetStake'
|
||||
| 'trigger'
|
||||
> | null,
|
||||
onSelect?: (id: string) => void
|
||||
onSelect?: (id: string, metaKey?: boolean) => void
|
||||
): { label: ReactNode; value?: ReactNode }[] => {
|
||||
const grid: SimpleGridProps['grid'] = [];
|
||||
const isLiquidityMonitoringAuction =
|
||||
@ -78,7 +78,7 @@ export const compileGridData = (
|
||||
label: (
|
||||
<Link
|
||||
to={`/liquidity/${market.id}`}
|
||||
onClick={() => onSelect && onSelect(market.id)}
|
||||
onClick={(ev) => onSelect && onSelect(market.id, ev.metaKey)}
|
||||
>
|
||||
<UILink>{t('Current liquidity')}</UILink>
|
||||
</Link>
|
||||
|
@ -12,14 +12,16 @@ import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list';
|
||||
|
||||
type TradingModeTooltipProps = {
|
||||
marketId?: string;
|
||||
onSelect?: (marketId: string) => void;
|
||||
onSelect?: (marketId: string, metaKey?: boolean) => void;
|
||||
skip?: boolean;
|
||||
skipGrid?: boolean;
|
||||
};
|
||||
|
||||
export const TradingModeTooltip = ({
|
||||
marketId,
|
||||
onSelect,
|
||||
skip,
|
||||
skipGrid,
|
||||
}: TradingModeTooltipProps) => {
|
||||
const { VEGA_DOCS_URL } = useEnvironment();
|
||||
const { data: market } = useMarket(marketId);
|
||||
@ -42,7 +44,7 @@ export const TradingModeTooltip = ({
|
||||
);
|
||||
|
||||
const compiledGrid =
|
||||
onSelect && compileGridData(market, marketData, onSelect);
|
||||
!skipGrid && compileGridData(market, marketData, onSelect);
|
||||
|
||||
switch (marketTradingMode) {
|
||||
case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: {
|
||||
@ -103,6 +105,7 @@ export const TradingModeTooltip = ({
|
||||
{VEGA_DOCS_URL && (
|
||||
<ExternalLink
|
||||
href={createDocsLinks(VEGA_DOCS_URL).AUCTION_TYPE_OPENING}
|
||||
className="ml-1"
|
||||
>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
@ -129,6 +132,7 @@ export const TradingModeTooltip = ({
|
||||
createDocsLinks(VEGA_DOCS_URL)
|
||||
.AUCTION_TYPE_LIQUIDITY_MONITORING
|
||||
}
|
||||
className="ml-1"
|
||||
>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
@ -153,6 +157,7 @@ export const TradingModeTooltip = ({
|
||||
createDocsLinks(VEGA_DOCS_URL)
|
||||
.AUCTION_TYPE_LIQUIDITY_MONITORING
|
||||
}
|
||||
className="ml-1"
|
||||
>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
@ -175,6 +180,7 @@ export const TradingModeTooltip = ({
|
||||
createDocsLinks(VEGA_DOCS_URL)
|
||||
.AUCTION_TYPE_PRICE_MONITORING
|
||||
}
|
||||
className="ml-1"
|
||||
>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>
|
||||
|
@ -8,7 +8,7 @@ export const FillsContainer = ({
|
||||
onMarketClick,
|
||||
}: {
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
}) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { useBottomPlaceholder } from '@vegaprotocol/react-helpers';
|
||||
interface FillsManagerProps {
|
||||
partyId: string;
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
}
|
||||
|
||||
export const FillsManager = ({
|
||||
|
@ -7,6 +7,7 @@ import type { Trade } from './fills-data-provider';
|
||||
|
||||
import { FillsTable, getFeesBreakdown } from './fills-table';
|
||||
import { generateFill } from './test-helpers';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
describe('FillsTable', () => {
|
||||
let defaultFill: PartialDeep<Trade>;
|
||||
@ -36,7 +37,11 @@ describe('FillsTable', () => {
|
||||
|
||||
it('correct columns are rendered', async () => {
|
||||
await act(async () => {
|
||||
render(<FillsTable partyId="party-id" rowData={[generateFill()]} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId="party-id" rowData={[generateFill()]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
@ -67,7 +72,11 @@ describe('FillsTable', () => {
|
||||
liquidityFee: '2',
|
||||
},
|
||||
});
|
||||
render(<FillsTable partyId={partyId} rowData={[{ ...buyerFill }]} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId={partyId} rowData={[{ ...buyerFill }]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const expectedValues = [
|
||||
buyerFill.market?.tradableInstrument.instrument.name || '',
|
||||
@ -100,7 +109,11 @@ describe('FillsTable', () => {
|
||||
liquidityFee: '1',
|
||||
},
|
||||
});
|
||||
render(<FillsTable partyId={partyId} rowData={[buyerFill]} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId={partyId} rowData={[buyerFill]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const expectedValues = [
|
||||
@ -129,7 +142,9 @@ describe('FillsTable', () => {
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
});
|
||||
const { rerender } = render(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId={partyId} rowData={[takerFill]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
expect(
|
||||
screen
|
||||
@ -143,7 +158,11 @@ describe('FillsTable', () => {
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_BUY,
|
||||
});
|
||||
rerender(<FillsTable partyId={partyId} rowData={[makerFill]} />);
|
||||
rerender(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId={partyId} rowData={[makerFill]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen
|
||||
@ -160,7 +179,11 @@ describe('FillsTable', () => {
|
||||
},
|
||||
aggressor: Schema.Side.SIDE_SELL,
|
||||
});
|
||||
render(<FillsTable partyId={partyId} rowData={[takerFill]} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<FillsTable partyId={partyId} rowData={[takerFill]} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
const feeCell = screen
|
||||
.getAllByRole('gridcell')
|
||||
|
@ -14,16 +14,13 @@ import {
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { AgGridColumn } from 'ag-grid-react';
|
||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
AgGridDynamic as AgGrid,
|
||||
positiveClassNames,
|
||||
negativeClassNames,
|
||||
MarketNameCell,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/datagrid';
|
||||
import { forwardRef } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { Trade } from './fills-data-provider';
|
||||
@ -34,7 +31,7 @@ const MAKER = 'MAKER';
|
||||
|
||||
export type Props = (AgGridReactProps | AgReactUiProps) & {
|
||||
partyId: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
};
|
||||
|
||||
export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
@ -48,30 +45,14 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
getRowId={({ data }) => data?.id}
|
||||
tooltipShowDelay={0}
|
||||
tooltipHideDelay={2000}
|
||||
components={{ MarketNameCell }}
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market')}
|
||||
field="market.tradableInstrument.instrument.name"
|
||||
cellRenderer={({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<
|
||||
Trade,
|
||||
'market.tradableInstrument.instrument.name'
|
||||
>) =>
|
||||
onMarketClick ? (
|
||||
<Link
|
||||
onClick={() =>
|
||||
data?.market?.id && onMarketClick(data?.market?.id)
|
||||
}
|
||||
>
|
||||
{value}
|
||||
</Link>
|
||||
) : (
|
||||
value
|
||||
)
|
||||
}
|
||||
cellRenderer="MarketNameCell"
|
||||
cellRendererParams={{ idPath: 'market.id', onMarketClick }}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Size')}
|
||||
|
@ -39,12 +39,12 @@ import {
|
||||
|
||||
export interface InfoProps {
|
||||
market: MarketInfoWithDataAndCandles;
|
||||
onSelect: (id: string) => void;
|
||||
onSelect?: (id: string, metaKey?: boolean) => void;
|
||||
}
|
||||
|
||||
export interface MarketInfoContainerProps {
|
||||
marketId: string;
|
||||
onSelect?: (id: string) => void;
|
||||
onSelect?: (id: string, metaKey?: boolean) => void;
|
||||
}
|
||||
export const MarketInfoContainer = ({
|
||||
marketId,
|
||||
@ -73,7 +73,7 @@ export const MarketInfoContainer = ({
|
||||
<AsyncRenderer data={data} loading={loading} error={error} reload={reload}>
|
||||
{data ? (
|
||||
<TinyScroll className="h-full overflow-auto">
|
||||
<Info market={data} onSelect={(id) => onSelect?.(id)} />
|
||||
<Info market={data} onSelect={onSelect} />
|
||||
</TinyScroll>
|
||||
) : (
|
||||
<Splash>
|
||||
@ -169,7 +169,7 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
<LiquidityInfoPanel market={market}>
|
||||
<Link
|
||||
to={`/liquidity/${market.id}`}
|
||||
onClick={() => onSelect(market.id)}
|
||||
onClick={(ev) => onSelect?.(market.id, ev.metaKey)}
|
||||
data-testid="view-liquidity-link"
|
||||
>
|
||||
<UILink>{t('View liquidity provision table')}</UILink>
|
||||
|
@ -10,6 +10,7 @@ import type {
|
||||
import {
|
||||
AgGridDynamic as AgGrid,
|
||||
PriceFlashCell,
|
||||
MarketNameCell,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { AgGridColumn } from 'ag-grid-react';
|
||||
@ -24,8 +25,10 @@ export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
||||
|
||||
export const MarketListTable = forwardRef<
|
||||
AgGridReact,
|
||||
TypedDataAgGrid<MarketMaybeWithData>
|
||||
>((props, ref) => {
|
||||
TypedDataAgGrid<MarketMaybeWithData> & {
|
||||
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
||||
}
|
||||
>(({ onMarketClick, ...props }, ref) => {
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
return (
|
||||
<AgGrid
|
||||
@ -41,22 +44,14 @@ export const MarketListTable = forwardRef<
|
||||
filterParams: { buttons: ['reset'] },
|
||||
}}
|
||||
suppressCellFocus={true}
|
||||
components={{ PriceFlashCell }}
|
||||
components={{ PriceFlashCell, MarketNameCell }}
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market')}
|
||||
field="tradableInstrument.instrument.code"
|
||||
cellRenderer={({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<
|
||||
MarketMaybeWithData,
|
||||
'tradableInstrument.instrument.code'
|
||||
>) => {
|
||||
if (!data) return null;
|
||||
return <span data-testid={`market-${data.id}`}>{value}</span>;
|
||||
}}
|
||||
cellRenderer="MarketNameCell"
|
||||
cellRendererParams={{ onMarketClick }}
|
||||
/>
|
||||
<AgGridColumn
|
||||
headerName={t('Description')}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import type { MouseEvent } from 'react';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { MarketListTable } from './market-list-table';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type { RowClickedEvent } from 'ag-grid-community';
|
||||
import type { CellClickedEvent } from 'ag-grid-community';
|
||||
import { marketsWithDataProvider as dataProvider } from '../../markets-provider';
|
||||
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||
|
||||
interface MarketsContainerProps {
|
||||
onSelect: (marketId: string) => void;
|
||||
onSelect: (marketId: string, metaKey?: boolean) => void;
|
||||
}
|
||||
|
||||
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||
@ -21,16 +23,23 @@ 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, event } = 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);
|
||||
onSelect(
|
||||
(data as MarketMaybeWithData).id,
|
||||
(event as unknown as MouseEvent)?.metaKey
|
||||
);
|
||||
}}
|
||||
onMarketClick={onSelect}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
|
@ -9,7 +9,7 @@ export const OrderListContainer = ({
|
||||
enforceBottomPlaceholder,
|
||||
}: {
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
enforceBottomPlaceholder?: boolean;
|
||||
}) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
|
@ -23,7 +23,7 @@ import type { Order, OrderEdge } from '../order-data-provider';
|
||||
export interface OrderListManagerProps {
|
||||
partyId: string;
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
isReadOnly: boolean;
|
||||
enforceBottomPlaceholder?: boolean;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
limitOrder,
|
||||
marketOrder,
|
||||
} from '../mocks/generate-orders';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
// Mock theme switcher to get around inconsistent mocking of zustand
|
||||
// stores
|
||||
@ -36,9 +37,11 @@ const generateJsx = (
|
||||
) => {
|
||||
return (
|
||||
<MockedProvider>
|
||||
<MemoryRouter>
|
||||
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
|
||||
<OrderListTable {...defaultProps} {...props} />
|
||||
</VegaWalletContext.Provider>
|
||||
</MemoryRouter>
|
||||
</MockedProvider>
|
||||
);
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { AgGridColumn } from 'ag-grid-react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { memo, forwardRef } from 'react';
|
||||
@ -15,6 +15,7 @@ import {
|
||||
DateRangeFilter,
|
||||
negativeClassNames,
|
||||
positiveClassNames,
|
||||
MarketNameCell,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type {
|
||||
TypedDataAgGrid,
|
||||
@ -29,7 +30,7 @@ type OrderListProps = TypedDataAgGrid<Order> & { marketId?: string };
|
||||
export type OrderListTableProps = OrderListProps & {
|
||||
cancel: (order: Order) => void;
|
||||
setEditOrder: (order: Order) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
isReadOnly: boolean;
|
||||
};
|
||||
|
||||
@ -50,30 +51,14 @@ export const OrderListTable = memo(
|
||||
height: '100%',
|
||||
}}
|
||||
getRowId={({ data }) => data.id}
|
||||
components={{ MarketNameCell }}
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market')}
|
||||
field="market.tradableInstrument.instrument.code"
|
||||
cellRenderer={({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<
|
||||
Order,
|
||||
'market.tradableInstrument.instrument.code'
|
||||
>) =>
|
||||
onMarketClick ? (
|
||||
<Link
|
||||
onClick={() =>
|
||||
data?.market?.id && onMarketClick(data?.market?.id)
|
||||
}
|
||||
>
|
||||
{value}
|
||||
</Link>
|
||||
) : (
|
||||
value
|
||||
)
|
||||
}
|
||||
cellRenderer="MarketNameCell"
|
||||
cellRendererParams={{ idPath: 'market.id', onMarketClick }}
|
||||
minWidth={150}
|
||||
/>
|
||||
<AgGridColumn
|
||||
|
@ -6,6 +6,7 @@ import type { Position } from './positions-data-providers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
|
||||
import type { ICellRendererParams } from 'ag-grid-community';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
const singleRow: Position = {
|
||||
marketName: 'ETH/BTC (31 july 2022)',
|
||||
@ -37,7 +38,9 @@ const singleRowData = [singleRow];
|
||||
it('should render successfully', async () => {
|
||||
await act(async () => {
|
||||
const { baseElement } = render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={[]} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
@ -45,7 +48,11 @@ it('should render successfully', async () => {
|
||||
|
||||
it('render correct columns', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={true} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={true} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
@ -69,7 +76,11 @@ it('render correct columns', async () => {
|
||||
|
||||
it('renders market name', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
expect(screen.getByText('ETH/BTC (31 july 2022)')).toBeTruthy();
|
||||
});
|
||||
@ -80,7 +91,11 @@ it('Does not fail if the market name does not match the split pattern', async ()
|
||||
Object.assign({}, singleRow, { marketName: breakingMarketName }),
|
||||
];
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={row} isReadOnly={false} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={row} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
expect(screen.getByText(breakingMarketName)).toBeTruthy();
|
||||
@ -90,7 +105,9 @@ it('add color and sign to amount, displays positive notional value', async () =>
|
||||
let result: RenderResult;
|
||||
await act(async () => {
|
||||
result = render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
@ -101,10 +118,12 @@ it('add color and sign to amount, displays positive notional value', async () =>
|
||||
expect(cells[1].textContent).toEqual('1,230.0');
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
<MemoryRouter>
|
||||
<PositionsTable
|
||||
rowData={[{ ...singleRow, openVolume: '-100' }]}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
@ -118,7 +137,9 @@ it('displays mark price', async () => {
|
||||
let result: RenderResult;
|
||||
await act(async () => {
|
||||
result = render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
@ -127,6 +148,7 @@ it('displays mark price', async () => {
|
||||
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
<MemoryRouter>
|
||||
<PositionsTable
|
||||
rowData={[
|
||||
{
|
||||
@ -137,6 +159,7 @@ it('displays mark price', async () => {
|
||||
]}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
@ -146,7 +169,11 @@ it('displays mark price', async () => {
|
||||
|
||||
it('displays leverage', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[6].textContent).toEqual('1.1');
|
||||
@ -154,7 +181,11 @@ it('displays leverage', async () => {
|
||||
|
||||
it('displays allocated margin', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const cell = cells[7];
|
||||
@ -163,7 +194,11 @@ it('displays allocated margin', async () => {
|
||||
|
||||
it('displays realised and unrealised PNL', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[9].textContent).toEqual('4.56');
|
||||
@ -172,6 +207,7 @@ it('displays realised and unrealised PNL', async () => {
|
||||
it('displays close button', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable
|
||||
rowData={singleRowData}
|
||||
onClose={() => {
|
||||
@ -179,6 +215,7 @@ it('displays close button', async () => {
|
||||
}}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
@ -188,6 +225,7 @@ it('displays close button', async () => {
|
||||
it('do not display close button if openVolume is zero', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<PositionsTable
|
||||
rowData={[{ ...singleRow, openVolume: '0' }]}
|
||||
onClose={() => {
|
||||
@ -195,6 +233,7 @@ it('do not display close button if openVolume is zero', async () => {
|
||||
}}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
|
@ -14,12 +14,12 @@ import {
|
||||
PriceFlashCell,
|
||||
signedNumberCssClass,
|
||||
signedNumberCssClassRules,
|
||||
MarketNameCell,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
ButtonLink,
|
||||
Tooltip,
|
||||
TooltipCellComponent,
|
||||
Link,
|
||||
ExternalLink,
|
||||
Icon,
|
||||
ProgressBarCell,
|
||||
@ -43,7 +43,7 @@ import { useEnvironment } from '@vegaprotocol/environment';
|
||||
|
||||
interface Props extends TypedDataAgGrid<Position> {
|
||||
onClose?: (data: Position) => void;
|
||||
onMarketClick?: (id: string) => void;
|
||||
onMarketClick?: (id: string, metaKey?: boolean) => void;
|
||||
style?: CSSProperties;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
@ -96,26 +96,19 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
filterParams: { buttons: ['reset'] },
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
}}
|
||||
components={{ AmountCell, PriceFlashCell, ProgressBarCell }}
|
||||
components={{
|
||||
AmountCell,
|
||||
PriceFlashCell,
|
||||
ProgressBarCell,
|
||||
MarketNameCell,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Market')}
|
||||
field="marketName"
|
||||
cellRenderer={({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<Position, 'marketName'>) =>
|
||||
onMarketClick ? (
|
||||
<Link
|
||||
onClick={() => data?.marketId && onMarketClick(data?.marketId)}
|
||||
>
|
||||
{value}
|
||||
</Link>
|
||||
) : (
|
||||
value
|
||||
)
|
||||
}
|
||||
cellRenderer="MarketNameCell"
|
||||
cellRendererParams={{ idPath: 'marketId', onMarketClick }}
|
||||
minWidth={190}
|
||||
/>
|
||||
<AgGridColumn
|
||||
|
Loading…
Reference in New Issue
Block a user