diff --git a/frontend-modern/src/components/Kubernetes/K8sDeploymentsDrawer.tsx b/frontend-modern/src/components/Kubernetes/K8sDeploymentsDrawer.tsx index 6e02a52d9a..809295fb5f 100644 --- a/frontend-modern/src/components/Kubernetes/K8sDeploymentsDrawer.tsx +++ b/frontend-modern/src/components/Kubernetes/K8sDeploymentsDrawer.tsx @@ -16,6 +16,12 @@ import { } from '@/components/shared/Table'; import { EmptyState } from '@/components/shared/EmptyState'; import { buildKubernetesPath } from '@/routing/resourceLinks'; +import { + PLATFORM_TABLE_BODY_CLASS, + PLATFORM_TABLE_HEADER_ROW_CLASS, + getPlatformTableCellClassForKind, + getPlatformTableHeadClassForKind, +} from '@/features/platformPage/sharedPlatformPage'; import { getK8sDeploymentsDrawerPresentation, getK8sDeploymentsEmptyState, @@ -224,33 +230,41 @@ export const K8sDeploymentsDrawer: Component<{ } > - - - - +
+ + + {drawerPresentation.deploymentColumnLabel} - + {drawerPresentation.namespaceColumnLabel} - + {drawerPresentation.desiredColumnLabel} - + {drawerPresentation.updatedColumnLabel} - + {drawerPresentation.readyColumnLabel} - + {drawerPresentation.availableColumnLabel} - + {drawerPresentation.actionsColumnLabel} - + {(dep) => { const name = () => asTrimmedString(dep.name) || dep.id; @@ -262,8 +276,8 @@ export const K8sDeploymentsDrawer: Component<{ const status = () => getSimpleStatusIndicator(dep.status); return ( - - + +
- {ns()} - {desired()} - {updated()} - {ready()} - {available()} - + + + {ns()} + + + + {desired()} + + + {updated()} + + + {ready()} + + + {available()} + +
- - - +
+ + + {drawerPresentation.namespaceColumnLabel} - + {drawerPresentation.podsColumnLabel} - + {drawerPresentation.deploymentsColumnLabel} - + {drawerPresentation.actionsColumnLabel} - + {(row) => { const podIndicator = () => getNamespaceCountsIndicator(row.pods); return ( - - + +
- - {formatInteger(row.pods.total)} + + + {formatInteger(row.pods.total)} + {row.pods.offline > 0 ? `${formatInteger(row.pods.offline)} off` : ''} {row.pods.warning > 0 @@ -192,8 +206,10 @@ export const K8sNamespacesDrawer: Component<{ : ''} - - + + {formatInteger(row.deployments.total)} @@ -205,7 +221,7 @@ export const K8sNamespacesDrawer: Component<{ : ''} - +
), - TableHeader: (props: any) => {props.children}, + TableHeader: (props: any) => {props.children}, TableBody: (props: any) => {props.children}, TableRow: (props: any) => {props.children}, TableHead: (props: any) => {props.children}, @@ -190,6 +190,21 @@ describe('K8sDeploymentsDrawer', () => { expect(screen.getByText('2')).toBeInTheDocument(); }); + it('uses the shared platform table spacing and divider contract', async () => { + mockApiResponse([makeDeployment({ id: 'dep-1', name: 'web-frontend' })]); + const { container } = render(() => ); + + await waitFor(() => { + expect(screen.getByText('web-frontend')).toBeInTheDocument(); + }); + + expect(screen.getByTestId('table')).toHaveClass('table-fixed'); + expect(container.querySelector('thead tr')).toHaveClass('bg-surface-alt'); + expect(container.querySelector('tbody')).toHaveClass('divide-y', 'divide-border'); + expect(container.querySelector('tbody')).not.toHaveClass('divide-border-subtle'); + expect(container.querySelector('th')).toHaveClass('px-1.5', 'py-0.5'); + }); + it('uses deployment id as name when name is empty', async () => { const dep = makeDeployment({ id: 'dep-abc', name: '' }); mockApiResponse([dep]); diff --git a/frontend-modern/src/components/Kubernetes/__tests__/K8sNamespacesDrawer.test.tsx b/frontend-modern/src/components/Kubernetes/__tests__/K8sNamespacesDrawer.test.tsx index 9ce7013129..0ad2d89d36 100644 --- a/frontend-modern/src/components/Kubernetes/__tests__/K8sNamespacesDrawer.test.tsx +++ b/frontend-modern/src/components/Kubernetes/__tests__/K8sNamespacesDrawer.test.tsx @@ -61,6 +61,21 @@ describe('K8sNamespacesDrawer', () => { expect(navigateMock).toHaveBeenCalledWith('/kubernetes/pods'); }); + it('uses the shared platform table spacing and divider contract', async () => { + apiFetchJSONMock.mockResolvedValueOnce(makeResponse([{ namespace: 'default' }])); + const { container } = render(() => ); + + await waitFor(() => { + expect(screen.getByText('default')).toBeInTheDocument(); + }); + + expect(container.querySelector('table')).toHaveClass('table-fixed'); + expect(container.querySelector('thead tr')).toHaveClass('bg-surface-alt'); + expect(container.querySelector('tbody')).toHaveClass('divide-y', 'divide-border'); + expect(container.querySelector('tbody')).not.toHaveClass('divide-border-subtle'); + expect(container.querySelector('th')).toHaveClass('px-1.5', 'py-0.5'); + }); + it('does not navigate when cluster is empty', async () => { render(() => );