feat: 1661 add market expiry date from metadata tags to market info and market header (#1739)
This commit is contained in:
parent
d674162e38
commit
fe472acfe9
@ -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
|
||||
}
|
||||
|
@ -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;
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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>;
|
||||
};
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './market-expires';
|
||||
export * from './market-info';
|
||||
|
1
libs/market-info/src/components/market-expires/index.ts
Normal file
1
libs/market-info/src/components/market-expires/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './market-expires';
|
@ -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();
|
||||
});
|
||||
});
|
@ -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;
|
||||
};
|
@ -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(':');
|
||||
|
Loading…
Reference in New Issue
Block a user