feat: 1651 market select snags (#1874)
* feat: #1651 market select snags * fix: #1651 fix markets.cy.ts cypress test * fix: #1651 prevent default and stop propagation on select markets asset click
This commit is contained in:
parent
b86c3386c6
commit
a90970399c
@ -37,15 +37,15 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
cy.getByTestId('market-name').should('not.be.empty');
|
cy.getByTestId('market-name').should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to select market from dropdown', () => {
|
it('able to select market from dropdown', () => {
|
||||||
openMarketDropDown();
|
openMarketDropDown();
|
||||||
cy.getByTestId('market-link-market-0').should('be.visible').click();
|
cy.getByTestId('market-link-market-0').first().should('be.visible').click();
|
||||||
cy.contains('ACTIVE MARKET').should('be.visible');
|
cy.contains('ACTIVE MARKET').should('be.visible');
|
||||||
cy.url().should('include', '/markets/market-0');
|
cy.url().should('include', '/markets/market-0');
|
||||||
cy.getByTestId('popover-trigger').should('not.be.empty');
|
cy.getByTestId('popover-trigger').should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to open and sort full market list - market page', () => {
|
it('able to open and sort full market list - market page', () => {
|
||||||
const ExpectedSortedMarkets = [
|
const ExpectedSortedMarkets = [
|
||||||
'AAPL.MF21',
|
'AAPL.MF21',
|
||||||
'BTCUSD.MF21',
|
'BTCUSD.MF21',
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { TradingModeTooltip } from '@vegaprotocol/deal-ticket';
|
||||||
import { FeesCell } from '@vegaprotocol/market-info';
|
import { FeesCell } from '@vegaprotocol/market-info';
|
||||||
import {
|
import {
|
||||||
calcCandleHigh,
|
calcCandleHigh,
|
||||||
@ -17,9 +18,13 @@ import {
|
|||||||
MarketTradingMode,
|
MarketTradingMode,
|
||||||
MarketTradingModeMapping,
|
MarketTradingModeMapping,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import { PriceCellChange, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit';
|
import {
|
||||||
|
Link,
|
||||||
|
PriceCellChange,
|
||||||
|
Sparkline,
|
||||||
|
Tooltip,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import isNil from 'lodash/isNil';
|
import isNil from 'lodash/isNil';
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
import type { CandleClose } from '@vegaprotocol/types';
|
import type { CandleClose } from '@vegaprotocol/types';
|
||||||
import type {
|
import type {
|
||||||
@ -30,6 +35,31 @@ type Market = MarketWithData & MarketWithCandles;
|
|||||||
|
|
||||||
export const cellClassNames = 'py-1 first:text-left text-right';
|
export const cellClassNames = 'py-1 first:text-left text-right';
|
||||||
|
|
||||||
|
const TradingMode = ({ market }: { market: Market }) => {
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
description={
|
||||||
|
market && (
|
||||||
|
<TradingModeTooltip
|
||||||
|
tradingMode={market.tradingMode}
|
||||||
|
trigger={market.data?.trigger || null}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{market.tradingMode ===
|
||||||
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
|
market.data?.trigger &&
|
||||||
|
market.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
|
? `${MarketTradingModeMapping[market.tradingMode]}
|
||||||
|
- ${AuctionTriggerMapping[market.data.trigger]}`
|
||||||
|
: MarketTradingModeMapping[market.tradingMode]}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const FeesInfo = () => {
|
const FeesInfo = () => {
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -174,10 +204,30 @@ export const columns = (
|
|||||||
const candleLow = market.candles && calcCandleLow(market.candles);
|
const candleLow = market.candles && calcCandleLow(market.candles);
|
||||||
const candleHigh = market.candles && calcCandleHigh(market.candles);
|
const candleHigh = market.candles && calcCandleHigh(market.candles);
|
||||||
const candleVolume = market.candles && calcCandleVolume(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[] = [
|
const selectMarketColumns: Column[] = [
|
||||||
{
|
{
|
||||||
kind: ColumnKind.Market,
|
kind: ColumnKind.Market,
|
||||||
value: market.tradableInstrument.instrument.code,
|
value: (
|
||||||
|
<Link
|
||||||
|
href={`/markets/${market.id}`}
|
||||||
|
data-testid={`market-link-${market.id}`}
|
||||||
|
onKeyPress={(event) => handleKeyPress(event, market.id)}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
onSelect(market.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{market.tradableInstrument.instrument.code}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
className: cellClassNames,
|
className: cellClassNames,
|
||||||
onlyOnDetailed: false,
|
onlyOnDetailed: false,
|
||||||
},
|
},
|
||||||
@ -227,15 +277,16 @@ export const columns = (
|
|||||||
value: (
|
value: (
|
||||||
<button
|
<button
|
||||||
data-dialog-trigger
|
data-dialog-trigger
|
||||||
className="inline hover:underline"
|
className="inline underline"
|
||||||
onClick={(e) =>
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
onCellClick(
|
onCellClick(
|
||||||
e,
|
e,
|
||||||
ColumnKind.Asset,
|
ColumnKind.Asset,
|
||||||
market.tradableInstrument.instrument.product.settlementAsset
|
market.tradableInstrument.instrument.product.settlementAsset
|
||||||
.symbol
|
.symbol
|
||||||
)
|
);
|
||||||
}
|
}}
|
||||||
>
|
>
|
||||||
{market.tradableInstrument.instrument.product.settlementAsset.symbol}
|
{market.tradableInstrument.instrument.product.settlementAsset.symbol}
|
||||||
</button>
|
</button>
|
||||||
@ -293,14 +344,7 @@ export const columns = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: ColumnKind.TradingMode,
|
kind: ColumnKind.TradingMode,
|
||||||
value:
|
value: <TradingMode market={market} />,
|
||||||
market.tradingMode ===
|
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger &&
|
|
||||||
market.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
|
||||||
? `${MarketTradingModeMapping[market.tradingMode]}
|
|
||||||
- ${AuctionTriggerMapping[market.data.trigger]}`
|
|
||||||
: MarketTradingModeMapping[market.tradingMode],
|
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
dataTestId: 'trading-mode-col',
|
dataTestId: 'trading-mode-col',
|
||||||
@ -347,17 +391,16 @@ export const columnsPositionMarkets = (
|
|||||||
{
|
{
|
||||||
kind: ColumnKind.Market,
|
kind: ColumnKind.Market,
|
||||||
value: (
|
value: (
|
||||||
<Link href={`/markets/${market.id}`} passHref={true}>
|
<Link
|
||||||
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid,jsx-a11y/no-static-element-interactions */}
|
href={`/markets/${market.id}`}
|
||||||
<a
|
data-testid={`market-link-${market.id}`}
|
||||||
onKeyPress={(event) => handleKeyPress(event, market.id)}
|
onKeyPress={(event) => handleKeyPress(event, market.id)}
|
||||||
onClick={() => {
|
onClick={(e) => {
|
||||||
onSelect(market.id);
|
e.preventDefault();
|
||||||
}}
|
onSelect(market.id);
|
||||||
data-testid={`market-link-${market.id}`}
|
}}
|
||||||
>
|
>
|
||||||
{market.tradableInstrument.instrument.code}
|
{market.tradableInstrument.instrument.code}
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
className: cellClassNames,
|
className: cellClassNames,
|
||||||
@ -409,8 +452,9 @@ export const columnsPositionMarkets = (
|
|||||||
value: (
|
value: (
|
||||||
<button
|
<button
|
||||||
data-dialog-trigger
|
data-dialog-trigger
|
||||||
className="inline hover:underline"
|
className="inline underline"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
if (!onCellClick) return;
|
if (!onCellClick) return;
|
||||||
onCellClick(
|
onCellClick(
|
||||||
e,
|
e,
|
||||||
@ -475,14 +519,7 @@ export const columnsPositionMarkets = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: ColumnKind.TradingMode,
|
kind: ColumnKind.TradingMode,
|
||||||
value:
|
value: <TradingMode market={market} />,
|
||||||
market.tradingMode ===
|
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
|
||||||
market.data?.trigger &&
|
|
||||||
market.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
|
||||||
? `${MarketTradingModeMapping[market.tradingMode]}
|
|
||||||
- ${AuctionTriggerMapping[market.data.trigger]}`
|
|
||||||
: MarketTradingModeMapping[market.tradingMode],
|
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
dataTestId: 'trading-mode-col',
|
dataTestId: 'trading-mode-col',
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { fireEvent, render, screen } from '@testing-library/react';
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
|
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
|
|
||||||
|
import {
|
||||||
|
SelectAllMarketsTableBody,
|
||||||
|
SelectMarketLandingTable,
|
||||||
|
} from './select-market';
|
||||||
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type {
|
import type {
|
||||||
MarketWithCandles,
|
MarketWithCandles,
|
||||||
MarketWithData,
|
MarketWithData,
|
||||||
MarketData,
|
MarketData,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import {
|
|
||||||
SelectAllMarketsTableBody,
|
|
||||||
SelectMarketLandingTable,
|
|
||||||
} from './select-market';
|
|
||||||
|
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketWithCandles & MarketWithData;
|
||||||
|
|
||||||
jest.mock(
|
jest.mock(
|
||||||
@ -162,7 +163,7 @@ describe('SelectMarket', () => {
|
|||||||
expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
|
expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
|
||||||
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
||||||
expect(container).toHaveTextContent(/1,000/); // volume
|
expect(container).toHaveTextContent(/1,000/); // volume
|
||||||
fireEvent.click(screen.getByTestId(`market-link-1`));
|
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||||
expect(onSelect).toHaveBeenCalledWith('1');
|
expect(onSelect).toHaveBeenCalledWith('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -177,9 +178,9 @@ describe('SelectMarket', () => {
|
|||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
fireEvent.click(screen.getByTestId(`market-link-1`));
|
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||||
expect(onSelect).toHaveBeenCalledWith('1');
|
expect(onSelect).toHaveBeenCalledWith('1');
|
||||||
fireEvent.click(screen.getByTestId(`market-link-2`));
|
fireEvent.click(screen.getAllByTestId(`market-link-2`)[0]);
|
||||||
expect(onSelect).toHaveBeenCalledWith('2');
|
expect(onSelect).toHaveBeenCalledWith('2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,34 +1,35 @@
|
|||||||
import type { ReactNode } from 'react';
|
import { useMarketList } from '@vegaprotocol/market-list';
|
||||||
import { useMemo, useState } from 'react';
|
import { positionsDataProvider } from '@vegaprotocol/positions';
|
||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
Icon,
|
Icon,
|
||||||
Intent,
|
Intent,
|
||||||
Loader,
|
|
||||||
Link,
|
Link,
|
||||||
|
Loader,
|
||||||
Popover,
|
Popover,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { useMarketList } from '@vegaprotocol/market-list';
|
|
||||||
import type {
|
|
||||||
MarketWithCandles,
|
|
||||||
MarketWithData,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
import { useMemo, useState } from 'react';
|
||||||
import { positionsDataProvider } from '@vegaprotocol/positions';
|
|
||||||
|
import {
|
||||||
|
columnHeaders,
|
||||||
|
columnHeadersPositionMarkets,
|
||||||
|
columns,
|
||||||
|
columnsPositionMarkets,
|
||||||
|
} from './select-market-columns';
|
||||||
import {
|
import {
|
||||||
SelectMarketTableHeader,
|
SelectMarketTableHeader,
|
||||||
SelectMarketTableRow,
|
SelectMarketTableRow,
|
||||||
} from './select-market-table';
|
} from './select-market-table';
|
||||||
import type { Column, OnCellClickHandler } from './select-market-columns';
|
|
||||||
import {
|
|
||||||
columnHeadersPositionMarkets,
|
|
||||||
columnsPositionMarkets,
|
|
||||||
columnHeaders,
|
|
||||||
columns,
|
|
||||||
} from './select-market-columns';
|
|
||||||
|
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
import type {
|
||||||
|
MarketWithCandles,
|
||||||
|
MarketWithData,
|
||||||
|
} from '@vegaprotocol/market-list';
|
||||||
|
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
||||||
|
import type { Column, OnCellClickHandler } from './select-market-columns';
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketWithCandles & MarketWithData;
|
||||||
|
|
||||||
export const SelectMarketLandingTable = ({
|
export const SelectMarketLandingTable = ({
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { MarketTradingMode, AuctionTrigger } from '@vegaprotocol/types';
|
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { MarketDataGrid } from './market-data-grid';
|
import { MarketDataGrid } from './market-data-grid';
|
||||||
|
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
type TradingModeTooltipProps = {
|
type TradingModeTooltipProps = {
|
||||||
tradingMode: MarketTradingMode | null;
|
tradingMode: MarketTradingMode | null;
|
||||||
trigger: AuctionTrigger | null;
|
trigger: AuctionTrigger | null;
|
||||||
compiledGrid: { label: ReactNode; value?: ReactNode }[];
|
compiledGrid?: { label: ReactNode; value?: ReactNode }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TradingModeTooltip = ({
|
export const TradingModeTooltip = ({
|
||||||
@ -38,7 +39,7 @@ export const TradingModeTooltip = ({
|
|||||||
{t('Find out more')}
|
{t('Find out more')}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
</p>
|
</p>
|
||||||
<MarketDataGrid grid={compiledGrid} />
|
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -57,7 +58,7 @@ export const TradingModeTooltip = ({
|
|||||||
{t('Find out more')}
|
{t('Find out more')}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
</p>
|
</p>
|
||||||
<MarketDataGrid grid={compiledGrid} />
|
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -72,7 +73,7 @@ export const TradingModeTooltip = ({
|
|||||||
{t('Find out more')}
|
{t('Find out more')}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
</p>
|
</p>
|
||||||
<MarketDataGrid grid={compiledGrid} />
|
{compiledGrid && <MarketDataGrid grid={compiledGrid} />}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user