diff --git a/packages/api/typings/app.ts b/packages/api/typings/app.ts index 7a7244d9..9bce9d04 100644 --- a/packages/api/typings/app.ts +++ b/packages/api/typings/app.ts @@ -202,9 +202,34 @@ export type UIConfig = Partial<{ miscLinks: Array; favIcon: FavIcon; locale: { lng?: string }; + dateFormats?: DateFormats; }>; export type FavIcon = { default: string; alternative: string; }; + +export type DateFormats = { + /** + * When timestamp is in same day (today) + * + * @example `hh:mm:ss` + * @see https://date-fns.org/v3.6.0/docs/format + */ + short?: string; + + /** + * When timestamp is in same year + * + * @example `MM-dd hh:mm:ss` + * @see https://date-fns.org/v3.6.0/docs/format + */ + common?: string; + + /** + * @example `yyyy-MM-dd hh:mm:ss` + * @see https://date-fns.org/v3.6.0/docs/format + */ + full?: string; +} diff --git a/packages/ui/src/components/JobCard/Timeline/Timeline.tsx b/packages/ui/src/components/JobCard/Timeline/Timeline.tsx index 94f98ce5..6b027d22 100644 --- a/packages/ui/src/components/JobCard/Timeline/Timeline.tsx +++ b/packages/ui/src/components/JobCard/Timeline/Timeline.tsx @@ -1,4 +1,4 @@ -import { formatDistance, getYear, isToday, differenceInMilliseconds } from 'date-fns'; +import { formatDistance, getYear, isToday, differenceInMilliseconds, format } from 'date-fns'; import enLocale from 'date-fns/locale/en-US'; import { TFunction } from 'i18next'; import React from 'react'; @@ -7,18 +7,29 @@ import { dateFnsLocale } from '../../../services/i18n'; import s from './Timeline.module.css'; import { AppJob, Status } from '@bull-board/api/typings/app'; import { STATUSES } from '@bull-board/api/src/constants/statuses'; +import { useUIConfig } from '../../../hooks/useUIConfig'; type TimeStamp = number | Date; const formatDate = (ts: TimeStamp, locale: string) => { + const uiConfig = useUIConfig(); + const dateFormats = uiConfig.dateFormats || {}; + let options: Intl.DateTimeFormatOptions; + if (isToday(ts)) { + if (dateFormats?.short) { + return format(new Date(ts), dateFormats.short) + } options = { hour: 'numeric', minute: 'numeric', second: 'numeric', }; } else if (getYear(ts) === getYear(new Date())) { + if (dateFormats?.common) { + return format(new Date(ts), dateFormats.common) + } options = { month: 'numeric', day: 'numeric', @@ -27,6 +38,9 @@ const formatDate = (ts: TimeStamp, locale: string) => { second: '2-digit', }; } else { + if (dateFormats?.full) { + return format(new Date(ts), dateFormats.full) + } options = { year: 'numeric', month: 'numeric',