diff --git a/ui/src/components/ActivityFeedItem.tsx b/ui/src/components/ActivityFeedItem.tsx index 397979f3..3d0d80f6 100644 --- a/ui/src/components/ActivityFeedItem.tsx +++ b/ui/src/components/ActivityFeedItem.tsx @@ -41,15 +41,26 @@ export interface ActivityFeedItemProps { } /** - * Format timestamp for display + * Format timestamp for display. + * Returns both a full string ("about 5 hours ago") and a compact one ("5hrs ago"). */ -function formatTimestamp(timestamp?: string): string { - if (!timestamp) return 'Unknown time'; +function formatTimestamp(timestamp?: string): { full: string; compact: string } { + if (!timestamp) return { full: 'Unknown time', compact: 'Unknown' }; try { const date = new Date(timestamp); - return formatDistanceToNow(date, { addSuffix: true }); + const full = formatDistanceToNow(date, { addSuffix: true }); + // Compact: strip "about ", "less than ", "over ", abbreviate units + const compact = full + .replace(/^(about|less than|over|almost)\s+/i, '') + .replace(/\bminutes?\b/g, 'min') + .replace(/\bhours?\b/g, 'hrs') + .replace(/\bdays?\b/g, 'd') + .replace(/\bmonths?\b/g, 'mo') + .replace(/\byears?\b/g, 'yr') + .replace(/\s+ago$/, ' ago'); + return { full, compact }; } catch { - return timestamp; + return { full: timestamp, compact: timestamp }; } } @@ -204,7 +215,7 @@ export function ActivityFeedItem({
@@ -220,7 +231,7 @@ export function ActivityFeedItem({
{/* Summary */} -
+
- {/* Tenant badge */} - {tenant && ( -
- {tenantRenderer ? tenantRenderer(tenant) : } -
- )} + {/* Metadata row — sits below summary on mobile, inline on desktop */} +
+ {/* Tenant badge — truncates on narrow screens */} + {tenant && ( +
+ {tenantRenderer ? tenantRenderer(tenant) : } +
+ )} - {/* Timestamp */} - - {formatTimestamp(timestamp)} - + {/* Timestamp — compact on mobile, full on desktop */} + + {formatTimestamp(timestamp).compact} + + + {formatTimestamp(timestamp).full} + - {/* Expand toggle */} - + {/* Spacer pushes expand button to far right */} +
+ + {/* Expand toggle — always bottom-right */} + +
{/* Expanded Details */} @@ -279,12 +302,13 @@ export function ActivityFeedItem({ )} onClick={handleClick} > - {/* Single row layout */} -
+ {/* Feed row layout — wraps on mobile so summary gets full width */} +
{/* Actor Avatar */}
- {/* Summary - takes remaining space */} -
+ {/* Summary - full width on mobile, flex-1 on desktop */} +
- {/* Tenant badge */} - {tenant && ( -
- {tenantRenderer ? tenantRenderer(tenant) : } -
- )} + {/* Metadata row — sits below summary on mobile, inline on desktop */} +
+ {/* Tenant badge — truncates on narrow screens */} + {tenant && ( +
+ {tenantRenderer ? tenantRenderer(tenant) : } +
+ )} - {/* Timestamp */} - - {formatTimestamp(timestamp)} - + {/* Timestamp — compact on mobile, full on desktop */} + + {formatTimestamp(timestamp).compact} + + + {formatTimestamp(timestamp).full} + - {/* Expand button */} - + {/* Spacer pushes expand button to far right */} +
+ + {/* Expand button — always bottom-right */} + +
{/* Expanded Details */} diff --git a/ui/src/components/TenantBadge.tsx b/ui/src/components/TenantBadge.tsx index bfd56312..86483907 100644 --- a/ui/src/components/TenantBadge.tsx +++ b/ui/src/components/TenantBadge.tsx @@ -83,7 +83,7 @@ export function TenantBadge({ / - {tenant.name} + {tenant.name} )}