feat: add handle successor and parent markets - add some improvements
This commit is contained in:
@@ -14,7 +14,6 @@ import { TradePanels } from './trade-panels';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
import { MarketSuccessorBanner } from '../../components/banner';
|
||||
|
||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||
return markPrice && decimalPlaces
|
||||
@@ -133,10 +132,7 @@ export const MarketPage = () => {
|
||||
marketName={data?.tradableInstrument.instrument.name}
|
||||
decimalPlaces={data?.decimalPlaces}
|
||||
/>
|
||||
<div className="flex flex-col h-full">
|
||||
<MarketSuccessorBanner />
|
||||
{tradeView}
|
||||
</div>
|
||||
{tradeView}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { memo, useState } from 'react';
|
||||
import React, { memo, useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { LayoutPriority } from 'allotment';
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
import { TradingViews } from './trade-views';
|
||||
import { MarketSelector } from './market-selector';
|
||||
import { HeaderStats } from './header-stats';
|
||||
import { MarketSuccessorBanner } from '../../components/market-banner';
|
||||
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
@@ -317,6 +318,7 @@ export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
|
||||
<HeaderStats market={market} />
|
||||
</div>
|
||||
<div className="col-span-2 bg-vega-green">
|
||||
<MarketSuccessorBanner market={market} />
|
||||
<OracleBanner marketId={market?.id || ''} />
|
||||
</div>
|
||||
{sidebarOpen && (
|
||||
|
||||
@@ -21,6 +21,7 @@ import { HeaderStats } from './header-stats';
|
||||
import * as DialogPrimitives from '@radix-ui/react-dialog';
|
||||
import { HeaderTitle } from '../../components/header';
|
||||
import { MarketSelector } from './market-selector';
|
||||
import { MarketSuccessorBanner } from '../../components/market-banner';
|
||||
|
||||
interface TradePanelsProps {
|
||||
market: Market | null;
|
||||
@@ -92,6 +93,7 @@ export const TradePanels = ({
|
||||
<HeaderStats market={market} />
|
||||
</div>
|
||||
<div>
|
||||
<MarketSuccessorBanner market={market} />
|
||||
<OracleBanner marketId={market?.id || ''} />
|
||||
</div>
|
||||
<div className="h-full">
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './announcement-banner';
|
||||
export * from './upgrade-banner';
|
||||
export * from './market-successor-banner';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './market-successor-banner';
|
||||
+32
-68
@@ -7,13 +7,21 @@ import * as allUtils from '@vegaprotocol/utils';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
let mockParams = {};
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useParams: jest.fn(() => mockParams),
|
||||
}));
|
||||
const market = {
|
||||
id: 'marketId',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
marketTimestamps: {
|
||||
close: null,
|
||||
},
|
||||
successorMarketID: 'successorMarketID',
|
||||
} as unknown as Market;
|
||||
|
||||
let mockDataMarket: PartialDeep<Market> | null = null;
|
||||
let mockDataSuccessorMarket: PartialDeep<Market> | null = null;
|
||||
jest.mock('@vegaprotocol/data-provider', () => ({
|
||||
...jest.requireActual('@vegaprotocol/data-provider'),
|
||||
@@ -24,12 +32,6 @@ jest.mock('@vegaprotocol/data-provider', () => ({
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
if (args.variables.marketId === 'marketId') {
|
||||
return {
|
||||
data: mockDataMarket,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
return {
|
||||
data: mockDataSuccessorMarket,
|
||||
error: null,
|
||||
@@ -49,21 +51,6 @@ jest.mock('@vegaprotocol/markets', () => ({
|
||||
describe('MarketSuccessorBanner', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockParams = { marketId: 'marketId' };
|
||||
mockDataMarket = {
|
||||
id: 'marketId',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
marketTimestamps: {
|
||||
close: null,
|
||||
},
|
||||
successorMarketID: 'successorMarketID',
|
||||
};
|
||||
mockDataSuccessorMarket = {
|
||||
id: 'successorMarketID',
|
||||
state: Types.MarketState.STATE_ACTIVE,
|
||||
@@ -76,27 +63,25 @@ describe('MarketSuccessorBanner', () => {
|
||||
};
|
||||
});
|
||||
describe('should be hidden', () => {
|
||||
it('when no marketID', () => {
|
||||
mockParams = {};
|
||||
const { container } = render(<MarketSuccessorBanner />, {
|
||||
it('when no market', () => {
|
||||
const { container } = render(<MarketSuccessorBanner market={null} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('when no successorMarketID', () => {
|
||||
delete mockDataMarket?.successorMarketID;
|
||||
const { container } = render(<MarketSuccessorBanner />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(dataProviders.useDataProvider).nthCalledWith(
|
||||
1,
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'marketId' },
|
||||
skip: false,
|
||||
})
|
||||
const amendedMarket = {
|
||||
...market,
|
||||
successorMarketID: null,
|
||||
};
|
||||
const { container } = render(
|
||||
<MarketSuccessorBanner market={amendedMarket} />,
|
||||
{
|
||||
wrapper: MockedProvider,
|
||||
}
|
||||
);
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(dataProviders.useDataProvider).lastCalledWith(
|
||||
expect.objectContaining({ skip: true })
|
||||
);
|
||||
@@ -104,17 +89,10 @@ describe('MarketSuccessorBanner', () => {
|
||||
|
||||
it('no successor market data', () => {
|
||||
mockDataSuccessorMarket = null;
|
||||
const { container } = render(<MarketSuccessorBanner />, {
|
||||
const { container } = render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(dataProviders.useDataProvider).nthCalledWith(
|
||||
1,
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'marketId' },
|
||||
skip: false,
|
||||
})
|
||||
);
|
||||
expect(dataProviders.useDataProvider).lastCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'successorMarketID' },
|
||||
@@ -128,17 +106,10 @@ describe('MarketSuccessorBanner', () => {
|
||||
...mockDataSuccessorMarket,
|
||||
tradingMode: Types.MarketTradingMode.TRADING_MODE_NO_TRADING,
|
||||
};
|
||||
const { container } = render(<MarketSuccessorBanner />, {
|
||||
const { container } = render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(dataProviders.useDataProvider).nthCalledWith(
|
||||
1,
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'marketId' },
|
||||
skip: false,
|
||||
})
|
||||
);
|
||||
expect(dataProviders.useDataProvider).lastCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'successorMarketID' },
|
||||
@@ -153,17 +124,10 @@ describe('MarketSuccessorBanner', () => {
|
||||
...mockDataSuccessorMarket,
|
||||
state: Types.MarketState.STATE_PENDING,
|
||||
};
|
||||
const { container } = render(<MarketSuccessorBanner />, {
|
||||
const { container } = render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
expect(dataProviders.useDataProvider).nthCalledWith(
|
||||
1,
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'marketId' },
|
||||
skip: false,
|
||||
})
|
||||
);
|
||||
expect(dataProviders.useDataProvider).lastCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: { marketId: 'successorMarketID' },
|
||||
@@ -176,7 +140,7 @@ describe('MarketSuccessorBanner', () => {
|
||||
|
||||
describe('should be displayed', () => {
|
||||
it('should be rendered', () => {
|
||||
render(<MarketSuccessorBanner />, {
|
||||
render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(
|
||||
@@ -201,7 +165,7 @@ describe('MarketSuccessorBanner', () => {
|
||||
],
|
||||
};
|
||||
|
||||
render(<MarketSuccessorBanner />, {
|
||||
render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(screen.getByText('has 101.367 24h vol.')).toBeInTheDocument();
|
||||
@@ -213,7 +177,7 @@ describe('MarketSuccessorBanner', () => {
|
||||
.mockReturnValue(
|
||||
new Date(Date.now() + 24 * 60 * 60 * 1000 + 60 * 1000)
|
||||
);
|
||||
render(<MarketSuccessorBanner />, {
|
||||
render(<MarketSuccessorBanner market={market} />, {
|
||||
wrapper: MockedProvider,
|
||||
});
|
||||
expect(
|
||||
+11
-15
@@ -1,7 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { isBefore, formatDuration, intervalToDuration } from 'date-fns';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import {
|
||||
calcCandleVolume,
|
||||
marketProvider,
|
||||
@@ -25,28 +25,24 @@ const getExpiryDate = (tags: string[], close?: string): Date | null => {
|
||||
return expiryDate || (close && new Date(close)) || null;
|
||||
};
|
||||
|
||||
export const MarketSuccessorBanner = () => {
|
||||
const { marketId } = useParams();
|
||||
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: marketProvider,
|
||||
variables: { marketId: marketId || '' },
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
export const MarketSuccessorBanner = ({
|
||||
market,
|
||||
}: {
|
||||
market: Market | null;
|
||||
}) => {
|
||||
const { data: successorData } = useDataProvider({
|
||||
dataProvider: marketProvider,
|
||||
variables: {
|
||||
marketId: data?.successorMarketID || '',
|
||||
marketId: market?.successorMarketID || '',
|
||||
},
|
||||
skip: !data?.successorMarketID,
|
||||
skip: !market?.successorMarketID,
|
||||
});
|
||||
const [visible, setVisible] = useState(true);
|
||||
|
||||
const expiry = data
|
||||
const expiry = market
|
||||
? getExpiryDate(
|
||||
data.tradableInstrument.instrument.metadata.tags || [],
|
||||
data.marketTimestamps.close
|
||||
market.tradableInstrument.instrument.metadata.tags || [],
|
||||
market.marketTimestamps.close
|
||||
)
|
||||
: null;
|
||||
|
||||
Reference in New Issue
Block a user