From 08fd58aa9a0a1fc8d8b2ffd3098db388a014adf4 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Fri, 12 Dec 2025 11:18:49 +0000 Subject: [PATCH 1/3] Toggle status page date format between 12hr and 24hr --- .../pages/status/date-format-selection.vue | 20 +++++++++++ site/frontend/src/pages/status/page.vue | 35 +++++++++++++++++-- site/frontend/src/utils/formatting.ts | 17 +++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 site/frontend/src/pages/status/date-format-selection.vue diff --git a/site/frontend/src/pages/status/date-format-selection.vue b/site/frontend/src/pages/status/date-format-selection.vue new file mode 100644 index 000000000..ea730b934 --- /dev/null +++ b/site/frontend/src/pages/status/date-format-selection.vue @@ -0,0 +1,20 @@ + + + diff --git a/site/frontend/src/pages/status/page.vue b/site/frontend/src/pages/status/page.vue index 0f91fa89a..983b0bd18 100644 --- a/site/frontend/src/pages/status/page.vue +++ b/site/frontend/src/pages/status/page.vue @@ -9,6 +9,10 @@ import { formatISODate, formatSecondsAsDuration, parseDateIsoStringOrNull, + setDateFmt, + getDateFmt, + DATE_FMT_12HR, + DATE_FMT_24HR, } from "../../utils/formatting"; import {useExpandedStore} from "../../utils/expansion"; import { @@ -20,6 +24,7 @@ import { } from "./data"; import Collector from "./collector.vue"; import CommitSha from "./commit-sha.vue"; +import DateFmtPicker from "./date-format-selection.vue"; const loading = ref(true); @@ -27,6 +32,7 @@ const data: Ref<{ timeline: BenchmarkRequestRow[]; queueLength: number; collectors: CollectorConfig[]; + dateFmt: string; } | null> = ref(null); type BenchmarkRequestRow = BenchmarkRequest & { @@ -77,6 +83,7 @@ async function loadStatusData(loading: Ref) { timeline, collectors: resp.collectors, queueLength, + dateFmt: getDateFmt(), }; }); } @@ -101,6 +108,11 @@ function formatStatus(request: BenchmarkRequest): string { } } +function formatDate(dateString?: string): string { + const fmt = data.value.dateFmt; + return formatISODate(dateString, fmt); +} + function hasErrors(request: BenchmarkRequest) { return Object.keys(request.errors).length !== 0; } @@ -204,6 +216,17 @@ const {toggleExpanded: toggleExpandedErrors, isExpanded: hasExpandedErrors} = const tableWidth = 8; +function toggleDate() { + let dateFmt: string; + if (data.value.dateFmt === DATE_FMT_24HR) { + dateFmt = DATE_FMT_12HR; + } else { + dateFmt = DATE_FMT_24HR; + } + setDateFmt(dateFmt); + data.value.dateFmt = dateFmt; +} + loadStatusData(loading); @@ -212,8 +235,9 @@ loadStatusData(loading);

Timeline

- + Times are local. + @@ -256,7 +280,7 @@ loadStatusData(loading); /> - {{ formatISODate(req.completedAt) }} + {{ formatDate(req.completedAt) }} (est.) @@ -421,4 +445,11 @@ loadStatusData(loading); .small-padding-bottom { padding-bottom: 8px; } + +.local-time-message { + display: flex; + flex-direction: column; + align-items: center; + padding-bottom: 12px; +} diff --git a/site/frontend/src/utils/formatting.ts b/site/frontend/src/utils/formatting.ts index 16e5fdf96..bc341a759 100644 --- a/site/frontend/src/utils/formatting.ts +++ b/site/frontend/src/utils/formatting.ts @@ -20,10 +20,23 @@ export function formatSecondsAsDuration(time: number): string { return s; } +export const DATE_FMT_KEY = "__rustc-perf-user-date-fmt-preference__"; +export const DATE_FMT_24HR = "yyyy-MM-dd HH:mm:ss"; +export const DATE_FMT_12HR = "yyyy-MM-dd pp"; + +export function setDateFmt(dateFmt: string) { + window.localStorage.setItem(DATE_FMT_KEY, dateFmt); +} + +export function getDateFmt() { + return window.localStorage.getItem(DATE_FMT_KEY) ?? DATE_FMT_24HR; +} + // Takes a date like `2025-09-10T08:22:47.161348Z` -> `"2025-09-10 08:22:47"` -export function formatISODate(dateString?: string): string { +export function formatISODate(dateString?: string, fmt?: string): string { if (dateString) { - return format(parseISO(dateString), "yyyy-MM-dd HH:mm:ss"); + const dateFmt = fmt ?? getDateFmt(); + return format(parseISO(dateString), dateFmt); } return ""; } From 98d672d9dce4282db5374c2061e3501a46b4b716 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 17 Dec 2025 08:26:08 +0000 Subject: [PATCH 2/3] PR Feedback; date fmt update and better comments --- site/frontend/src/utils/formatting.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/site/frontend/src/utils/formatting.ts b/site/frontend/src/utils/formatting.ts index bc341a759..30eb1e520 100644 --- a/site/frontend/src/utils/formatting.ts +++ b/site/frontend/src/utils/formatting.ts @@ -21,8 +21,9 @@ export function formatSecondsAsDuration(time: number): string { } export const DATE_FMT_KEY = "__rustc-perf-user-date-fmt-preference__"; +// Date formats taken from https://date-fns.org/v4.1.0/docs/format export const DATE_FMT_24HR = "yyyy-MM-dd HH:mm:ss"; -export const DATE_FMT_12HR = "yyyy-MM-dd pp"; +export const DATE_FMT_12HR = "yyyy-MM-dd hh:mm:ss a"; export function setDateFmt(dateFmt: string) { window.localStorage.setItem(DATE_FMT_KEY, dateFmt); @@ -32,10 +33,11 @@ export function getDateFmt() { return window.localStorage.getItem(DATE_FMT_KEY) ?? DATE_FMT_24HR; } -// Takes a date like `2025-09-10T08:22:47.161348Z` -> `"2025-09-10 08:22:47"` -export function formatISODate(dateString?: string, fmt?: string): string { +// Takes a date like `2025-09-10T08:22:47.161348Z` and formats it according to +// the user preference stored in local storage (either 12 hour or 24 hour format). +export function formatISODate(dateString?: string): string { if (dateString) { - const dateFmt = fmt ?? getDateFmt(); + const dateFmt = getDateFmt(); return format(parseISO(dateString), dateFmt); } return ""; From c9432107f87f83b54b4cc05a6a76fc04e0fbca7c Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 17 Dec 2025 08:34:23 +0000 Subject: [PATCH 3/3] PR Feedback; try without VUE state, did not work so split out --- site/frontend/src/pages/status/page.vue | 28 ++++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/site/frontend/src/pages/status/page.vue b/site/frontend/src/pages/status/page.vue index 983b0bd18..cd5af192d 100644 --- a/site/frontend/src/pages/status/page.vue +++ b/site/frontend/src/pages/status/page.vue @@ -32,9 +32,13 @@ const data: Ref<{ timeline: BenchmarkRequestRow[]; queueLength: number; collectors: CollectorConfig[]; - dateFmt: string; } | null> = ref(null); +// This state exists so the UI immediately update when a user changes their +// date format preference. As only setting Local Storage does not trigger a +// re-render. +const dateFmt: Ref = ref(getDateFmt()); + type BenchmarkRequestRow = BenchmarkRequest & { isLastInProgress: boolean; hasPendingJobs: boolean; @@ -83,7 +87,6 @@ async function loadStatusData(loading: Ref) { timeline, collectors: resp.collectors, queueLength, - dateFmt: getDateFmt(), }; }); } @@ -108,11 +111,6 @@ function formatStatus(request: BenchmarkRequest): string { } } -function formatDate(dateString?: string): string { - const fmt = data.value.dateFmt; - return formatISODate(dateString, fmt); -} - function hasErrors(request: BenchmarkRequest) { return Object.keys(request.errors).length !== 0; } @@ -217,14 +215,14 @@ const {toggleExpanded: toggleExpandedErrors, isExpanded: hasExpandedErrors} = const tableWidth = 8; function toggleDate() { - let dateFmt: string; - if (data.value.dateFmt === DATE_FMT_24HR) { - dateFmt = DATE_FMT_12HR; + let nextDateFmt: string; + if (dateFmt.value === DATE_FMT_24HR) { + nextDateFmt = DATE_FMT_12HR; } else { - dateFmt = DATE_FMT_24HR; + nextDateFmt = DATE_FMT_24HR; } - setDateFmt(dateFmt); - data.value.dateFmt = dateFmt; + setDateFmt(nextDateFmt); + dateFmt.value = nextDateFmt; } loadStatusData(loading); @@ -237,7 +235,7 @@ loadStatusData(loading);

Timeline

Times are local. - + @@ -280,7 +278,7 @@ loadStatusData(loading); /> - {{ formatDate(req.completedAt) }} + {{ formatISODate(req.completedAt) }} (est.)