From b615e019b14b87ac01841d06e37193fbb3b638d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Tue, 25 Oct 2022 19:37:01 +0200 Subject: [PATCH] chore: improve data time formatting in token app (#1722) * chore: improve data time formatting in token app * chore: handle wrong date in network stats fields --- ...-form-vote-and-enactment-deadline.spec.tsx | 28 +++++++++------- ...posal-form-vote-and-enactment-deadline.tsx | 7 ++-- libs/network-stats/src/config/stats-fields.ts | 32 ++++++++++++++++--- libs/react-helpers/src/lib/format/date.ts | 3 ++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.spec.tsx b/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.spec.tsx index 8652bd64d..2d2824f5f 100644 --- a/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.spec.tsx +++ b/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.spec.tsx @@ -1,6 +1,13 @@ import { render, screen, fireEvent, act } from '@testing-library/react'; import { ProposalFormVoteAndEnactmentDeadline } from './proposal-form-vote-and-enactment-deadline'; +jest.mock('@vegaprotocol/react-helpers', () => ({ + ...jest.requireActual('@vegaprotocol/react-helpers'), + getDateTimeFormat: jest.fn(() => ({ + format: (date: Date) => date.toISOString(), + })), +})); + beforeEach(() => { jest.useFakeTimers(); jest.setSystemTime(new Date('2022-01-01T00:00:00.000Z')); @@ -19,7 +26,6 @@ const maxEnactDeadline = '4h0m0s'; * Formats date according to locale. * @param expected Use format: YYYY-MM-DDThh:mm:ss.000Z */ -const expectedDate = (expected: string) => new Date(expected).toLocaleString(); const renderComponent = () => { const register = jest.fn(); @@ -142,13 +148,13 @@ describe('Proposal form vote, validation and enactment deadline', () => { // Should be adding 2 mins to the vote deadline as the minimum is set by // default, and we add 2 mins for wallet confirmation expect(screen.getByTestId('voting-date')).toHaveTextContent( - expectedDate('2022-01-01T01:02:00.000Z') + '2022-01-01T01:02:00.000Z' ); expect(screen.getByTestId('validation-date')).toHaveTextContent( - expectedDate('2022-01-01T00:02:00.000Z') + '2022-01-01T00:02:00.000Z' ); expect(screen.getByTestId('enactment-date')).toHaveTextContent( - expectedDate('2022-01-01T02:00:00.000Z') + '2022-01-01T02:00:00.000Z' ); }); @@ -159,13 +165,13 @@ describe('Proposal form vote, validation and enactment deadline', () => { }); expect(screen.getByTestId('voting-date')).toHaveTextContent( - expectedDate('2022-01-01T01:02:30.000Z') + '2022-01-01T01:02:30.000Z' ); expect(screen.getByTestId('validation-date')).toHaveTextContent( - expectedDate('2022-01-01T00:02:30.000Z') + '2022-01-01T00:02:30.000Z' ); expect(screen.getByTestId('enactment-date')).toHaveTextContent( - expectedDate('2022-01-01T02:00:30.000Z') + '2022-01-01T02:00:30.000Z' ); }); @@ -174,10 +180,10 @@ describe('Proposal form vote, validation and enactment deadline', () => { const voteDeadlineInput = screen.getByTestId('proposal-vote-deadline'); fireEvent.change(voteDeadlineInput, { target: { value: 2 } }); expect(screen.getByTestId('voting-date')).toHaveTextContent( - expectedDate('2022-01-01T02:00:00.000Z') + '2022-01-01T02:00:00.000Z' ); expect(screen.getByTestId('enactment-date')).toHaveTextContent( - expectedDate('2022-01-01T03:00:00.000Z') + '2022-01-01T03:00:00.000Z' ); }); @@ -192,12 +198,12 @@ describe('Proposal form vote, validation and enactment deadline', () => { fireEvent.click(voteDeadlineMaxButton); fireEvent.click(validationDeadlineMaxButton); expect(screen.getByTestId('validation-date')).toHaveTextContent( - expectedDate('2022-01-01T05:00:00.000Z') + '2022-01-01T05:00:00.000Z' ); expect(validationDeadlineInput).toHaveValue(5); fireEvent.click(voteDeadlineMinButton); expect(screen.getByTestId('validation-date')).toHaveTextContent( - expectedDate('2022-01-01T01:00:00.000Z') + '2022-01-01T01:00:00.000Z' ); expect(validationDeadlineInput).toHaveValue(1); }); diff --git a/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.tsx b/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.tsx index ffc2637e1..a1da96410 100644 --- a/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.tsx +++ b/apps/token/src/routes/governance/components/propose/proposal-form-vote-and-enactment-deadline.tsx @@ -6,6 +6,7 @@ import { Input, InputError, } from '@vegaprotocol/ui-toolkit'; +import { getDateTimeFormat } from '@vegaprotocol/react-helpers'; import { addHours, addMinutes } from 'date-fns'; import { deadlineToSeconds, @@ -109,7 +110,7 @@ const ValidationForm = ({ {t('ThisWillSetValidationDeadlineTo')} - {deadlineDates.validation.toLocaleString()} + {getDateTimeFormat().format(deadlineDates.validation)} {deadlines.validation === 0 && ( - {deadlineDates.enactment.toLocaleString()} + {getDateTimeFormat().format(deadlineDates.enactment)}

)} @@ -454,7 +455,7 @@ export function ProposalFormVoteAndEnactmentDeadline({ {t('ThisWillSetVotingDeadlineTo')}
- {deadlineDates.vote.toLocaleString()} + {getDateTimeFormat().format(deadlineDates.vote)} {deadlines.vote === minVoteHours && ( new Date(time).toLocaleTimeString(), + formatter: (time: Date) => { + if (!time) { + return; + } + const date = new Date(time); + if (!isValidDate(date)) { + return; + } + return getTimeFormat().format(date); + }, goodThreshold: (time: Date) => { const diff = new Date().getTime() - new Date(time).getTime(); return diff > 0 && diff < 5000; @@ -147,8 +162,11 @@ export const statsFields: { [key in keyof Stats]: StatFields[] } = { if (!t) { return; } - const secSinceStart = - (new Date().getTime() - new Date(t).getTime()) / 1000; + const date = new Date(t); + if (!isValidDate(date)) { + return; + } + const secSinceStart = (new Date().getTime() - date.getTime()) / 1000; const days = Math.floor(secSinceStart / 60 / 60 / 24); const hours = Math.floor((secSinceStart / 60 / 60) % 24); const mins = Math.floor((secSinceStart / 60) % 60); @@ -164,7 +182,11 @@ export const statsFields: { [key in keyof Stats]: StatFields[] } = { if (!t) { return; } - return `${new Date(t).toLocaleString().replace(',', ' ')}`; + const date = new Date(t); + if (!isValidDate(date)) { + return; + } + return getDateTimeFormat().format(date); }, description: t('Genesis'), }, diff --git a/libs/react-helpers/src/lib/format/date.ts b/libs/react-helpers/src/lib/format/date.ts index b06a71002..3bc6c39da 100644 --- a/libs/react-helpers/src/lib/format/date.ts +++ b/libs/react-helpers/src/lib/format/date.ts @@ -1,6 +1,9 @@ import once from 'lodash/once'; import { getUserLocale } from './utils'; +export const isValidDate = (date: Date) => + date instanceof Date && !isNaN(date.getTime()); + export const getTimeFormat = once( () => new Intl.DateTimeFormat(getUserLocale(), {