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(), {