chore(trading): add sub statuses of opening auction trading mode (#2797)

This commit is contained in:
macqbat 2023-01-31 17:31:55 +01:00 committed by GitHub
parent 8f8e9c1061
commit d151b6e923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 161 additions and 9 deletions

View File

@ -1,4 +1,7 @@
import * as Schema from '@vegaprotocol/types';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { marketQuery } from '@vegaprotocol/mock';
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
describe('markets table', { tags: '@smoke' }, () => {
beforeEach(() => {
@ -111,6 +114,53 @@ describe('markets table', { tags: '@smoke' }, () => {
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
);
});
it('opening auction subsets should be properly displayed', () => {
cy.mockTradingPage(
Schema.MarketState.STATE_ACTIVE,
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
);
cy.mockGQL((req) => {
const override = {
market: {
tradableInstrument: {
instrument: {
name: `opening auction MARKET`,
},
},
state: Schema.MarketState.STATE_ACTIVE,
tradingMode: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
},
};
const market = marketQuery(override);
aliasGQLQuery(req, 'Market', market);
aliasGQLQuery(req, 'ProposalOfMarket', {
proposal: { terms: { enactmentDatetime: '2023-01-31 12:00:01' } },
});
});
cy.visit('/');
cy.visit('#/markets/market-0');
cy.getByTestId('item-value').contains('Opening auction').realHover();
cy.getByTestId('opening-auction-sub-status').should(
'contain.text',
'Opening auction: Not enough liquidity to open'
);
const now = new Date(Date.parse('2023-01-30 12:00:01')).getTime();
cy.clock(now, ['Date']); // Set "now" to BEFORE reservation
cy.visit('/');
cy.visit('#/markets/market-0');
cy.getByTestId('item-value').contains('Opening auction').realHover();
cy.getByTestId('opening-auction-sub-status').should(
'contain.text',
`Opening auction: Closing on ${getDateTimeFormat().format(
new Date('2023-01-31 12:00:01')
)}`
);
cy.clock().then((clock) => {
clock.restore();
});
});
});
function openMarketDropDown() {

View File

@ -1,6 +1,9 @@
import { useMemo } from 'react';
import { parseISO, isValid, isAfter } from 'date-fns';
import classNames from 'classnames';
import { useProposalOfMarketQuery } from '@vegaprotocol/governance';
import { useEnvironment } from '@vegaprotocol/environment';
import { DataGrid, t } from '@vegaprotocol/react-helpers';
import { DataGrid, getDateTimeFormat, t } from '@vegaprotocol/react-helpers';
import * as Schema from '@vegaprotocol/types';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { createDocsLinks } from '@vegaprotocol/react-helpers';
@ -21,14 +24,24 @@ export const TradingModeTooltip = ({
const { VEGA_DOCS_URL } = useEnvironment();
const market = useMarket(marketId);
const marketData = useStaticMarketData(marketId, skip);
const { marketTradingMode: tradingMode, trigger } = marketData || {};
const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]);
const { data: proposalData } = useProposalOfMarketQuery({
variables,
skip:
!tradingMode ||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION !== tradingMode,
});
if (!market || !marketData) {
return null;
}
const enactmentDate = parseISO(
proposalData?.proposal?.terms.enactmentDatetime
);
const compiledGrid =
onSelect && compileGridData(market, marketData, onSelect);
const { marketTradingMode: tradingMode, trigger } = marketData;
switch (tradingMode) {
case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: {
@ -43,12 +56,47 @@ export const TradingModeTooltip = ({
case Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION: {
return (
<section data-testid="trading-mode-tooltip">
<p className={classNames({ 'mb-4': Boolean(compiledGrid) })}>
<span>
{t(
'This new market is in an opening auction to determine a fair mid-price before starting continuous trading.'
)}
</span>{' '}
<p
className={classNames('flex flex-col', {
'mb-4': Boolean(compiledGrid),
})}
>
{isValid(enactmentDate) && isAfter(new Date(), enactmentDate) ? (
<>
<span
className="justify-center font-bold my-2"
data-testid="opening-auction-sub-status"
>
{`${Schema.MarketTradingModeMapping[tradingMode]}: ${t(
'Not enough liquidity to open'
)}`}
</span>
<span>
{t(
'This market is in opening auction until it has reached enough liquidity to move into continuous trading.'
)}
</span>
</>
) : (
<>
{isValid(enactmentDate) && (
<span
className="justify-center font-bold my-2"
data-testid="opening-auction-sub-status"
>
{`${Schema.MarketTradingModeMapping[tradingMode]}: ${t(
'Closing on %s',
getDateTimeFormat().format(enactmentDate)
)}`}
</span>
)}
<span>
{t(
'This is a new market in an opening auction to determine a fair mid-price before starting continuous trading.'
)}
</span>
</>
)}
{VEGA_DOCS_URL && (
<ExternalLink
href={createDocsLinks(VEGA_DOCS_URL).AUCTION_TYPE_OPENING}

View File

@ -43,3 +43,12 @@ subscription OnUpdateNetworkParameters {
}
}
}
query ProposalOfMarket($marketId: ID!) {
proposal(id: $marketId) {
id
terms {
enactmentDatetime
}
}
}

View File

@ -19,6 +19,13 @@ export type OnUpdateNetworkParametersSubscriptionVariables = Types.Exact<{ [key:
export type OnUpdateNetworkParametersSubscription = { __typename?: 'Subscription', busEvents?: Array<{ __typename?: 'BusEvent', event: { __typename?: 'AccountEvent' } | { __typename?: 'Asset' } | { __typename?: 'AuctionEvent' } | { __typename?: 'Deposit' } | { __typename?: 'LiquidityProvision' } | { __typename?: 'LossSocialization' } | { __typename?: 'MarginLevels' } | { __typename?: 'Market' } | { __typename?: 'MarketData' } | { __typename?: 'MarketEvent' } | { __typename?: 'MarketTick' } | { __typename?: 'NodeSignature' } | { __typename?: 'OracleSpec' } | { __typename?: 'Order' } | { __typename?: 'Party' } | { __typename?: 'PositionResolution' } | { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, datetime: any, terms: { __typename?: 'ProposalTerms', enactmentDatetime?: any | null, change: { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } } } | { __typename?: 'RiskFactor' } | { __typename?: 'SettleDistressed' } | { __typename?: 'SettlePosition' } | { __typename?: 'TimeUpdate' } | { __typename?: 'Trade' } | { __typename?: 'TransactionResult' } | { __typename?: 'TransferResponses' } | { __typename?: 'Vote' } | { __typename?: 'Withdrawal' } }> | null };
export type ProposalOfMarketQueryVariables = Types.Exact<{
marketId: Types.Scalars['ID'];
}>;
export type ProposalOfMarketQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, terms: { __typename?: 'ProposalTerms', enactmentDatetime?: any | null } } | null };
export const ProposalEventFieldsFragmentDoc = gql`
fragment ProposalEventFields on Proposal {
id
@ -113,4 +120,42 @@ export function useOnUpdateNetworkParametersSubscription(baseOptions?: Apollo.Su
return Apollo.useSubscription<OnUpdateNetworkParametersSubscription, OnUpdateNetworkParametersSubscriptionVariables>(OnUpdateNetworkParametersDocument, options);
}
export type OnUpdateNetworkParametersSubscriptionHookResult = ReturnType<typeof useOnUpdateNetworkParametersSubscription>;
export type OnUpdateNetworkParametersSubscriptionResult = Apollo.SubscriptionResult<OnUpdateNetworkParametersSubscription>;
export type OnUpdateNetworkParametersSubscriptionResult = Apollo.SubscriptionResult<OnUpdateNetworkParametersSubscription>;
export const ProposalOfMarketDocument = gql`
query ProposalOfMarket($marketId: ID!) {
proposal(id: $marketId) {
id
terms {
enactmentDatetime
}
}
}
`;
/**
* __useProposalOfMarketQuery__
*
* To run a query within a React component, call `useProposalOfMarketQuery` and pass it any options that fit your needs.
* When your component renders, `useProposalOfMarketQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useProposalOfMarketQuery({
* variables: {
* marketId: // value for 'marketId'
* },
* });
*/
export function useProposalOfMarketQuery(baseOptions: Apollo.QueryHookOptions<ProposalOfMarketQuery, ProposalOfMarketQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ProposalOfMarketQuery, ProposalOfMarketQueryVariables>(ProposalOfMarketDocument, options);
}
export function useProposalOfMarketLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ProposalOfMarketQuery, ProposalOfMarketQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ProposalOfMarketQuery, ProposalOfMarketQueryVariables>(ProposalOfMarketDocument, options);
}
export type ProposalOfMarketQueryHookResult = ReturnType<typeof useProposalOfMarketQuery>;
export type ProposalOfMarketLazyQueryHookResult = ReturnType<typeof useProposalOfMarketLazyQuery>;
export type ProposalOfMarketQueryResult = Apollo.QueryResult<ProposalOfMarketQuery, ProposalOfMarketQueryVariables>;