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}
>
)}