diff --git a/webui/src/features/admin/ModuleManagementPanel.tsx b/webui/src/features/admin/ModuleManagementPanel.tsx
index d506a92..a63c9f5 100644
--- a/webui/src/features/admin/ModuleManagementPanel.tsx
+++ b/webui/src/features/admin/ModuleManagementPanel.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import type { ApiSettings } from "@govoplan/core-webui";
-import { AdminPageLayout, adminErrorMessage, Button, dispatchPlatformModulesChanged, MetricCard, StatusBadge, ToggleSwitch, i18nMessage, useUnsavedDraftGuard } from "@govoplan/core-webui";
+import { AdminPageLayout, adminErrorMessage, Button, dispatchPlatformModulesChanged, formatDateTime, MetricCard, StatusBadge, ToggleSwitch, i18nMessage, useUnsavedDraftGuard, type FormatDateTimeOptions } from "@govoplan/core-webui";
import {
cancelModuleInstallerRequest,
clearModuleInstallPlan,
@@ -596,10 +596,10 @@ export default function ModuleManagementPanel({ settings, canWrite, canAccessMai
- i18n:govoplan-admin.created.0c78dab1 {formatDateTime(request.created_at)}
- i18n:govoplan-admin.started.fe3824e9 {formatDateTime(request.started_at)}
- i18n:govoplan-admin.finished.4b52fe3f {formatDateTime(request.finished_at)}
- {request.cancelled_at && i18n:govoplan-admin.cancelled.8c9dcfa8 {formatDateTime(request.cancelled_at)}}
+ i18n:govoplan-admin.created.0c78dab1 {formatDateTime(request.created_at, ADMIN_DATE_TIME_OPTIONS)}
+ i18n:govoplan-admin.started.fe3824e9 {formatDateTime(request.started_at, ADMIN_DATE_TIME_OPTIONS)}
+ i18n:govoplan-admin.finished.4b52fe3f {formatDateTime(request.finished_at, ADMIN_DATE_TIME_OPTIONS)}
+ {request.cancelled_at && i18n:govoplan-admin.cancelled.8c9dcfa8 {formatDateTime(request.cancelled_at, ADMIN_DATE_TIME_OPTIONS)}}
{request.retry_of && i18n:govoplan-admin.retry_of.3a6bb304 {request.retry_of}}
{traceId(request.trace) && i18n:govoplan-admin.trace.04a75036 {traceId(request.trace)}}
@@ -639,8 +639,8 @@ export default function ModuleManagementPanel({ settings, canWrite, canAccessMai
{run.request_id && i18n:govoplan-admin.request.43c2e7a7 {run.request_id}}
{traceId(run.trace) && i18n:govoplan-admin.trace.04a75036 {traceId(run.trace)}}
i18n:govoplan-admin.commands.f6a34aed {run.commands_count}
- i18n:govoplan-admin.started.fe3824e9 {formatDateTime(run.started_at)}
- i18n:govoplan-admin.finished.4b52fe3f {formatDateTime(run.finished_at)}
+ i18n:govoplan-admin.started.fe3824e9 {formatDateTime(run.started_at, ADMIN_DATE_TIME_OPTIONS)}
+ i18n:govoplan-admin.finished.4b52fe3f {formatDateTime(run.finished_at, ADMIN_DATE_TIME_OPTIONS)}
{run.error && {run.error}
}
@@ -665,7 +665,7 @@ function LicenseStatus({ license }: {license: ModuleLicenseDiagnostics;}) {
{label}
- i18n:govoplan-admin.valid.b374b8f9 {formatDateTime(license.valid_from)} to {formatDateTime(license.valid_until)}
+ i18n:govoplan-admin.valid.b374b8f9 {formatDateTime(license.valid_from, ADMIN_DATE_TIME_OPTIONS)} to {formatDateTime(license.valid_until, ADMIN_DATE_TIME_OPTIONS)}
i18n:govoplan-admin.features.5df81ffa {license.features.length ? license.features.join(", ") : "none"}
{license.required_features.length > 0 && i18n:govoplan-admin.required.d5793988 {license.required_features.join(", ")}}
{license.missing_features.length > 0 && i18n:govoplan-admin.missing.feb2bbaa {license.missing_features.join(", ")}}
@@ -847,12 +847,16 @@ function licenseLabel(license: ModuleLicenseDiagnostics): string {
return "i18n:govoplan-admin.unsigned.e91344ea";
}
-function formatDateTime(value?: string | null): string {
- if (!value) return "i18n:govoplan-admin.not_recorded.9925ee3c";
- const date = new Date(value);
- if (Number.isNaN(date.getTime())) return value;
- return date.toLocaleString();
-}
+const ADMIN_DATE_TIME_OPTIONS: FormatDateTimeOptions = {
+ fallback: "i18n:govoplan-admin.not_recorded.9925ee3c",
+ year: "numeric",
+ month: "numeric",
+ day: "numeric",
+ hour: "numeric",
+ minute: "numeric",
+ second: "numeric",
+ timeZoneName: undefined
+};
function traceId(value?: Record | null): string {
const correlationId = value?.correlation_id;