diff --git a/lms/static/scripts/frontend_apps/components/dashboard/DashboardActivityFilters.tsx b/lms/static/scripts/frontend_apps/components/dashboard/DashboardActivityFilters.tsx index 651de83d13..0cc31a9e00 100644 --- a/lms/static/scripts/frontend_apps/components/dashboard/DashboardActivityFilters.tsx +++ b/lms/static/scripts/frontend_apps/components/dashboard/DashboardActivityFilters.tsx @@ -2,6 +2,7 @@ import { FilterClearIcon, LinkButton, MultiSelect, + formatDateTime, } from '@hypothesis/frontend-shared'; import classnames from 'classnames'; import type { MutableRef } from 'preact/hooks'; @@ -19,7 +20,6 @@ import type { } from '../../api-types'; import { useConfig } from '../../config'; import { usePaginatedAPIFetch } from '../../utils/api'; -import { formatDateTime } from '../../utils/date'; import PaginatedMultiSelect from './PaginatedMultiSelect'; /** diff --git a/lms/static/scripts/frontend_apps/components/dashboard/FormattedDate.tsx b/lms/static/scripts/frontend_apps/components/dashboard/FormattedDate.tsx index 7643e14c62..d05f74a7d9 100644 --- a/lms/static/scripts/frontend_apps/components/dashboard/FormattedDate.tsx +++ b/lms/static/scripts/frontend_apps/components/dashboard/FormattedDate.tsx @@ -1,7 +1,6 @@ +import { formatDateTime } from '@hypothesis/frontend-shared'; import { useMemo } from 'preact/hooks'; -import { formatDateTime } from '../../utils/date'; - export type FormattedDateProps = { /** Date in ISO format */ date: string; diff --git a/lms/static/scripts/frontend_apps/components/dashboard/test/AllCoursesActivity-test.js b/lms/static/scripts/frontend_apps/components/dashboard/test/AllCoursesActivity-test.js index c474dbe728..7169bcfe72 100644 --- a/lms/static/scripts/frontend_apps/components/dashboard/test/AllCoursesActivity-test.js +++ b/lms/static/scripts/frontend_apps/components/dashboard/test/AllCoursesActivity-test.js @@ -1,3 +1,4 @@ +import { formatDateTime } from '@hypothesis/frontend-shared'; import { checkAccessibility, mockImportedComponents, @@ -7,7 +8,6 @@ import { act } from 'preact/test-utils'; import sinon from 'sinon'; import { Config } from '../../../config'; -import { formatDateTime } from '../../../utils/date'; import AllCoursesActivity, { $imports } from '../AllCoursesActivity'; describe('AllCoursesActivity', () => { diff --git a/lms/static/scripts/frontend_apps/components/dashboard/test/AssignmentActivity-test.js b/lms/static/scripts/frontend_apps/components/dashboard/test/AssignmentActivity-test.js index 1bbcfc1429..eaff7b663d 100644 --- a/lms/static/scripts/frontend_apps/components/dashboard/test/AssignmentActivity-test.js +++ b/lms/static/scripts/frontend_apps/components/dashboard/test/AssignmentActivity-test.js @@ -1,3 +1,4 @@ +import { formatDateTime } from '@hypothesis/frontend-shared'; import { checkAccessibility, mockImportedComponents, @@ -7,7 +8,6 @@ import { act } from 'preact/test-utils'; import sinon from 'sinon'; import { Config } from '../../../config'; -import { formatDateTime } from '../../../utils/date'; import AssignmentActivity, { $imports } from '../AssignmentActivity'; describe('AssignmentActivity', () => { diff --git a/lms/static/scripts/frontend_apps/components/dashboard/test/DashboardActivityFilters-test.js b/lms/static/scripts/frontend_apps/components/dashboard/test/DashboardActivityFilters-test.js index efe0de3fb1..7c90ee3bf2 100644 --- a/lms/static/scripts/frontend_apps/components/dashboard/test/DashboardActivityFilters-test.js +++ b/lms/static/scripts/frontend_apps/components/dashboard/test/DashboardActivityFilters-test.js @@ -1,4 +1,5 @@ import { MultiSelect } from '@hypothesis/frontend-shared'; +import { formatDateTime } from '@hypothesis/frontend-shared'; import { checkAccessibility, mockImportedComponents, @@ -7,7 +8,6 @@ import { mount } from 'enzyme'; import sinon from 'sinon'; import { Config } from '../../../config'; -import { formatDateTime } from '../../../utils/date'; import DashboardActivityFilters, { $imports, } from '../DashboardActivityFilters'; diff --git a/lms/static/scripts/frontend_apps/utils/date.ts b/lms/static/scripts/frontend_apps/utils/date.ts deleted file mode 100644 index 495b93ca83..0000000000 --- a/lms/static/scripts/frontend_apps/utils/date.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Map of stringified `DateTimeFormatOptions` to cached `DateTimeFormat` instances. - */ -let formatters = new Map(); - -/** - * Clears the cache of formatters. - */ -export function clearFormatters() { - formatters = new Map(); -} - -type IntlType = typeof window.Intl; - -/** - * Return date string formatted with `options`. - * - * This is a caching wrapper for `Intl.DateTimeFormat.format`, useful because - * constructing a `DateTimeFormat` is expensive. - * - * @param Intl - Test seam. JS `Intl` API implementation. - */ -function format( - date: Date, - options: Intl.DateTimeFormatOptions, - /* istanbul ignore next */ - Intl: IntlType = window.Intl, -): string { - const key = JSON.stringify(options); - let formatter = formatters.get(key); - if (!formatter) { - formatter = new Intl.DateTimeFormat(undefined, options); - formatters.set(key, formatter); - } - return formatter.format(date); -} - -/** - * Formats a date as an absolute string in a human-readable format. - * - * The exact format will vary depending on the locale, but the verbosity will - * be consistent across locales. In en-US for example this will look like: - * - * "Dec 17, 2017, 10:00 AM" - * - * @param Intl - Test seam. JS `Intl` API implementation. - */ -export function formatDateTime(date: Date | string, Intl?: IntlType): string { - return format( - typeof date === 'string' ? new Date(date) : date, - { - year: 'numeric', - month: 'short', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - }, - Intl, - ); -} diff --git a/lms/static/scripts/frontend_apps/utils/test/date-test.js b/lms/static/scripts/frontend_apps/utils/test/date-test.js deleted file mode 100644 index 2fd732b4f5..0000000000 --- a/lms/static/scripts/frontend_apps/utils/test/date-test.js +++ /dev/null @@ -1,46 +0,0 @@ -import { clearFormatters, formatDateTime } from '../date'; - -describe('date', () => { - let sandbox; - - beforeEach(() => { - sandbox = sinon.createSandbox(); - sandbox.useFakeTimers(); - - // Clear the formatters cache so that mocked formatters - // from one test run don't affect the next. - clearFormatters(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('formatDateTime', () => { - // Normalize "special" spaces (eg. "\u202F") to standard spaces. - function normalizeSpaces(str) { - return str.normalize('NFKC'); - } - - it('returns absolute formatted date', () => { - const date = new Date('2020-05-04T23:02:01'); - const fakeIntl = locale => ({ - DateTimeFormat: function (_, options) { - return new Intl.DateTimeFormat(locale, options); - }, - }); - - assert.equal( - normalizeSpaces(formatDateTime(date, fakeIntl('en-US'))), - 'May 04, 2020, 11:02 PM', - ); - - clearFormatters(); - - assert.equal( - normalizeSpaces(formatDateTime(date, fakeIntl('de-DE'))), - '04. Mai 2020, 23:02', - ); - }); - }); -}); diff --git a/package.json b/package.json index f740b777da..d1ff83dde1 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@babel/preset-react": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@hypothesis/frontend-build": "^3.0.0", - "@hypothesis/frontend-shared": "^8.5.0", + "@hypothesis/frontend-shared": "^8.7.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-node-resolve": "^15.3.0", diff --git a/yarn.lock b/yarn.lock index 369c1b9715..aedf177659 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2169,15 +2169,15 @@ __metadata: languageName: node linkType: hard -"@hypothesis/frontend-shared@npm:^8.5.0": - version: 8.5.0 - resolution: "@hypothesis/frontend-shared@npm:8.5.0" +"@hypothesis/frontend-shared@npm:^8.7.0": + version: 8.7.0 + resolution: "@hypothesis/frontend-shared@npm:8.7.0" dependencies: highlight.js: ^11.6.0 wouter-preact: ^3.0.0 peerDependencies: preact: ^10.4.0 - checksum: 4d01b2f07dc44173351e3e72f9607b54596468d620a0f872fe851776ad5c77dce5ec631fdfe77654c6851f9a24a3701a5bbf0df78bf4ceff580ace73a86bd91a + checksum: 646087a5d592080e7bdd336ecd18df047450b15c3410b4bd39b36a41702bfcdbbf39b378ad3a17a2442b825dfc0500d10c25be24b6c2a9d814052f33d3e2fe11 languageName: node linkType: hard @@ -7412,7 +7412,7 @@ __metadata: "@babel/preset-react": ^7.24.7 "@babel/preset-typescript": ^7.24.7 "@hypothesis/frontend-build": ^3.0.0 - "@hypothesis/frontend-shared": ^8.5.0 + "@hypothesis/frontend-shared": ^8.7.0 "@hypothesis/frontend-testing": ^1.2.2 "@rollup/plugin-babel": ^6.0.4 "@rollup/plugin-commonjs": ^28.0.0