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:
m.ray 2022-10-28 13:41:33 +01:00 committed by GitHub
parent b86c3386c6
commit a90970399c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 69 deletions

View File

@ -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',

View File

@ -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',

View File

@ -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');
}); });
}); });

View File

@ -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 = ({

View File

@ -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>
); );
} }