refactor(webui): use Core date-time formatting
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
DismissibleAlert,
|
||||
ExplorerTree,
|
||||
fetchAuthGroups,
|
||||
formatDateTime,
|
||||
FormField,
|
||||
LoadingFrame,
|
||||
PasswordField,
|
||||
@@ -19,7 +20,8 @@ import {
|
||||
hasScope,
|
||||
type ApiSettings,
|
||||
type AuthInfo,
|
||||
type AuthUpdate
|
||||
type AuthUpdate,
|
||||
type FormatDateTimeOptions
|
||||
} from "@govoplan/core-webui";
|
||||
import {
|
||||
createAddressBook,
|
||||
@@ -291,14 +293,17 @@ function syncSourceLabel(source: AddressSyncSource): string {
|
||||
return source.display_name || source.external_address_book_ref || source.connector_type;
|
||||
}
|
||||
|
||||
function formatDateTime(value?: string | null): string {
|
||||
if (!value) return "Never";
|
||||
try {
|
||||
return new Intl.DateTimeFormat(undefined, { dateStyle: "short", timeStyle: "short" }).format(new Date(value));
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
const ADDRESS_DATE_TIME_OPTIONS: FormatDateTimeOptions = {
|
||||
fallback: "Never",
|
||||
year: undefined,
|
||||
month: undefined,
|
||||
day: undefined,
|
||||
hour: undefined,
|
||||
minute: undefined,
|
||||
timeZoneName: undefined,
|
||||
dateStyle: "short",
|
||||
timeStyle: "short"
|
||||
};
|
||||
|
||||
function planSummary(plan: AddressSyncPlan | null): string {
|
||||
if (!plan) return "No preview loaded.";
|
||||
@@ -1740,7 +1745,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
{selectedBookSyncSources.map((source) => (
|
||||
<p key={source.id}>
|
||||
{syncSourceLabel(source)} · {source.connector_type} · {source.status}
|
||||
{source.last_success_at ? ` · last success ${formatDateTime(source.last_success_at)}` : ""}
|
||||
{source.last_success_at ? ` · last success ${formatDateTime(source.last_success_at, ADDRESS_DATE_TIME_OPTIONS)}` : ""}
|
||||
{source.last_error ? ` · ${source.last_error}` : ""}
|
||||
</p>
|
||||
))}
|
||||
@@ -2314,7 +2319,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
<StatusBadge status={syncInspector.source.status} />
|
||||
{syncInspector.source.read_only && <StatusBadge status="read-only" />}
|
||||
</div>
|
||||
<p className="muted">Last attempt: {formatDateTime(syncInspector.source.last_attempted_at)} · Last success: {formatDateTime(syncInspector.source.last_success_at)}</p>
|
||||
<p className="muted">Last attempt: {formatDateTime(syncInspector.source.last_attempted_at, ADDRESS_DATE_TIME_OPTIONS)} · Last success: {formatDateTime(syncInspector.source.last_success_at, ADDRESS_DATE_TIME_OPTIONS)}</p>
|
||||
{syncInspector.source.last_error && <DismissibleAlert tone="danger" resetKey={syncInspector.source.last_error}>{syncInspector.source.last_error}</DismissibleAlert>}
|
||||
<div className="button-row compact-actions">
|
||||
<Button
|
||||
@@ -2383,7 +2388,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
<div className="address-sync-record-list">
|
||||
{syncTombstones.slice(0, 20).map((tombstone) => (
|
||||
<div className="address-sync-record-row" key={tombstone.id}>
|
||||
<span><strong>{tombstone.remote_uid || tombstone.resource_href || tombstone.contact_id}</strong><small>{formatDateTime(tombstone.synced_at || tombstone.remote_deleted_at || tombstone.local_deleted_at)}</small></span>
|
||||
<span><strong>{tombstone.remote_uid || tombstone.resource_href || tombstone.contact_id}</strong><small>{formatDateTime(tombstone.synced_at || tombstone.remote_deleted_at || tombstone.local_deleted_at, ADDRESS_DATE_TIME_OPTIONS)}</small></span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user