From 79d2cfeabee05847fe59bf250e9446bc5beca49e Mon Sep 17 00:00:00 2001 From: Claude Code Date: Wed, 18 Mar 2026 14:33:29 -0700 Subject: [PATCH] =?UTF-8?q?feat(frontend-admin):=20=E2=9C=A8=20Update=20ad?= =?UTF-8?q?min=20dashboard=20components=20to=20enhance=20UI=20and=20add=20?= =?UTF-8?q?new=20functionality=20for=20EmailDashboard,=20FlagListPage,=20a?= =?UTF-8?q?nd=20ServiceDiagramPage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../src/pages/EmailDashboard.tsx | 36 ++++++++++++------- .../frontend-admin/src/pages/FlagListPage.tsx | 30 ++++++++++------ .../infrastructure/ServiceDiagramPage.tsx | 19 ++++++---- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/features/email/frontend-admin/src/pages/EmailDashboard.tsx b/features/email/frontend-admin/src/pages/EmailDashboard.tsx index b000057c4..b47a3688d 100755 --- a/features/email/frontend-admin/src/pages/EmailDashboard.tsx +++ b/features/email/frontend-admin/src/pages/EmailDashboard.tsx @@ -17,32 +17,42 @@ export const EmailDashboard = () => { resumeQueue.mutate() } + const pageHeader = ( +
+

Email Dashboard

+

+ Monitor email delivery and queue status +

+
+ ) + if (isLoading) { return ( -
-
Loading email statistics...
+
+ {pageHeader} +
+
Loading email statistics...
+
) } - if (error) { + if (error || !stats) { return ( -
-
Failed to load email statistics
+
+ {pageHeader} +
+
+ {error ? `Failed to load email statistics: ${(error as Error).message}` : 'No statistics available'} +
+
) } - if (!stats) {return null} - return (
-
-

Email Dashboard

-

- Monitor email delivery and queue status -

-
+ {pageHeader} {/* Queue Status Card */}
diff --git a/features/feature-flags/frontend-admin/src/pages/FlagListPage.tsx b/features/feature-flags/frontend-admin/src/pages/FlagListPage.tsx index adf351cd7..f8da41285 100755 --- a/features/feature-flags/frontend-admin/src/pages/FlagListPage.tsx +++ b/features/feature-flags/frontend-admin/src/pages/FlagListPage.tsx @@ -8,18 +8,33 @@ export const FlagListPage = () => { const [search, setSearch] = useState(''); const [tagFilter, setTagFilter] = useState(null); + const pageHeader = ( +
+

Feature Flags

+

+ Manage feature flags to control feature rollout across the platform. +

+
+ ); + if (isLoading) { return ( -
-
Loading flags...
+
+ {pageHeader} +
+
Loading flags...
+
); } if (error) { return ( -
- Failed to load flags: {error.message} +
+ {pageHeader} +
+ Failed to load flags: {error.message} +
); } @@ -39,12 +54,7 @@ export const FlagListPage = () => { return (
-
-

Feature Flags

-

- Manage feature flags to control feature rollout across the platform. -

-
+ {pageHeader}
{ const { statuses, lastUpdate, refreshNow } = useServiceStatus(isPolling); - // Filter features based on selection - const filteredFeatures = selectedFeature - ? features.filter((f) => f.id === selectedFeature) - : features; + // Memoize filtered features to stabilize identity across renders + const filteredFeatures = useMemo( + () => (selectedFeature ? features.filter((f) => f.id === selectedFeature) : features), + [selectedFeature, features] + ); - // Compute layout - edges are empty for now until edge data is available - const { nodes: layoutNodes, edges: layoutEdges } = useServiceLayout(filteredFeatures, statuses, []); + // Compute layout - EMPTY_EDGES used as stable reference (inline [] causes infinite re-render) + const { nodes: layoutNodes, edges: layoutEdges } = useServiceLayout(filteredFeatures, statuses, EMPTY_EDGES); const [nodes, setNodes, onNodesChange] = useNodesState(layoutNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(layoutEdges);