feat: 1661 add market expiry date from metadata tags to market info and market header (#1739)

This commit is contained in:
m.ray 2022-10-14 08:09:11 +01:00 committed by GitHub
parent d674162e38
commit fe472acfe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 92 additions and 56 deletions

View File

@ -9,7 +9,6 @@ import classNames from 'classnames';
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import { SIDE_NAMES } from './side-selector';
import SimpleMarketExpires from '../simple-market-list/simple-market-expires';
import { gql, useQuery } from '@apollo/client';
import type {
MarketTags,
@ -17,6 +16,7 @@ import type {
} from './__generated__/MarketTags';
import { DealTicketEstimates } from './deal-ticket-estimates';
import { Side } from '@vegaprotocol/types';
import { MarketExpires } from '@vegaprotocol/market-info';
export const MARKET_TAGS_QUERY = gql`
query MarketTags($marketId: ID!) {
@ -86,7 +86,7 @@ export default ({
<div>
{tagsData?.market?.tradableInstrument.instrument.metadata
.tags && (
<SimpleMarketExpires
<MarketExpires
tags={
tagsData?.market.tradableInstrument.instrument.metadata.tags
}

View File

@ -1,34 +0,0 @@
import React from 'react';
import { format, isValid, parseISO } from 'date-fns';
import { EXPIRE_DATE_FORMAT } from '../../constants';
const SimpleMarketExpires = ({
tags,
}: {
tags?: ReadonlyArray<string> | null;
}) => {
if (tags) {
const dateFound = tags.reduce<Date | null>((agg, tag) => {
const parsed = parseISO(
(tag.match(/^settlement.*:/) &&
tag
.split(':')
.filter((item, i) => i)
.join(':')) as string
);
if (isValid(parsed)) {
agg = parsed;
}
return agg;
}, null);
return dateFound ? (
<div className="p-2 text-ui-small border border-pink text-pink inline-block">{`${format(
dateFound as Date,
EXPIRE_DATE_FORMAT
)}`}</div>
) : null;
}
return null;
};
export default SimpleMarketExpires;

View File

@ -1,6 +1,6 @@
import classNames from 'classnames';
import SimpleMarketExpires from './simple-market-expires';
import type { Market } from '@vegaprotocol/market-list';
import { MarketExpires } from '@vegaprotocol/market-info';
interface Props {
market: Market;
@ -19,7 +19,7 @@ const MarketNameRenderer = ({ market, isMobile }: Props) => {
{isMobile
? market.tradableInstrument.instrument.code
: market.tradableInstrument.instrument.name}{' '}
<SimpleMarketExpires
<MarketExpires
tags={market.tradableInstrument.instrument.metadata.tags}
/>
</div>

View File

@ -3,7 +3,6 @@ import { t } from '@vegaprotocol/react-helpers';
import type { Market } from '@vegaprotocol/market-list';
export const DATE_FORMAT = 'dd MMMM yyyy HH:mm';
export const EXPIRE_DATE_FORMAT = 'MMM dd';
export const TRADABLE_STATES = {
[MarketState.STATE_ACTIVE]: true,

View File

@ -1,5 +1,5 @@
import { DealTicketContainer } from '@vegaprotocol/deal-ticket';
import { MarketInfoContainer } from '@vegaprotocol/market-info';
import { MarketInfoContainer, getExpiryDate } from '@vegaprotocol/market-info';
import { OrderbookContainer } from '@vegaprotocol/market-depth';
import { OrderListContainer } from '@vegaprotocol/orders';
import { FillsContainer } from '@vegaprotocol/fills';
@ -20,7 +20,7 @@ import {
ButtonLink,
Link,
} from '@vegaprotocol/ui-toolkit';
import { getDateFormat, t } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/react-helpers';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import { useEnvironment } from '@vegaprotocol/environment';
import { Header, HeaderStat } from '../../components/header';
@ -56,15 +56,7 @@ type ExpiryLabelProps = {
};
const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
let content = null;
if (market.marketTimestamps.close === null) {
content = t('Not time-based');
} else {
const closeDate = new Date(market.marketTimestamps.close as string);
const isExpired = Date.now() - closeDate.valueOf() > 0;
const expiryDate = getDateFormat().format(closeDate);
content = `${isExpired ? `${t('Expired')} ` : ''} ${expiryDate}`;
}
const content = getExpiryDate(market);
return <div data-testid="trading-expiry">{content}</div>;
};

View File

@ -1 +1,2 @@
export * from './market-expires';
export * from './market-info';

View File

@ -0,0 +1 @@
export * from './market-expires';

View File

@ -1,8 +1,8 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import SimpleMarketExpires from './simple-market-expires';
import { MarketExpires } from './market-expires';
describe('SimpleMarketExpires', () => {
describe('MarketExpires', () => {
describe('should properly parse different tags', () => {
it('settlement:date', () => {
const tags = [
@ -12,7 +12,7 @@ describe('SimpleMarketExpires', () => {
'settlement:notadate',
'settlement:20220525T1200',
];
render(<SimpleMarketExpires tags={tags} />);
render(<MarketExpires tags={tags} />);
expect(screen.getByText('May 25')).toBeInTheDocument();
});
@ -22,7 +22,7 @@ describe('SimpleMarketExpires', () => {
'settlement:20220525T1200',
'settlement-date:2022-04-25T1200',
];
render(<SimpleMarketExpires tags={tags} />);
render(<MarketExpires tags={tags} />);
expect(screen.getByText('Apr 25')).toBeInTheDocument();
});
@ -32,7 +32,7 @@ describe('SimpleMarketExpires', () => {
'settlement-date:20220525T1200',
'settlement-expiry-date:2022-03-25T12:00:00',
];
render(<SimpleMarketExpires tags={tags} />);
render(<MarketExpires tags={tags} />);
expect(screen.getByText('Mar 25')).toBeInTheDocument();
});
@ -42,7 +42,7 @@ describe('SimpleMarketExpires', () => {
'settlemenz:20220525T1200',
'settlemenx-date:20220425T1200',
];
const { container } = render(<SimpleMarketExpires tags={tags} />);
const { container } = render(<MarketExpires tags={tags} />);
expect(container.firstChild).toBeNull();
});
});

View File

@ -0,0 +1,73 @@
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
import { getDateFormat, t } from '@vegaprotocol/react-helpers';
import { format, isValid, parseISO } from 'date-fns';
export const EXPIRE_DATE_FORMAT = 'MMM dd';
export const getMarketExpiryDate = (
tags?: ReadonlyArray<string> | null
): Date | null => {
if (tags) {
const dateFound = tags.reduce<Date | null>((agg, tag) => {
const parsed = parseISO(
(tag.match(/^settlement.*:/) &&
tag
.split(':')
.filter((item, i) => i)
.join(':')) as string
);
if (isValid(parsed)) {
agg = parsed;
}
return agg;
}, null);
return dateFound;
}
return null;
};
export const getMarketExpiryDateFormatted = (
tags?: ReadonlyArray<string> | null
): string | null => {
if (tags) {
const dateFound = getMarketExpiryDate(tags);
return dateFound ? format(dateFound, EXPIRE_DATE_FORMAT) : null;
}
return null;
};
export const getExpiryDate = (market: SingleMarketFieldsFragment): string => {
const closeDate = getMarketExpiryDate(
market.tradableInstrument.instrument.metadata.tags
);
const closedMarketDate =
market.marketTimestamps.close && new Date(market.marketTimestamps.close);
let content = null;
if (!closeDate) {
content = closedMarketDate
? `Expired on ${getDateFormat().format(closedMarketDate)}`
: t('Not time-based');
} else {
const isExpired = Date.now() - closeDate.valueOf() > 0;
const expiryDate = getDateFormat().format(closeDate);
if (isExpired) {
content = closedMarketDate
? `Expired on ${getDateFormat().format(closedMarketDate)}`
: t('Expired');
} else {
content = expiryDate;
}
}
return content;
};
export const MarketExpires = ({
tags,
}: {
tags?: ReadonlyArray<string> | null;
}) => {
const date = getMarketExpiryDateFormatted(tags);
return date ? (
<div className="p-2 text-ui-small border border-pink text-pink inline-block">{`${date}`}</div>
) : null;
};

View File

@ -24,6 +24,7 @@ import { useEnvironment } from '@vegaprotocol/environment';
import { Link as UiToolkitLink } from '@vegaprotocol/ui-toolkit';
import Link from 'next/link';
import { AssetDetailsTable, useAssetDataProvider } from '@vegaprotocol/assets';
import { getMarketExpiryDateFormatted } from '../market-expires';
const Links = {
PROPOSAL_PAGE: ':tokenUrl/governance/:proposalId',
@ -224,6 +225,9 @@ export const Info = ({ market, onSelect }: InfoProps) => {
content: (
<MarketInfoTable
data={{
expiryDate: getMarketExpiryDateFormatted(
market.tradableInstrument.instrument.metadata.tags
),
...market.tradableInstrument.instrument.metadata.tags
?.map((tag) => {
const [key, value] = tag.split(':');