From a6c9dfe93f585fd5e93d7999035aff3f47dea6ef Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Fri, 26 Apr 2024 16:26:19 +0200 Subject: [PATCH] frontend: Use new Table component in the ResourceTable Replaces SimpleTable with the new Table component. Out of the box ResourceTable will enable sorting and filtering on all columns. To provide that functionality 'getter' in the column definition has to provide a plaintext value (but will keep working if it returns jsx for compatibility reasons). e2e and snapshot tests were also updated Signed-off-by: Oleksandr Dubenko --- .../api/modules/plugin_registry.md | 2 +- e2e-tests/tests/headlampPage.ts | 8 +- .../__snapshots__/index.stories.storyshot | 933 +- frontend/src/components/App/Home/index.tsx | 26 +- .../__snapshots__/List.stories.storyshot | 4 +- .../PluginSettings.stories.storyshot | 2 +- .../PluginSettingsDetails.stories.storyshot | 24 +- .../__snapshots__/Settings.stories.storyshot | 26 +- .../__snapshots__/TopBar.stories.storyshot | 2 +- .../__snapshots__/Sidebar.stories.storyshot | 8 +- frontend/src/components/cluster/Overview.tsx | 42 +- .../__snapshots__/Overview.stories.storyshot | 1217 +- .../common/ErrorBoundary/ErrorBoundary.tsx | 8 +- .../__snapshots__/ErrorPage.stories.storyshot | 2 +- .../UpdatePopup.stories.storyshot | 12 +- .../Resource/ResourceListView.stories.tsx | 2 +- .../common/Resource/ResourceListView.tsx | 46 +- .../common/Resource/ResourceTable.stories.tsx | 13 +- .../common/Resource/ResourceTable.tsx | 384 +- .../Resource/ResourceTableColumnChooser.tsx | 4 +- .../ResourceListView.stories.storyshot | 893 +- .../ResourceTable.stories.storyshot | 2077 +++- .../common/Resource/resourceTableSlice.ts | 6 +- .../common/Tooltip/TooltipLight.tsx | 14 +- .../ActionsNotifier.stories.storyshot | 2 +- .../ConfirmButton.stories.storyshot | 4 +- .../NamespacesAutocomplete.stories.storyshot | 12 +- .../SimpleTable.stories.storyshot | 168 +- .../__snapshots__/Table.stories.storyshot | 9937 +++++++++++++++++ frontend/src/components/configmap/List.tsx | 4 +- .../__snapshots__/Details.stories.storyshot | 8 +- .../__snapshots__/List.stories.storyshot | 800 +- .../src/components/crd/CustomResourceList.tsx | 16 +- frontend/src/components/crd/List.tsx | 20 +- ...CustomResourceDefinition.stories.storyshot | 1613 ++- .../CustomResourceDetails.stories.storyshot | 4 +- .../CustomResourceList.stories.storyshot | 797 +- frontend/src/components/cronjob/List.tsx | 33 +- .../CronJobDetails.stories.storyshot | 104 +- frontend/src/components/daemonset/List.tsx | 33 +- .../__snapshots__/List.stories.storyshot | 1341 ++- frontend/src/components/deployments/List.tsx | 28 +- frontend/src/components/endpoints/List.tsx | 6 +- .../EndpointDetails.stories.storyshot | 12 +- .../EndpointList.stories.storyshot | 1079 +- .../horizontalPodAutoscaler/List.tsx | 25 +- .../HPADetails.stories.storyshot | 12 +- .../__snapshots__/HPAList.stories.storyshot | 1834 ++- frontend/src/components/ingress/ClassList.tsx | 8 +- frontend/src/components/ingress/List.tsx | 14 +- .../ClassDetails.stories.storyshot | 8 +- .../__snapshots__/ClassList.stories.storyshot | 757 +- .../__snapshots__/Details.stories.storyshot | 8 +- .../__snapshots__/List.stories.storyshot | 1040 +- frontend/src/components/job/List.tsx | 25 +- .../__snapshots__/JobList.stories.storyshot | 1499 ++- frontend/src/components/lease/List.tsx | 2 +- .../__snapshots__/Details.stories.storyshot | 4 +- .../__snapshots__/List.stories.storyshot | 715 +- .../__snapshots__/Details.stories.storyshot | 4 +- .../__snapshots__/List.stories.storyshot | 621 +- frontend/src/components/namespace/List.tsx | 80 +- .../NamespaceDetails.stories.storyshot | 3681 ++++-- .../NamespaceList.stories.storyshot | 889 +- .../src/components/networkpolicy/List.tsx | 12 +- frontend/src/components/node/List.tsx | 40 +- .../node/__snapshots__/List.stories.storyshot | 1456 ++- frontend/src/components/node/utils.tsx | 2 +- frontend/src/components/pod/List.tsx | 45 +- .../PodDetails.stories.storyshot | 24 +- .../__snapshots__/PodList.stories.storyshot | 2263 ++-- .../__snapshots__/PodLogs.stories.storyshot | 4 +- .../components/podDisruptionBudget/List.tsx | 7 +- .../pdbDetails.stories.storyshot | 12 +- .../__snapshots__/pdbList.stories.storyshot | 1334 ++- .../src/components/priorityClass/List.tsx | 6 +- .../priorityClassDetails.stories.storyshot | 12 +- .../priorityClassList.stories.storyshot | 998 +- frontend/src/components/replicaset/List.tsx | 55 +- .../__snapshots__/List.stories.storyshot | 1444 ++- .../src/components/resourceQuota/List.tsx | 6 +- .../resourceQuotaDetails.stories.storyshot | 12 +- .../resourceQuotaList.stories.storyshot | 1339 ++- frontend/src/components/role/BindingList.tsx | 73 +- frontend/src/components/role/List.tsx | 13 +- frontend/src/components/runtimeClass/List.tsx | 2 +- .../__snapshots__/Details.stories.storyshot | 4 +- .../__snapshots__/List.stories.storyshot | 618 +- frontend/src/components/secret/List.tsx | 8 +- .../__snapshots__/Details.stories.storyshot | 14 +- .../__snapshots__/List.stories.storyshot | 916 +- frontend/src/components/service/List.tsx | 17 +- .../src/components/serviceaccount/List.tsx | 4 +- frontend/src/components/statefulset/List.tsx | 18 +- frontend/src/components/storage/ClaimList.tsx | 24 +- frontend/src/components/storage/ClassList.tsx | 12 +- .../src/components/storage/VolumeList.tsx | 27 +- .../ClaimDetails.stories.storyshot | 4 +- .../__snapshots__/ClaimList.stories.storyshot | 1588 ++- .../ClassDetails.stories.storyshot | 4 +- .../__snapshots__/ClassList.stories.storyshot | 918 +- .../VolumeDetails.stories.storyshot | 4 +- .../VolumeList.stories.storyshot | 918 +- .../components/verticalPodAutoscaler/List.tsx | 7 +- .../VPADetails.stories.storyshot | 12 +- .../__snapshots__/VPAList.stories.storyshot | 1334 ++- .../MutatingWebhookConfigList.tsx | 2 +- .../ValidatingWebhookConfigList.tsx | 2 +- ...tingWebhookConfigDetails.stories.storyshot | 12 +- ...utatingWebhookConfigList.stories.storyshot | 919 +- ...tingWebhookConfigDetails.stories.storyshot | 12 +- ...idatingWebhookConfigList.stories.storyshot | 919 +- frontend/src/components/workload/Overview.tsx | 17 +- .../LocaleSelect.stories.storyshot | 2 +- frontend/src/i18n/locales/de/glossary.json | 2 +- frontend/src/i18n/locales/de/translation.json | 1 - .../src/i18n/locales/de/translation_old.json | 3 + frontend/src/i18n/locales/en/glossary.json | 2 +- frontend/src/i18n/locales/en/translation.json | 1 - .../src/i18n/locales/en/translation_old.json | 3 + frontend/src/i18n/locales/es/glossary.json | 2 +- frontend/src/i18n/locales/es/translation.json | 1 - .../src/i18n/locales/es/translation_old.json | 3 + frontend/src/i18n/locales/fr/glossary.json | 2 +- frontend/src/i18n/locales/fr/translation.json | 1 - .../src/i18n/locales/fr/translation_old.json | 3 + frontend/src/i18n/locales/pt/glossary.json | 2 +- frontend/src/i18n/locales/pt/translation.json | 1 - .../src/i18n/locales/pt/translation_old.json | 3 + frontend/src/plugin/registry.tsx | 7 +- plugins/examples/tables/src/index.tsx | 3 +- 131 files changed, 40406 insertions(+), 10131 deletions(-) create mode 100644 frontend/src/components/common/__snapshots__/Table.stories.storyshot create mode 100644 frontend/src/i18n/locales/de/translation_old.json create mode 100644 frontend/src/i18n/locales/en/translation_old.json create mode 100644 frontend/src/i18n/locales/es/translation_old.json create mode 100644 frontend/src/i18n/locales/fr/translation_old.json create mode 100644 frontend/src/i18n/locales/pt/translation_old.json diff --git a/docs/development/api/modules/plugin_registry.md b/docs/development/api/modules/plugin_registry.md index 904151614df..a988a235523 100644 --- a/docs/development/api/modules/plugin_registry.md +++ b/docs/development/api/modules/plugin_registry.md @@ -639,7 +639,7 @@ registerResourceTableColumnsProcessor(function ageRemover({ id, columns }) { if (id === 'headlamp-pods') { columns.push({ label: 'Init Containers', - getter: (pod: Pod) => { + getValue: (pod: Pod) => { return pod.spec.initContainers.length; }, }); diff --git a/e2e-tests/tests/headlampPage.ts b/e2e-tests/tests/headlampPage.ts index 76e729e7857..4477d1657d3 100644 --- a/e2e-tests/tests/headlampPage.ts +++ b/e2e-tests/tests/headlampPage.ts @@ -1,3 +1,4 @@ +/// import { expect, Page } from '@playwright/test'; export class HeadlampPage { @@ -5,7 +6,6 @@ export class HeadlampPage { async authenticate() { await this.page.goto('/'); - await this.page.waitForSelector('h1:has-text("Authentication")'); // Expects the URL to contain c/main/token @@ -104,7 +104,9 @@ export class HeadlampPage { const rowsDisplayed1 = await this.getRowsDisplayed(); // Click on the next page button - const nextPageButton = this.page.getByTitle('Next page'); + const nextPageButton = this.page.getByRole('button', { + name: 'Go to next page', + }); await nextPageButton.click(); // Get value of rows per page after clicking next page button @@ -115,7 +117,7 @@ export class HeadlampPage { } async getRowsDisplayed() { - const paginationCaption = this.page.locator("p:has-text(' of ')"); + const paginationCaption = this.page.locator("span:has-text(' of ')"); const captionText = await paginationCaption.textContent(); return captionText; } diff --git a/frontend/src/components/App/Home/__snapshots__/index.stories.storyshot b/frontend/src/components/App/Home/__snapshots__/index.stories.storyshot index 07cc307af57..27b79e3456e 100644 --- a/frontend/src/components/App/Home/__snapshots__/index.stories.storyshot +++ b/frontend/src/components/App/Home/__snapshots__/index.stories.storyshot @@ -186,132 +186,584 @@ exports[`Storyshots Home/Home Base 1`] = ` class="MuiBox-root css-1txv3mw" >
- - +
+
+ +
+
+ + - - - - - - - - + + + +
+
+ +
+ +
+
- Name -
- Status - - Warnings - - Kubernetes Version - - -
- - - - - + + + + + + - + + + - - - + - - cluster1 - - - + - - - + + - - - + - - cluster2 - - - + - - - + + + + + +
- - cluster0 - - -
+ +
+ +
+
+ +
- -

+

+ Status +
+ + + + + + 0 + + +
+
- ⋯ -

+ +
- - -
- ⋯ - - ⋯ - + +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+
+ +

+ ⋯ +

+
+
+
+ ⋯ + + ⋯ +
-
-
+
-
+ cluster1 + +
- -

- ⋯ -

+ +

+ ⋯ +

+
- -
- ⋯ - - ⋯ - -
+
+ ⋯ + + ⋯ +
-
-
+
-
+ cluster2 + +
- -

- ⋯ -

+ +

+ ⋯ +

+
- -
- ⋯ - - ⋯ - -
+
+ ⋯ + + ⋯ +
+
+
+
+
+ +
+
+
+ +
+ + + +
- - - - + + 1-3 of 3 + +
+ + + + + + +
+
+
+
+
diff --git a/frontend/src/components/App/Home/index.tsx b/frontend/src/components/App/Home/index.tsx index 0419d53e9bd..4b4d5928dc7 100644 --- a/frontend/src/components/App/Home/index.tsx +++ b/frontend/src/components/App/Home/index.tsx @@ -212,38 +212,38 @@ function HomeComponent(props: HomeComponentProps) { > ( + getValue: cluster => cluster.name, + render: ({ name }) => ( {name} ), - sort: (c1: Cluster, c2: Cluster) => c1.name.localeCompare(c2.name), }, { label: t('Status'), - getter: ({ name }: Cluster) => , + getValue: cluster => cluster.name, + render: ({ name }) => , }, { label: t('Warnings'), - getter: ({ name }: Cluster) => renderWarningsText(name), - sort: true, + getValue: ({ name }) => renderWarningsText(name), }, { label: t('glossary|Kubernetes Version'), - getter: ({ name }: Cluster) => versions[name]?.gitVersion || '⋯', - sort: true, + getValue: ({ name }) => versions[name]?.gitVersion || '⋯', }, { label: '', - getter: (cluster: Cluster) => ( - - - - ), + getValue: () => '', + cellProps: { + align: 'right', + }, + render: cluster => , }, ]} data={Object.values(clusters)} diff --git a/frontend/src/components/App/Notifications/__snapshots__/List.stories.storyshot b/frontend/src/components/App/Notifications/__snapshots__/List.stories.storyshot index f2946d16126..ffdfaf5c9d2 100644 --- a/frontend/src/components/App/Notifications/__snapshots__/List.stories.storyshot +++ b/frontend/src/components/App/Notifications/__snapshots__/List.stories.storyshot @@ -3,12 +3,12 @@ exports[`Storyshots Notifications List 1`] = `
-
-
- -
- - + + + @@ -568,334 +540,959 @@ exports[`Storyshots cluster/Overview Events 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - + + + +
+
- Type - - - Name - - - Namespace - - +
+
+ +
+
+ + + + + + +
+ +
+
- Reason -
- Message - - Last Seen -
- - - - - - - + +
+ +
+ + + + + + + + - - - + + + + + + + - - default - - - + + + + + + + - - FailedGetResourceMetric - - - + + + + + + + +
- Pod - - - nginx-deployment-1234567890-abcde - - - - default - - - - FailedGetResourceMetric - - -
+ +
+ +
+
+ +
- - - - -

+

+ Name +
+ + + + + + 0 + + + +
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- Pod - - - nginx-deployment-abcd-1234567890 - - + Pod + + + nginx-deployment-abcd-1234567890 + + + + default + + + + FailedGetResourceMetric + + +
+ +
+
+

+ 3mo + +

+
+ Pod + + + nginx-deployment-1234567890-abcde + + + + default + + + + FailedGetResourceMetric + + +
+ +
+
+

+ 3mo + +

+
+ + + nginx-deployment + + + + default + + + + FailedGetResourceMetric + + +
+ +
+
+

+ 3mo + +

+
+
+
+
+ +
+
+
+ + + +
- - -

- 3mo - -

- - - - - HorizontalPodAutoscaler - - - - nginx-deployment - - - - - default - - - - FailedGetResourceMetric + 1-3 of 3 - -
- + + + + +
- - -

- 3mo - -

- - - - +
+
+
+
diff --git a/frontend/src/components/common/ErrorBoundary/ErrorBoundary.tsx b/frontend/src/components/common/ErrorBoundary/ErrorBoundary.tsx index 4c72ea5c4ae..30cbb3702d7 100644 --- a/frontend/src/components/common/ErrorBoundary/ErrorBoundary.tsx +++ b/frontend/src/components/common/ErrorBoundary/ErrorBoundary.tsx @@ -44,14 +44,20 @@ export default class ErrorBoundary extends Component render() { const { error } = this.state; if (error) { + console.error('ErrorBoundary:', error); store.dispatch(eventAction({ type: HeadlampEventType.ERROR_BOUNDARY, data: error })); } if (!error) { return this.props.children; } + if (!this.props.fallback) { + return null; + } if (isValidElement(this.props.fallback)) { return this.props.fallback; } - return this.props.fallback ? Children.toArray([]) : null; + + const FallbackComponent = this.props.fallback as ComponentType<{ error: Error }>; + return Children.toArray([]); } } diff --git a/frontend/src/components/common/ErrorPage/__snapshots__/ErrorPage.stories.storyshot b/frontend/src/components/common/ErrorPage/__snapshots__/ErrorPage.stories.storyshot index 8f567552ff1..0afb7749c30 100644 --- a/frontend/src/components/common/ErrorPage/__snapshots__/ErrorPage.stories.storyshot +++ b/frontend/src/components/common/ErrorPage/__snapshots__/ErrorPage.stories.storyshot @@ -49,7 +49,7 @@ exports[`Storyshots common/GenericError Component Title 1`] = ` class="MuiTypography-root MuiTypography-h1 css-5ewpze-MuiTypography-root" > +
+ + + + + + + + diff --git a/frontend/src/components/common/Resource/__snapshots__/ResourceTable.stories.storyshot b/frontend/src/components/common/Resource/__snapshots__/ResourceTable.stories.storyshot index bcab273a0fd..049ce3c276f 100644 --- a/frontend/src/components/common/Resource/__snapshots__/ResourceTable.stories.storyshot +++ b/frontend/src/components/common/Resource/__snapshots__/ResourceTable.stories.storyshot @@ -3,113 +3,612 @@ exports[`Storyshots ResourceTable Name Search 1`] = `
- - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
+
+
+
+
+ + +
+ + + +
+ +
+
+
+
+
+
- Namespace -
- Age -
- - - + + + + + - - MyNamespace3 - - - + + + + + +
- - mypod3 - - +
+ +
+ +
+
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ + mypod3 + + + + MyNamespace3 + + +

+ 3mo + +

+
+
+
+
+ +
+
-

- 3mo - -

- - - - + +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+
`; @@ -117,224 +616,666 @@ exports[`Storyshots ResourceTable Name Search 1`] = ` exports[`Storyshots ResourceTable No Filter 1`] = `
- - +
+
+ +
+
+ + +
-
+
-
- - - - - + + + +
+
- Name - - Namespace - - Age -
- - - - + - + +
+ +
+ + + + + - - - - - - + + + + - - mypod2 - - - + + + + - - MyNamespace2 - - - + + + + -

+ + mypod3 + + +

- - + MyNamespace3 + + + + + + +
- - mypod0 - - - - MyNamespace0 - - -

+

+ +
+ +
+
+ +
+
+ +
+ +
+
+
- 3mo - -

- -
- - mypod1 - - - - MyNamespace1 - - -

- 3mo - -

-
+ mypod0 + + + + MyNamespace0 + + +

+ 3mo + +

+
+ + mypod1 + + + + MyNamespace1 + + +

+ 3mo + +

+
+ + mypod2 + + + + MyNamespace2 + + +

+ 3mo + +

+
- 3mo - -

-
+

+ 3mo + +

+
+
+
+
+ +
- - - mypod3 - - - - - MyNamespace3 - - - -

+ +

+ + + +
+
+ - 3mo - -

- - - - + 1-4 of 4 +
+
+ + + + + + +
+
+
+
+ `; @@ -342,167 +1283,545 @@ exports[`Storyshots ResourceTable No Filter 1`] = ` exports[`Storyshots ResourceTable With Hidden Cols 1`] = `
- - +
+
+ +
+
+ + - - - - - + + + +
+
+ +
+ +
+
- Name + -
- Age -
- - - - + +
+ +
+ + + + + - - + + + -

- 3mo - -

- - - - + + + - - mypod2 - - - + + + -

+ + mypod3 + + +

- - + 3mo + +

+ +
+ + +
- - mypod0 - - -

+

+ +
+ +
+
+ +
- 3mo - -

- -
- - mypod1 - - + + mypod0 + + +

+ 3mo + +

+
+ mypod1 + + +

+ 3mo + +

+
+ + mypod2 + + +

+ 3mo + +

+
- 3mo - -

-
+
+
+
+ +
- - - mypod3 - - - -

+ +

+ + + +
+
+ - 3mo - -

- - - - + 1-4 of 4 +
+
+ + + + + + +
+
+
+
+ `; diff --git a/frontend/src/components/common/Resource/resourceTableSlice.ts b/frontend/src/components/common/Resource/resourceTableSlice.ts index defa01c446c..c584ff2a127 100644 --- a/frontend/src/components/common/Resource/resourceTableSlice.ts +++ b/frontend/src/components/common/Resource/resourceTableSlice.ts @@ -17,10 +17,10 @@ export type TableColumnsProcessor = { * * @returns The new table columns. */ - processor: (args: { + processor: (args: { id: string; - columns: ResourceTableProps['columns']; - }) => ResourceTableProps['columns']; + columns: ResourceTableProps['columns']; + }) => ResourceTableProps['columns']; }; const initialState: ResourceTableState = { diff --git a/frontend/src/components/common/Tooltip/TooltipLight.tsx b/frontend/src/components/common/Tooltip/TooltipLight.tsx index 4e83ca451c5..86bd7277335 100644 --- a/frontend/src/components/common/Tooltip/TooltipLight.tsx +++ b/frontend/src/components/common/Tooltip/TooltipLight.tsx @@ -1,13 +1,15 @@ import Tooltip, { TooltipProps } from '@mui/material/Tooltip'; import withStyles from '@mui/styles/withStyles'; +import { ReactElement, ReactNode } from 'react'; -export interface TooltipLightProps extends TooltipProps { +export interface TooltipLightProps extends Omit { /** * If true, the tooltip will be interactive. Defaults to true. * * If a tooltip is interactive, it will close when the user hovers over the tooltip before the leaveDelay is expired. */ interactive?: boolean; + children: ReactNode; } const StyledTooltip = withStyles(theme => ({ @@ -32,5 +34,13 @@ export default function TooltipLight(props: TooltipLightProps) { ); } - return ; + return ( + + ); } diff --git a/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot b/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot index e4597a42729..bd38a709952 100644 --- a/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot +++ b/frontend/src/components/common/__snapshots__/ActionsNotifier.stories.storyshot @@ -36,7 +36,7 @@ exports[`Storyshots ActionsNotifier Some 1`] = ` class="SnackbarItem-action" > + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ some name0 + + some status0 + + some age0 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
+ some name1 + + some status1 + + some age1 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
+ some name2 + + some status2 + + some age2 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-3 of 3 + +
+ + + + + + +
+
+
+
+
+ + +`; + +exports[`Storyshots Table Getter 1`] = ` +
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ some name0 + + some status0 + + some age0 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + 22 +
+ some name1 + + some status1 + + some age1 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + 33 +
+ some name2 + + some status2 + + some age2 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + 44 +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-3 of 3 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Label Search 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources1.io + + MyNamespace1 + + phony1 + + {"mylabel1":"myvalue1"} +
+ mydefinition.phonyresources2.io + + MyNamespace2 + + phony2 + + {"mykey2":"mylabel"} +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-2 of 2 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Name Search 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources2.io + + MyNamespace2 + + phony2 + + {"mykey2":"mylabel"} +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Namespace Search 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources3.io + + MyNamespace3 + + phony3 + + {"mykey3":"myvalue3"} +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Namespace Select 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+

+ MyNamespace1 + + ,  + + + +1 + +

+ +
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources0.io + + MyNamespace0 + + phony0 + +
+ mydefinition.phonyresources1.io + + MyNamespace1 + + phony1 + + {"mylabel1":"myvalue1"} +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-2 of 2 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Not Found Message 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+

+ No records to display +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 0-0 of 0 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Number Search 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources3.io + + MyNamespace3 + + 30 +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Reflect In URL 1`] = ` +
+
+

+ Test changing the page and rows per page. +

+

+ + Current URL search: + + + ?p=2 +

+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ Name 0 + + Namespace 0 + + 0 +
+ Name 1 + + Namespace 1 + + 1 +
+ Name 2 + + Namespace 2 + + 2 +
+ Name 3 + + Namespace 3 + + 3 +
+ Name 4 + + Namespace 4 + + 4 +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-5 of 50 + +
+ + + + + + +
+
+
+
+
+
+
+
+`; + +exports[`Storyshots Table Reflect In URL With Prefix 1`] = ` +
+
+

+ Test changing the page and rows per page. +

+

+ + Current URL search: + + + ?p=2 +

+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ Name 0 + + Namespace 0 + +
+ Name 1 + + Namespace 1 + +
+ Name 2 + + Namespace 2 + +
+ Name 3 + + Namespace 3 + +
+ Name 4 + + Namespace 4 + +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-5 of 50 + +
+ + + + + + +
+
+
+
+
+
+
+
+`; + +exports[`Storyshots Table UID Search 1`] = ` +
+
+
+
+

+ Test +

+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources0.io + + MyNamespace0 + + phony0 + +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table With Filter Multi Select 1`] = ` +
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources0.io + + MyNamespace0 +
+ mydefinition.phonyresources1.io + + MyNamespace1 +
+ mydefinition.phonyresources2.io + + MyNamespace2 +
+ mydefinition.phonyresources3.io + + MyNamespace3 +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-4 of 4 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table With Global Filter 1`] = ` +
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+
+
+
+ + +
+ + + +
+ +
+
+
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+

+ No results found +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 0-0 of 0 + +
+ + + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Table With Sorting 1`] = ` +
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+ + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ mydefinition.phonyresources3.io + + MyNamespace3 + + phony3 + + {"mykey3":"myvalue3"} +
+ mydefinition.phonyresources2.io + + MyNamespace2 + + phony2 + + {"mykey2":"mylabel"} +
+ mydefinition.phonyresources1.io + + MyNamespace1 + + phony1 + + {"mylabel1":"myvalue1"} +
+ mydefinition.phonyresources0.io + + MyNamespace0 + + phony0 + +
+
+
+
+ +
+
+
+ +
+ + + +
+
+ + 1-4 of 4 + +
+ + + + + + +
+
+
+
+
+
+
+`; diff --git a/frontend/src/components/configmap/List.tsx b/frontend/src/components/configmap/List.tsx index 270e43a95f8..e72e341caf9 100644 --- a/frontend/src/components/configmap/List.tsx +++ b/frontend/src/components/configmap/List.tsx @@ -15,9 +15,7 @@ export default function ConfigMapList() { { id: 'data', label: t('translation|Data'), - getter: (configmap: ConfigMap) => Object.keys(configmap.data || {}).length || 0, - sort: true, - gridTemplate: 0.5, + getValue: (configmap: ConfigMap) => Object.keys(configmap.data || {}).length || 0, }, 'age', ]} diff --git a/frontend/src/components/configmap/__snapshots__/Details.stories.storyshot b/frontend/src/components/configmap/__snapshots__/Details.stories.storyshot index 416baee2baa..a9f1b6805fd 100644 --- a/frontend/src/components/configmap/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/configmap/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots ConfigMap/DetailsView Empty 1`] = ` class="MuiBox-root css-p0cik4" > -
-
- -
-
-
+ + +
@@ -80,177 +52,675 @@ exports[`Storyshots ConfigMap/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Data - - Age -
- - - - + - + +
+ +
+ + + + + - - + - + + + + - 0 - - + + + + + + +
- - my-pvc - - - + +
+ +
+ + +
- default - - - - 3 - -

+

+
+ +
+ + +
+
+ +
+ +
+
+
- 3mo - -

- -
- - my-pvc - - - + my-pvc + + - default - - + default + + + 3 + +

+ 3mo + +

+
+ + my-pvc + + + + default + + + 0 + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ + 1-2 of 2 + +
- 3mo - -

- - - - + + + + + + +
+
+
+
+
diff --git a/frontend/src/components/crd/CustomResourceList.tsx b/frontend/src/components/crd/CustomResourceList.tsx index 310009fb37e..0db82cd48f4 100644 --- a/frontend/src/components/crd/CustomResourceList.tsx +++ b/frontend/src/components/crd/CustomResourceList.tsx @@ -6,11 +6,11 @@ import { useParams } from 'react-router-dom'; import { KubeObject } from '../../lib/k8s/cluster'; import CRD, { KubeCRD } from '../../lib/k8s/crd'; import { localeDate } from '../../lib/util'; -import { Link, Loader, PageGrid, SectionHeader, SimpleTableGetterColumn } from '../common'; +import { Link, Loader, PageGrid, SectionHeader } from '../common'; import BackLink from '../common/BackLink'; import Empty from '../common/EmptyContent'; import ResourceListView from '../common/Resource/ResourceListView'; -import { ResourceTableProps } from '../common/Resource/ResourceTable'; +import { ResourceTableColumn, ResourceTableProps } from '../common/Resource/ResourceTable'; export default function CustomResourceList() { const { t } = useTranslation(['glossary', 'translation']); @@ -124,7 +124,7 @@ export function CustomResourceListTable(props: CustomResourceTableProps) { crd.jsonData.spec.versions.find( (version: KubeCRD['spec']['versions'][number]) => version.name === currentVersion )?.additionalPrinterColumns || []; - const cols: SimpleTableGetterColumn[] = []; + const cols: ResourceTableColumn[] = []; for (let i = 0; i < colsFromSpec.length; i++) { const idx = i; const colSpec = colsFromSpec[idx]; @@ -135,7 +135,7 @@ export function CustomResourceListTable(props: CustomResourceTableProps) { cols.push({ label: colSpec.name, - getter: resource => { + getValue: resource => { let value = getValueWithJSONPath(resource, colSpec.jsonPath); if (colSpec.type === 'date') { value = localeDate(new Date(value)); @@ -150,13 +150,11 @@ export function CustomResourceListTable(props: CustomResourceTableProps) { }, [crd, apiGroup]); const cols = React.useMemo(() => { - const colsToDisplay: ResourceTableProps['columns'] = [ + const colsToDisplay: ResourceTableProps['columns'] = [ { label: t('translation|Name'), - getter: (resource: KubeObject) => , - sort: (c1: KubeObject, c2: KubeObject) => { - return c1.metadata.name.localeCompare(c2.metadata.name); - }, + getValue: resource => resource.metadata.name, + render: (resource: KubeObject) => , }, ...additionalPrinterCols, 'age', diff --git a/frontend/src/components/crd/List.tsx b/frontend/src/components/crd/List.tsx index 4e49763d43a..f7c183f3f64 100644 --- a/frontend/src/components/crd/List.tsx +++ b/frontend/src/components/crd/List.tsx @@ -16,7 +16,8 @@ export default function CustomResourceDefinitionList() { columns={[ { label: t('glossary|Resource'), - getter: crd => ( + getValue: crd => crd.spec.names.kind, + render: crd => ( ( + getValue: crd => crd.metadata.name, + render: crd => ( ), - sort: (c1: CRD, c2: CRD) => { - if (c1.metadata.name < c2.metadata.name) { - return -1; - } else if (c1.metadata.name > c2.metadata.name) { - return 1; - } - return 0; - }, }, { label: t('translation|Group'), - getter: crd => crd.spec.group, - sort: true, + getValue: crd => crd.spec.group, }, { label: t('Scope'), - getter: crd => crd.spec.scope, - sort: true, + getValue: crd => crd.spec.scope, }, 'age', ]} diff --git a/frontend/src/components/crd/__snapshots__/CustomResourceDefinition.stories.storyshot b/frontend/src/components/crd/__snapshots__/CustomResourceDefinition.stories.storyshot index cc0d5bb87f2..3160496ebdd 100644 --- a/frontend/src/components/crd/__snapshots__/CustomResourceDefinition.stories.storyshot +++ b/frontend/src/components/crd/__snapshots__/CustomResourceDefinition.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots crd/CustomResourceDefinition Details 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -506,166 +478,675 @@ exports[`Storyshots crd/CustomResourceDefinition Details 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name -
- Namespace - - Test Col - - Age -
- - - - - + +
+ +
+ + + + + + - - + - + + + + - myotherresource - - + + + + + + +
- - mycustomresource - - - + +
+ +
+ + +
- mynamespace - - - - mycustomresource - -

+

+
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
- - myotherresource - - - + mycustomresource + + - mynamespace - - + mynamespace + + + mycustomresource + +

+ 3mo + +

+
+ + myotherresource + + + + mynamespace + + + myotherresource + +

+ 3mo + +

+
+
+
+
+ +
+
-

- 3mo - -

- - - - + +
+ + + +
+
+ + 1-2 of 2 + +
+ + + + + + +
+
+
+
+ @@ -857,45 +1338,17 @@ exports[`Storyshots crd/CustomResourceDefinition List 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -904,146 +1357,712 @@ exports[`Storyshots crd/CustomResourceDefinition List 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - + + + +
+
- Resource - - Definition - - +
+
+ +
+
+ + + + + + +
+ +
+
- Group -
- Scope - - Age -
- - - - + + + + + + - Namespaced - - + + + + + + + +
- - MyCustomResource - - - + +
+ +
+ + +
- mydefinition.phonyresources.io - - - - my.phonyresources.io - + +
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ + MyCustomResource + + + + mydefinition.phonyresources.io + + + my.phonyresources.io + + Namespaced + +

+ 3mo + +

+
+
+
+
+ +
+
-

- 3mo - -

- - - - + +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+ diff --git a/frontend/src/components/crd/__snapshots__/CustomResourceDetails.stories.storyshot b/frontend/src/components/crd/__snapshots__/CustomResourceDetails.stories.storyshot index d93c28bc324..a68b5140052 100644 --- a/frontend/src/components/crd/__snapshots__/CustomResourceDetails.stories.storyshot +++ b/frontend/src/components/crd/__snapshots__/CustomResourceDetails.stories.storyshot @@ -69,12 +69,12 @@ exports[`Storyshots crd/CustomResourceDetails No Error 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -154,166 +126,675 @@ exports[`Storyshots crd/CustomResourceList List 1`] = ` class="MuiBox-root css-1txv3mw" >
- - +
+
+ +
+
+ + - - - - - - - + + + +
+
+ +
+ +
+
- Name -
- Namespace - - Test Col - - Age -
- - - - + - + +
+ +
+ + + + + - - + - + + + + - myotherresource - - + + + + + + +
- - mycustomresource - - - + +
+ +
+ + +
- mynamespace - - - - mycustomresource - -

+

+
+ +
+ + +
+
+ +
+ +
+
+
- 3mo - -

- -
- - myotherresource - - - + mycustomresource + + - mynamespace - - + mynamespace + + + mycustomresource + +

+ 3mo + +

+
+ + myotherresource + + + + mynamespace + + + myotherresource + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ + 1-2 of 2 + +
- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/cronjob/List.tsx b/frontend/src/components/cronjob/List.tsx index ca967bdb82c..84c5eaa1334 100644 --- a/frontend/src/components/cronjob/List.tsx +++ b/frontend/src/components/cronjob/List.tsx @@ -1,6 +1,5 @@ import cronstrue from 'cronstrue/i18n'; import { useTranslation } from 'react-i18next'; -import { KubeContainer } from '../../lib/k8s/cluster'; import CronJob from '../../lib/k8s/cronJob'; import { DateLabel, HoverInfoLabel, LightTooltip } from '../common'; import ResourceListView from '../common/Resource/ResourceListView'; @@ -42,32 +41,35 @@ export default function CronJobList() { { id: 'schedule', label: t('Schedule'), - getter: cronJob => getSchedule(cronJob, i18n.language), + getValue: cronJob => cronJob.spec.schedule, + render: cronJob => getSchedule(cronJob, i18n.language), }, { id: 'suspend', label: t('translation|Suspend'), - getter: cronJob => cronJob.spec.suspend.toString(), - sort: true, - gridTemplate: 0.6, + getValue: cronJob => cronJob.spec.suspend.toString(), }, { id: 'active', label: t('translation|Active'), - getter: cronJob => cronJob.status?.active?.length || 0, - sort: true, - gridTemplate: 0.6, + getValue: cronJob => cronJob.status?.active?.length || 0, }, { id: 'lastScheduleTime', label: t('Last Schedule'), - getter: cronJob => getLastScheduleTime(cronJob), + getValue: cronJob => cronJob.status.lastScheduletime ?? '', + render: cronJob => getLastScheduleTime(cronJob), }, { id: 'containers', label: t('Containers'), - getter: deployment => { - const containers = deployment.getContainers().map((c: KubeContainer) => c.name); + getValue: deployment => + deployment + .getContainers() + .map(c => c.name) + .join(', '), + render: deployment => { + const containers = deployment.getContainers().map(c => c.name); const containerText = containers.join(', '); const containerTooltip = containers.join('\n'); return ( @@ -80,8 +82,13 @@ export default function CronJobList() { { id: 'images', label: t('Images'), - getter: deployment => { - const images = deployment.getContainers().map((c: KubeContainer) => c.image); + getValue: deployment => + deployment + .getContainers() + .map(c => c.image) + .join(', '), + render: deployment => { + const images = deployment.getContainers().map(c => c.image); const imageText = images.join(', '); const imageTooltip = images.join('\n'); return ( diff --git a/frontend/src/components/cronjob/__snapshots__/CronJobDetails.stories.storyshot b/frontend/src/components/cronjob/__snapshots__/CronJobDetails.stories.storyshot index 81f5b131c75..5486a2dd0db 100644 --- a/frontend/src/components/cronjob/__snapshots__/CronJobDetails.stories.storyshot +++ b/frontend/src/components/cronjob/__snapshots__/CronJobDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots CronJob/CronJobDetailsView Every Ast 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -510,12 +482,12 @@ exports[`Storyshots CronJob/CronJobDetailsView Every Minute 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + diff --git a/frontend/src/components/daemonset/List.tsx b/frontend/src/components/daemonset/List.tsx index 6397e51436b..901d2378c79 100644 --- a/frontend/src/components/daemonset/List.tsx +++ b/frontend/src/components/daemonset/List.tsx @@ -17,35 +17,28 @@ export default function DaemonSetList() { { id: 'pods', label: t('Pods'), - getter: daemonSet => daemonSet.status?.currentNumberScheduled || 0, - gridTemplate: 0.6, - sort: true, + getValue: daemonSet => daemonSet.status?.currentNumberScheduled || 0, }, { id: 'currentPods', label: t('translation|Current'), - getter: daemonSet => daemonSet.status?.currentNumberScheduled || 0, - gridTemplate: 0.6, - sort: true, + getValue: daemonSet => daemonSet.status?.currentNumberScheduled || 0, }, { id: 'desiredPods', label: t('translation|Desired', { context: 'pods' }), - getter: daemonSet => daemonSet.status?.desiredNumberScheduled || 0, - gridTemplate: 0.6, - sort: true, + getValue: daemonSet => daemonSet.status?.desiredNumberScheduled || 0, }, { id: 'readyPods', label: t('translation|Ready'), - getter: daemonSet => daemonSet.status?.numberReady || 0, - gridTemplate: 0.6, - sort: true, + getValue: daemonSet => daemonSet.status?.numberReady || 0, }, { id: 'nodeSelector', label: t('Node Selector'), - getter: daemonSet => { + getValue: daemonSet => daemonSet.getNodeSelectors().join(', '), + render: daemonSet => { const selectors = daemonSet.getNodeSelectors(); const nodeSelectorTooltip = selectors.join('\n'); const nodeSelectorText = selectors.join(', '); @@ -59,7 +52,12 @@ export default function DaemonSetList() { { id: 'containers', label: t('Containers'), - getter: daemonSet => { + getValue: daemonSet => + daemonSet + .getContainers() + .map((c: KubeContainer) => c.name) + .join(', '), + render: daemonSet => { const containerNames = daemonSet.getContainers().map((c: KubeContainer) => c.name); const containerText = containerNames.join(', '); const containerTooltip = containerNames.join('\n'); @@ -73,7 +71,12 @@ export default function DaemonSetList() { { id: 'images', label: t('Images'), - getter: daemonSet => { + getValue: daemonSet => + daemonSet + .getContainers() + .map((c: KubeContainer) => c.image) + .join(', '), + render: daemonSet => { const images = daemonSet.getContainers().map((c: KubeContainer) => c.image); const imageTooltip = images.join('\n'); const imageText = images.join(', '); diff --git a/frontend/src/components/daemonset/__snapshots__/List.stories.storyshot b/frontend/src/components/daemonset/__snapshots__/List.stories.storyshot index a290072c158..d7d3315bf85 100644 --- a/frontend/src/components/daemonset/__snapshots__/List.stories.storyshot +++ b/frontend/src/components/daemonset/__snapshots__/List.stories.storyshot @@ -36,45 +36,17 @@ exports[`Storyshots DaemonSet/List Daemon Sets 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -83,252 +55,1145 @@ exports[`Storyshots DaemonSet/List Daemon Sets 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Pods - - Current - + + + +
+ + + - Desired - - - + - - - - + - - - - + +
+ +
+ + + + + + + + + + + + - - + - - - - - + - - + + + + + + + + +
- Ready - + + + - - - - - Node Selector - - Containers - - Images - - Age - + + + - - - -
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- - gadget - - - + gadget + + - gadget - - - 2 - - 2 - - 2 - - 2 - - + gadget + + - kubernetes.io/os=linux - - - + - gadget - - + + 2 + + 2 + + + kubernetes.io/os=linux + + + + gadget + + + + ghcr.io/inspektor-gadget/inspektor-gadget:v0.15.0 + + +

+ 3mo + +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
- ghcr.io/inspektor-gadget/inspektor-gadget:v0.15.0 + 1-1 of 1 - -
-

- 3mo - -

-
+ + + + + + +
+ + + + diff --git a/frontend/src/components/deployments/List.tsx b/frontend/src/components/deployments/List.tsx index 45bcf6c3874..9fd50312ae0 100644 --- a/frontend/src/components/deployments/List.tsx +++ b/frontend/src/components/deployments/List.tsx @@ -66,26 +66,30 @@ export default function DeploymentsList() { { id: 'pods', label: t('Pods'), - getter: deployment => renderPods(deployment), + getValue: deployment => deployment.status.availableReplicas, + render: deployment => renderPods(deployment), sort: sortByPods, - gridTemplate: 0.5, }, { id: 'replicas', label: t('Replicas'), - getter: deployment => deployment.spec.replicas || 0, - sort: true, - gridTemplate: 0.6, + getValue: deployment => deployment.spec.replicas || 0, }, { id: 'conditions', label: t('translation|Conditions'), - getter: deployment => renderConditions(deployment), + getValue: deployment => deployment.status?.conditions?.map((c: any) => c.type)?.join(''), + render: deployment => renderConditions(deployment), }, { id: 'containers', label: t('Containers'), - getter: deployment => { + getValue: deployment => + deployment + .getContainers() + .map(c => c.name) + .join(', '), + render: deployment => { const containers = deployment.getContainers().map((c: KubeContainer) => c.name); const containerText = containers.join(', '); const containerTooltip = containers.join('\n'); @@ -99,7 +103,12 @@ export default function DeploymentsList() { { id: 'images', label: t('Images'), - getter: deployment => { + getValue: deployment => + deployment + .getContainers() + .map(c => c.image) + .join(', '), + render: deployment => { const images = deployment.getContainers().map((c: KubeContainer) => c.image); const imageText = images.join(', '); const imageTooltip = images.join('\n'); @@ -113,7 +122,8 @@ export default function DeploymentsList() { { id: 'selector', label: t('Selector'), - getter: deployment => { + getValue: deployment => deployment.getMatchLabelsList().join(', '), + render: deployment => { const matchLabels = deployment.getMatchLabelsList(); const text = matchLabels.join(', '); const tooltip = matchLabels.join('\n'); diff --git a/frontend/src/components/endpoints/List.tsx b/frontend/src/components/endpoints/List.tsx index d4281bbd561..65ee574ed0f 100644 --- a/frontend/src/components/endpoints/List.tsx +++ b/frontend/src/components/endpoints/List.tsx @@ -6,7 +6,7 @@ import ResourceListView from '../common/Resource/ResourceListView'; export default function EndpointList() { const { t } = useTranslation(['glossary', 'translation']); - const filterFunc = useFilterFunc([ + const filterFunc = useFilterFunc([ '.jsonData.subsets[*].addresses[*].ip', '.jsonData.subsets[*].ports[*].port', '.jsonData.subsets[*].ports[*].name', @@ -23,8 +23,8 @@ export default function EndpointList() { { id: 'addresses', label: t('translation|Addresses'), - getter: endpoint => , - gridTemplate: 1.5, + getValue: endpoint => endpoint.getAddresses().join(', '), + render: endpoint => , }, 'age', ]} diff --git a/frontend/src/components/endpoints/__snapshots__/EndpointDetails.stories.storyshot b/frontend/src/components/endpoints/__snapshots__/EndpointDetails.stories.storyshot index cac7f21dccf..383f354140c 100644 --- a/frontend/src/components/endpoints/__snapshots__/EndpointDetails.stories.storyshot +++ b/frontend/src/components/endpoints/__snapshots__/EndpointDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots endpoints/EndpointsDetailsView Default 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,322 +52,843 @@ exports[`Storyshots endpoints/EndpointsListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - +
+
+ +
+
+ + +
-
+
-
- - - - - - + + + +
+
- Name - - Namespace - - Addresses - - Age -
- - - - + +
+ +
+ + + + + - - + - + - + - - - + + - - endpoints-2 - - - + - + - + - - - + + - - endpoints-3 - - - + - + - + - - - + + - - endpoints-4 - - - + + + + + - + + endpoints-4 + + + - + + + + + +
- - endpoints-0 - - - + +
+ +
+ + +
- my-namespace - - - - + +
+ +
+ + +
- 127.0.01:8080 - - - -

+

+
+ +
+ + +
- 3mo - -

- -
- - endpoints-1 - - - + endpoints-0 + + - my-namespace - - - + my-namespace + + - 127.0.01:8080 - - -

+ 127.0.01:8080 + +

- 3mo - -

-
+ 3mo + +

+
- + endpoints-1 + + - my-namespace - - - + my-namespace + + - 127.0.01:8080 - - -

+ 127.0.01:8080 + +

- 3mo - -

-
+ 3mo + +

+
- + endpoints-2 + + - my-namespace - - - + my-namespace + + - 127.0.01:8080 - - -

+ 127.0.01:8080 + +

- 3mo - -

-
+ 3mo + +

+
+ endpoints-3 + + + + my-namespace + + + + 127.0.01:8080 + + +

+ 3mo + +

+
- my-namespace - - + my-namespace + + + + 127.0.01:8080 + + +

+ 3mo + +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
- 127.0.01:8080 + 1-5 of 5 - - -

- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/horizontalPodAutoscaler/List.tsx b/frontend/src/components/horizontalPodAutoscaler/List.tsx index 0c3532b7663..5394da603b7 100644 --- a/frontend/src/components/horizontalPodAutoscaler/List.tsx +++ b/frontend/src/components/horizontalPodAutoscaler/List.tsx @@ -32,7 +32,8 @@ export default function HpaList() { { id: 'reference', label: t('translation|Reference'), - getter: item => ( + getValue: item => item.referenceObject?.metadata.name, + render: item => ( {item.referenceObject?.kind}/{item.referenceObject?.metadata.name} @@ -41,7 +42,12 @@ export default function HpaList() { { id: 'targets', label: t('translation|Targets'), - getter: (hpa: HPA) => { + getValue: item => + item + .metrics(t) + .map(it => it.shortValue) + .join(', '), + render: (hpa: HPA) => { const value: JSX.Element[] = []; const metrics = hpa.metrics(t); if (metrics.length) { @@ -61,30 +67,21 @@ export default function HpaList() { } return {value}; }, - cellProps: { - style: { - width: 'fit-content', - minWidth: '100%', - }, - }, }, { id: 'minReplicas', label: t('translation|MinReplicas'), - getter: item => item.spec.minReplicas, - sort: true, + getValue: item => item.spec.minReplicas, }, { id: 'maxReplicas', label: t('translation|MaxReplicas'), - getter: item => item.spec.maxReplicas, - sort: true, + getValue: item => item.spec.maxReplicas, }, { id: 'currentReplicas', label: t('glossary|Replicas'), - getter: item => item.status.currentReplicas, - sort: true, + getValue: item => item.status.currentReplicas, }, 'age', ]} diff --git a/frontend/src/components/horizontalPodAutoscaler/__snapshots__/HPADetails.stories.storyshot b/frontend/src/components/horizontalPodAutoscaler/__snapshots__/HPADetails.stories.storyshot index 3309adef4ce..db66ad23fa6 100644 --- a/frontend/src/components/horizontalPodAutoscaler/__snapshots__/HPADetails.stories.storyshot +++ b/frontend/src/components/horizontalPodAutoscaler/__snapshots__/HPADetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots hpa/HpaDetailsView Default 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,595 +52,1381 @@ exports[`Storyshots hpa/HpaListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - - - + + + +
+
- Name - - - Namespace - - - Reference - - Targets - - MinReplicas - - +
+
+ +
+
+ + + + + + +
+ +
+
- MaxReplicas -
- Replicas - - Age -
- - - - - - - - - - - - - - + - - - - - - - - + - - - - + +
+ +
+ + + + + - - - - + + + + + + + + + + + + + - - - - - - - - + + + + - - default - - - + + + + + + + + + - - Deployment - / - php-apache - - - + + + + + + + + + - + + + + + + + + + +
- - php-apache - - - - default - - - - Deployment - / - php-apache - - -
- - 14360576/100Mi - +
+ Name +
+ + + + + + 0 + + +
+
+ +
+ +
- - 1more… - +
+ Namespace +
+ + + + + + 0 + + +
+
+ +
- - -
- 1 - - 10 - - 1 - -

- 3mo - -

-
- - php-apache - - - - default - - - - Deployment - / - php-apache - - -
+
- +
+ Reference +
+ + + + + + 0 + + +
+
- 14360576/100Mi - + +
+
- +
+ Targets +
+ + + + + + 0 + + +
+
- 1more… - + +
- - -
- 1 - - 10 - - 1 - -

+

- 3mo - -

- -
- - php-apache - - - - default - - - - Deployment - / - php-apache - - -
+ +
+ +
+
+ +
- +
+ MaxReplicas +
+ + + + + + 0 + + +
+
- 14360576/100Mi - + +
+
- +
+ Replicas +
+ + + + + + 0 + + +
+
- 1more… - + +
- - -
- 1 - - 10 - - 1 - -

+

- 3mo - -

- -
- - php-apache - - - - default - - - - Deployment - / - php-apache - - - + + default + + + + Deployment + / + php-apache + +
- - 14360576/100Mi - + + 14360576/100Mi + +
+
+ + 1more… + +
+
+ 1 + + 10 + + 1 + +

+ 3mo + +

+
+ + php-apache + + + + default + + + + Deployment + / + php-apache + +
- + + 14360576/100Mi + +
+
- 1more… - + + 1more… + +
- -
- 1 - - 10 - - 1 - -

+

- 3mo - -

-
- - php-apache - - + + 10 + + 1 + +

+ 3mo + +

+
+ + php-apache + + + + default + + + + Deployment + / + php-apache + + +
+
+ + 14360576/100Mi + +
+
+ + 1more… + +
+
+
+ 1 + + 10 + + 1 + +

+ 3mo + +

+
+ + php-apache + + + + default + + + + Deployment + / + php-apache + + +
+
+ + 14360576/100Mi + +
+
+ + 1more… + +
+
+
+ 1 + + 10 + + 1 + +

+ 3mo + +

+
+ + default + + + + Deployment + / + php-apache + +
- + + 14360576/100Mi + +
+
- 14360576/100Mi - + + 1more… + +
+
+ 1 + + 10 + + 1 + +

+ 3mo + +

+
+
+
+
+ +
+
+
+
-
+ +
- - - 1 - - - 10 - - - 1 - - -

+ 1-5 of 5 + +

- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/ingress/ClassList.tsx b/frontend/src/components/ingress/ClassList.tsx index 4a7a628286f..2ebec0389a5 100644 --- a/frontend/src/components/ingress/ClassList.tsx +++ b/frontend/src/components/ingress/ClassList.tsx @@ -17,17 +17,17 @@ export default function IngressClassList() { { id: 'default', label: '', - gridTemplate: 0.1, - getter: (resource: IngressClass) => + getValue: resource => (resource?.isDefault ? t('Default Ingress Class') : null), + render: (resource: IngressClass) => resource && resource.isDefault ? : null, sort: false, + disableFiltering: true, }, 'name', { id: 'controller', label: t('Controller'), - getter: (ingressClass: IngressClass) => ingressClass.spec?.controller, - sort: true, + getValue: (ingressClass: IngressClass) => ingressClass.spec?.controller, }, 'age', ]} diff --git a/frontend/src/components/ingress/List.tsx b/frontend/src/components/ingress/List.tsx index 6a8315397a3..46adebb3325 100644 --- a/frontend/src/components/ingress/List.tsx +++ b/frontend/src/components/ingress/List.tsx @@ -46,25 +46,31 @@ export default function IngressList() { { id: 'class', label: t('Class Name'), - getter: (ingress: Ingress) => + getValue: ingress => ingress.spec?.ingressClassName, + render: ingress => ingress.spec?.ingressClassName ? ( {ingress.spec?.ingressClassName} ) : null, - sort: true, }, { id: 'hosts', label: t('Hosts'), - getter: (ingress: Ingress) => ( + getValue: ingress => + ingress + .getRules() + .map(r => r.host ?? '*') + .join(''), + render: ingress => ( host || '*')} /> ), }, { id: 'ports', label: t('translation|Path'), - getter: (ingress: Ingress) => , + getValue: () => '', + render: (ingress: Ingress) => , }, 'age', ]} diff --git a/frontend/src/components/ingress/__snapshots__/ClassDetails.stories.storyshot b/frontend/src/components/ingress/__snapshots__/ClassDetails.stories.storyshot index 7e977de744e..15f7d290f41 100644 --- a/frontend/src/components/ingress/__snapshots__/ClassDetails.stories.storyshot +++ b/frontend/src/components/ingress/__snapshots__/ClassDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots IngressClass/DetailsView Basic 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,161 +52,640 @@ exports[`Storyshots IngressClass/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - + + + +
+
- - +
+
+
+ +
+
+
+ + + + + +
+ +
+
- Name -
- Controller - - Age -
- - - - + - + +
+ +
+ + + + + + - - - + + + + - test - - + + + + + + +
- - - resource-example-ingress - - - test - -

+

+ +
+ +
+
+ +
+
+ +
+ +
+
+
- 3mo - -

- -
+
+ +
+ +
+
+
-

+

- - -

-
- - resource-example-ingress - - + resource-example-ingress + + + test + +

+ 3mo + +

+
+

+ + +

+
+ + resource-example-ingress + + + test + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ + 1-2 of 2 + +
- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/ingress/__snapshots__/Details.stories.storyshot b/frontend/src/components/ingress/__snapshots__/Details.stories.storyshot index d931876a98e..c8ea76582ee 100644 --- a/frontend/src/components/ingress/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/ingress/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots Ingress/DetailsView With Resource 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,230 +52,874 @@ exports[`Storyshots Ingress/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Class Name - - Hosts - - Path - - Age -
- - - - + +
+ +
+ + + + + + - - + - + + + + + - - https-example.foo.com - - - + + + + + + + +
- - tls-example-ingress - - - + +
+ +
+ + +
- default - - - - - + +
+ +
+ + +
- https-example.foo.com - - - - + +
+ +
+ + +
- / 🞂 service1:80, /second 🞂 service2:someport - - - -

+

+
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
- - resource-example-ingress - - - + tls-example-ingress + + - default - - - + default + + + + + https-example.foo.com + + + + / 🞂 service1:80, /second 🞂 service2:someport + + +

+ 3mo + +

+
+ resource-example-ingress + + + + default + + + + + https-example.foo.com + + + + / 🞂 Service:service1 + + +

+ 3mo + +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
- / 🞂 Service:service1 + 1-2 of 2 - - -

- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/job/List.tsx b/frontend/src/components/job/List.tsx index 4dc78038022..b5037e46e4e 100644 --- a/frontend/src/components/job/List.tsx +++ b/frontend/src/components/job/List.tsx @@ -98,18 +98,21 @@ export function JobsListRenderer(props: JobsListRendererProps) { { id: 'completions', label: t('Completions'), - getter: job => getCompletions(job), + getValue: job => getCompletions(job), sort: sortByCompletions, }, { id: 'conditions', label: t('translation|Conditions'), - getter: job => makePodStatusLabel(job), + getValue: job => + job.status?.conditions?.find(({ status }: { status: string }) => status === 'True') ?? + null, + render: job => makePodStatusLabel(job), }, { id: 'duration', label: t('translation|Duration'), - getter: job => { + getValue: job => { const startTime = job.status?.startTime; const completionTime = job.status?.completionTime; if (!!startTime && !!completionTime) { @@ -118,13 +121,16 @@ export function JobsListRenderer(props: JobsListRendererProps) { } return '-'; }, - gridTemplate: 0.6, - sort: true, }, { id: 'containers', label: t('Containers'), - getter: job => { + getValue: job => + job + .getContainers() + .map(c => c.name) + .join(''), + render: job => { const containerNames = job.getContainers().map((c: KubeContainer) => c.name); const containerTooltip = containerNames.join('\n'); const containerText = containerNames.join(', '); @@ -138,7 +144,12 @@ export function JobsListRenderer(props: JobsListRendererProps) { { id: 'images', label: t('Images'), - getter: job => { + getValue: job => + job + .getContainers() + .map(c => c.image) + .join(''), + render: job => { const containerImages = job.getContainers().map((c: KubeContainer) => c.image); const containerTooltip = containerImages.join('\n'); const containerText = containerImages.join(', '); diff --git a/frontend/src/components/job/__snapshots__/JobList.stories.storyshot b/frontend/src/components/job/__snapshots__/JobList.stories.storyshot index 7718ff50431..e94a0463abc 100644 --- a/frontend/src/components/job/__snapshots__/JobList.stories.storyshot +++ b/frontend/src/components/job/__snapshots__/JobList.stories.storyshot @@ -33,45 +33,17 @@ exports[`Storyshots Job/List Items 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -80,404 +52,1191 @@ exports[`Storyshots Job/List Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - - - + + + +
+
- Name - - - Namespace - - +
+
+ +
+
+ + + + + + +
+ +
+
- Completions -
- Conditions - - Duration - - Containers - - Images - - Age -
- - - - - - - - - - - - - - + +
+ +
+ + + + + - - + + + + + + + + + - - default - - - + + + + + + + + + - 1/1 - - + + + + + + + + + + +
- - job-0 - - - - default - - - 1/1 - -
- - Complete
- +
+ Name +
+ + + + + + 0 + +
-
-
-
- 8h - - + + + + + - hello - - - - + +
+ +
+ + +
- busybox:1.28 - - - -

+

+
+ +
+ + +
- 3mo - -

- -
- - job-1 - - - - default - - - 1/1 - -
+ +
+ +
+
+ +
- - Failed
- +
+ Duration +
+ + + + + + 0 + +
-
- - -
- 8h - - + + + + + - hello - - - - + +
+ +
+ + +
- busybox:1.28 - - - -

+

+
+ +
+ + +
- 3mo - -

- -
- - job-2 - - + + job-0 + + + + default + + + 1/1 + +
+ + Complete +
+ +
+
+
+
+ 8h + + + hello + + + + busybox:1.28 + + +

+ 3mo + +

+
+ + job-1 + + + + default + + + 1/1 + +
+ + Failed +
+ +
+
+
+
+ 8h + + + hello + + + + busybox:1.28 + + +

+ 3mo + +

+
+ + job-2 + + + + default + + + 1/1 + +
+ + Suspended +
+ +
+
+
+
+ 8h + + + hello + + + + busybox:1.28 + + +

+ 3mo + +

+
+
+
+
+ +
+
- + Rows per page + +
- Suspended - + + +
- - - 8h - - - hello + 1-3 of 3 - - - - busybox:1.28 - - - -

- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/lease/List.tsx b/frontend/src/components/lease/List.tsx index ce549eb52f3..6a791e78e18 100644 --- a/frontend/src/components/lease/List.tsx +++ b/frontend/src/components/lease/List.tsx @@ -14,7 +14,7 @@ export function LeaseList() { { id: 'holder', label: t('translation|Holder'), - getter: item => item?.spec.holderIdentity, + getValue: item => item?.spec.holderIdentity, }, 'age', ]} diff --git a/frontend/src/components/lease/__snapshots__/Details.stories.storyshot b/frontend/src/components/lease/__snapshots__/Details.stories.storyshot index eefc483a63b..f3a2c74f62f 100644 --- a/frontend/src/components/lease/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/lease/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots Lease/LeaseDetailsView Lease Detail 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,124 +52,629 @@ exports[`Storyshots Lease/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name -
- Namespace - - Holder - - Age -
- - - + + + + + - holder - - + + + + + + +
- - lease - - - + +
+ +
+ + +
+
+ +
+ +
+
+
- default - - - + +
+ +
+ + +
+
+ +
+ +
+
+
+ + lease + + + + default + + + holder + +

+ 3mo + +

+
+
+
+
+ +
+
-

- 3mo - -

- - - - + +
+ + + +
+
+ + 1-1 of 1 + +
+ + + + + + +
+
+
+
+ diff --git a/frontend/src/components/limitRange/__snapshots__/Details.stories.storyshot b/frontend/src/components/limitRange/__snapshots__/Details.stories.storyshot index abb44711f30..37ca492981e 100644 --- a/frontend/src/components/limitRange/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/limitRange/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots LimitRange/DetailsView Limit Range Detail 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,113 +52,546 @@ exports[`Storyshots LimitRange/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name -
- Namespace - - Age -
- - + + + + - + + limit-range + + + - + + + + +
- +
+ +
+ +
+
+ +
- limit-range - - - + +
+ +
+ + +
+
+ +
+ +
+
+
- default - - + default + + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ + 1-1 of 1 + +
- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/namespace/List.tsx b/frontend/src/components/namespace/List.tsx index a6a25b8a31f..bdb29c2ff7f 100644 --- a/frontend/src/components/namespace/List.tsx +++ b/frontend/src/components/namespace/List.tsx @@ -37,53 +37,55 @@ export default function NamespacesList() { return {status}; } - const resourceTableProps: ResourceTableFromResourceClassProps | ResourceTableProps = - React.useMemo(() => { - if (allowedNamespaces.length > 0) { - return { - columns: [ - { - id: 'name', - label: t('translation|Name'), - getter: ({ metadata }) => ( - - {metadata.name} - - ), - }, - { - id: 'status', - label: t('translation|Status'), - getter: () => 'Unknown', - }, - { - id: 'age', - label: t('translation|Age'), - getter: () => 'Unknown', - }, - ], - data: allowedNamespaces, - }; - } + const resourceTableProps: + | ResourceTableFromResourceClassProps + | ResourceTableProps = React.useMemo(() => { + if (allowedNamespaces.length > 0) { return { - resourceClass: Namespace, columns: [ - 'name', + { + id: 'name', + label: t('translation|Name'), + getValue: ns => ns.metadata.name, + render: ({ metadata }) => ( + + {metadata.name} + + ), + }, { id: 'status', label: t('translation|Status'), - getter: makeStatusLabel, - sort: (namespace: Namespace) => namespace.status.phase, + getValue: () => 'Unknown', + }, + { + id: 'age', + label: t('translation|Age'), + getValue: () => 'Unknown', }, - 'age', ], + data: allowedNamespaces as unknown as Namespace[], }; - }, [allowedNamespaces]); + } + return { + resourceClass: Namespace, + columns: [ + 'name', + { + id: 'status', + label: t('translation|Status'), + getValue: ns => ns.status.phase, + render: makeStatusLabel, + }, + 'age', + ], + }; + }, [allowedNamespaces]); return ( +
+ +
+ - - - -
-
- - - - - - - - - - + + + + + + + +
+
- - - - - - - - - - + + + - - + - - - - - + + + - + - - + + + - - - + - + - + + + + + + + + + + + + + + + +
- - test-cpu-quota - - -
- - requests.cpu: 0.5 cores/0.2 cores - +
+ Name +
+ + + + + + 0 + + +
+
+ +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - +
+ Request +
+ + + + + + 0 + + +
+
+ +
- - -
-

- 3mo - -

-
- - test-cpu-quota - - -
+
- - requests.cpu: 0.5 cores/0.2 cores - +
+ Limit +
+ + + + + + 0 + + +
+
+ +
- - -
-
+
- - limits.cpu: 0 cores/0.3 cores - +
+ Age +
+ + + + + + 0 + + +
+
+ +
- - -
-

- 3mo - -

-
- - test-cpu-quota - - -
+ test-cpu-quota + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
-

- 3mo - -

-
- + +

+ 3mo + +

+
- test-cpu-quota - - -
+ test-cpu-quota + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
-

+

+

+ 3mo + +

+
- 3mo - -

-
- + test-cpu-quota + + - test-cpu-quota - - -
+
+ + requests.cpu: 0.5 cores/0.2 cores + +
+
+
- - requests.cpu: 0.5 cores/0.2 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
+ +

+ 3mo + +

+
+ + test-cpu-quota + + +
+
+ + requests.cpu: 0.5 cores/0.2 cores + +
+
+
+
+
+ + limits.cpu: 0 cores/0.3 cores + +
+
+
+

+ 3mo + +

+
+ + test-cpu-quota + + +
+
+ + requests.cpu: 0.5 cores/0.2 cores + +
+
+
+
+
+ + limits.cpu: 0 cores/0.3 cores + +
+
+
+

+ 3mo + +

+
+
+
+
+ +
+
+
- + 15 +
+ +
- - -

- 3mo - -

- - - - + 1-5 of 5 + +
+ + + + + + +
+
+
+
+
@@ -616,910 +1124,1971 @@ exports[`Storyshots Namespace/DetailsView Active 1`] = ` /> + +
+
+
+ +
+
+
+ -
-
-
-
-
- - - +
-
- - - - - - - - - -
- Name - - Age -
- - limit-range - - -

- 3mo - -

-
-
-
- - - -
-
-
-
-
-
-

- Pods -

-
+ + + +
+
+
-
-
-
- -
-
-
-
-
-
- + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ + limit-range + + +

+ 3mo + +

+
+
+
- - +
- - Name - - - - Restarts -
+ + 1-1 of 1 + +
- - - - - Ready - - + + + + + +
+
+
+
+ + + + + + +
+
+
+
+
+
+

+ Pods +

+
+
+
+
+
+
+
+
+
+
- Status - - - +
+
+ +
+
+
+
+
+
+
+ +
+ +
+
- IP - - - Node - - - Age - - - - +
+
+
+
+ - - - - - - + + + + + + + + - - my-node + imagepullbackoff - - - + + - - - + - - - - - + + + - + + - - - + - - - - - + + + - + + - - - + - - - - - + + + - - - - + + + - - - + + - - + + + - + + - - - + - - - - - + + + - + + - - - + - - - - - + + + - + + - - - + - - - - - + + + - + + + + + + + + +
- - imagepullbackoff - - - 0 - - 0/1 - -
+ +
+ +
+
+ +
- - ImagePullBackOff - - - - - 0.0.0.2 - +
+ Restarts +
+ + + + + + 0 + + + +
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
-

+

+ 0 + + 0/1 + - 3mo - -

-
- + + ImagePullBackOff + + + - successful - - - 0 - - 0/1 - -
+
- Completed + + my-node + - - - 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + successful - - -

+

+ 0 + + 0/1 + - 3mo - -

-
- + + Completed + + + - initializing - - - 0 - - 0/1 - -
+
- Init:0/2 + + my-node + - - - 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + initializing - - -

+

+ 0 + + 0/1 + - 3mo - -

-
- + + Init:0/2 + + + - liveness-http - - - 337 (3mo ago) - - 0/1 - -
+
- CrashLoopBackOff -
- -
+ my-node +
- -
- 0.0.0.2 - - + +

+ 3mo + +

+
- my-node - - - -

- 3mo - -

-
- + liveness-http + + + 337 (3mo ago) + + 0/1 + - terminated - - - 0 - - 0/1 - -
+ + CrashLoopBackOff +
+ +
+
+
+
+ 0.0.0.2 + - Error -
- -
+ my-node +
- -
- 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + terminated - - -

+

+ 0 + + 0/1 + - 3mo - -

-
- + + Error +
+ +
+
+ +
- running - - - 0 - - 1/1 - -
+
- Running + + my-node + - - - 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + running - - -

+

+ 0 + + 1/1 + - 3mo - -

-
- + + Running + + + - nominated-node - - - 0 - - 1/1 - -
+
- Running + + my-node + - - - 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + nominated-node - - -

+

+ 0 + + 1/1 + - 3mo - -

-
- + + Running + + + - readiness-gate - - - 0 - - 1/1 - -
+
- Running + + my-node + - - - 0.0.0.2 - - + +

+ 3mo + +

+
- my-node + readiness-gate - - + + 0 + + 1/1 + +
+ + Running + +
+
+ 0.0.0.2 + + + + my-node + + + +

+ 3mo + +

+
+
+
+
+ +
+
-

- 3mo - -

- - - - + +
+ + + +
+
+ + 1-8 of 8 + +
+ + + + + + +
+
+
+
+
diff --git a/frontend/src/components/namespace/__snapshots__/NamespaceList.stories.storyshot b/frontend/src/components/namespace/__snapshots__/NamespaceList.stories.storyshot index ccd549b4887..54ecd5e3989 100644 --- a/frontend/src/components/namespace/__snapshots__/NamespaceList.stories.storyshot +++ b/frontend/src/components/namespace/__snapshots__/NamespaceList.stories.storyshot @@ -33,45 +33,17 @@ exports[`Storyshots Namespace/ListView Regular 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -80,261 +52,706 @@ exports[`Storyshots Namespace/ListView Regular 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name -
- Status - - Age -
- - - - + +
+ +
+ + + + + - - + - + - - - + + - - namespace-2 - - - + - + - - - + + - + + namespace-2 + + + - + + + - - Active - - - + + + + -

- 3mo - -

- - - + namespace-4 + + + + + + + +
- - namespace-0 - - - + +
+ +
+ + +
- Active - - - -

+

+
+ +
+ + +
- 3mo - -

- -
- - namespace-1 - - - + namespace-0 + + - Active - - -

+ Active + +

- 3mo - -

-
+ 3mo + +

+
- + namespace-1 + + - Active - - -

+ Active + +

- 3mo - -

-
+ 3mo + +

+
- namespace-3 - - + Active + + +

+ 3mo + +

+
+ namespace-3 + + + + Active + + +

+ 3mo + +

+
+ + Active + + +

+ 3mo + +

+
+
+
+
+ +
- - - namespace-4 - - - + +
+ + + +
+
- Active + 1-5 of 5 - - -

- 3mo - -

- - - - + + + + + + +
+
+ + + diff --git a/frontend/src/components/networkpolicy/List.tsx b/frontend/src/components/networkpolicy/List.tsx index f023c7b7764..8cd2e8a6be4 100644 --- a/frontend/src/components/networkpolicy/List.tsx +++ b/frontend/src/components/networkpolicy/List.tsx @@ -15,7 +15,7 @@ export function NetworkPolicyList() { { id: 'type', label: t('translation|Type'), - getter: networkpolicy => { + getValue: networkpolicy => { console.log(networkpolicy); const isIngressAvailable = networkpolicy.jsonData.spec.ingress && networkpolicy.jsonData.spec.ingress.length > 0; @@ -33,7 +33,15 @@ export function NetworkPolicyList() { { id: 'podSelector', label: t('Pod Selector'), - getter: networkpolicy => { + getValue: networkpolicy => { + const podSelector = networkpolicy.jsonData.spec.podSelector; + return podSelector.matchLabels + ? Object.keys(podSelector.matchLabels) + .map(key => `${key}=${podSelector.matchLabels[key]}`) + .join(', ') + : null; + }, + render: networkpolicy => { const podSelector = networkpolicy.jsonData.spec.podSelector; return podSelector.matchLabels ? ( ( + getValue: node => { + const [used] = getResourceMetrics(node, nodeMetrics || [], 'cpu'); + return used; + }, + render: node => ( ( + getValue: node => { + const [used] = getResourceMetrics(node, nodeMetrics || [], 'memory'); + return used; + }, + render: node => ( , + getValue: node => { + const isReady = !!node.status.conditions.find( + condition => condition.type === 'Ready' && condition.status === 'True' + ); + return isReady ? t('translation|Yes') : t('translation|No'); + }, + render: node => , }, { id: 'taints', label: t('translation|Taints'), - getter: (item: Node) => , + getValue: node => + node.spec?.taints?.map(taint => `${taint.key}:${taint.effect}`)?.join(', '), + render: (item: Node) => , }, { id: 'roles', label: t('Roles'), - gridTemplate: 'minmax(100px, .5fr)', - getter: node => { + getValue: node => { return Object.keys(node.metadata.labels) .filter((t: String) => t.startsWith('node-role.kubernetes.io/')) .map(t => t.replace('node-role.kubernetes.io/', '')) @@ -76,24 +91,23 @@ export default function NodeList() { { id: 'internalIP', label: t('translation|Internal IP'), - getter: node => node.getInternalIP(), + getValue: node => node.getInternalIP(), }, { id: 'externalIP', label: t('External IP'), - getter: node => node.getExternalIP(), + getValue: node => node.getExternalIP(), }, { id: 'version', label: t('translation|Version'), - gridTemplate: 'minmax(100px, .5fr)', - getter: node => node.status.nodeInfo.kubeletVersion, + getValue: node => node.status.nodeInfo.kubeletVersion, }, { id: 'software', label: t('translation|Software'), - gridTemplate: 'minmax(200px, 1.5fr)', - getter: node => { + getValue: node => node.status.nodeInfo.operatingSystem, + render: node => { let osIcon = 'mdi:desktop-classic'; if (node.status.nodeInfo.operatingSystem === 'linux') { osIcon = 'mdi:linux'; diff --git a/frontend/src/components/node/__snapshots__/List.stories.storyshot b/frontend/src/components/node/__snapshots__/List.stories.storyshot index 2712df3ba86..faad65bce10 100644 --- a/frontend/src/components/node/__snapshots__/List.stories.storyshot +++ b/frontend/src/components/node/__snapshots__/List.stories.storyshot @@ -36,45 +36,17 @@ exports[`Storyshots node/List Nodes 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -83,267 +55,1225 @@ exports[`Storyshots node/List Nodes 1`] = ` class="MuiBox-root css-1txv3mw" >
- - +
+
+ +
+
+ + - - - - - - - - - - - - - + + + +
+
+ +
+ +
+
- Name + -
- CPU - - Memory - - Ready - - Taints - - Roles - - Internal IP - - External IP - - Version - - Age -
- - - - - - - - - - - - + +
+ +
+ + + + + + + + + + + + + - - + + + + + + + + + + + -
- -
+ + + + + + + + + + + + +
- - my-windows-node - - -
-
-
-
- - Yes - - -
-
- agent - - 1.2.3.4 - - - - v1.26.3 - -

+

+
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- - my-linux-node - - + + my-windows-node + + +
+
+
+
+ + Yes + + +
+
+ agent + + 1.2.3.4 + + + + v1.26.3 + +

+ 3mo + +

+
+ + my-linux-node + + +
+
+
+
+ + Yes + + +
+
+ + + 10.2.3.4 + + + + v1.23.12 + +

+ 3mo + +

+
+
+
+
+ +
+
- - + class="MuiBox-root css-exd1zr" + > + +
+ + + +
+
- Yes + 1-2 of 2 - -
- - - - - - 10.2.3.4 - - - - - - v1.23.12 - - -

- 3mo - -

- - - - + + + + + + +
+
+
+
+
diff --git a/frontend/src/components/node/utils.tsx b/frontend/src/components/node/utils.tsx index 32dfb96317f..618fef9833c 100644 --- a/frontend/src/components/node/utils.tsx +++ b/frontend/src/components/node/utils.tsx @@ -24,7 +24,7 @@ export function NodeTaintsLabel(props: { node: Node }) { const limits: JSX.Element[] = []; node.spec.taints.forEach(taint => { limits.push( - + ); diff --git a/frontend/src/components/pod/List.tsx b/frontend/src/components/pod/List.tsx index 5612e300cf5..1b31a5a9b08 100644 --- a/frontend/src/components/pod/List.tsx +++ b/frontend/src/components/pod/List.tsx @@ -99,7 +99,7 @@ export function PodListRenderer(props: PodListProps) { 'namespace', { label: t('Restarts'), - getter: (pod: Pod) => { + getValue: (pod: Pod) => { const { restarts, lastRestartDate } = pod.getDetailedStatus(); return lastRestartDate.getTime() !== 0 ? t('{{ restarts }} ({{ abbrevTime }} ago)', { @@ -108,12 +108,11 @@ export function PodListRenderer(props: PodListProps) { }) : restarts; }, - sort: true, }, { id: 'ready', label: t('translation|Ready'), - getter: (pod: Pod) => { + getValue: (pod: Pod) => { const podRow = pod.getDetailedStatus(); return `${podRow.readyContainers}/${podRow.totalContainers}`; }, @@ -121,51 +120,55 @@ export function PodListRenderer(props: PodListProps) { { id: 'status', label: t('translation|Status'), - getter: makePodStatusLabel, - sort: (pod: Pod) => { - const podRow = pod.getDetailedStatus(); - return podRow.reason; - }, + getValue: pod => pod.getDetailedStatus().reason, + render: makePodStatusLabel, }, { id: 'ip', label: t('glossary|IP'), - getter: (pod: Pod) => pod.status.podIP, - sort: true, + getValue: (pod: Pod) => pod.status.podIP, }, { id: 'node', label: t('glossary|Node'), - getter: (pod: Pod) => + getValue: pod => pod?.spec?.nodeName, + render: pod => pod?.spec?.nodeName && ( {pod.spec.nodeName} ), - sort: (p1: Pod, p2: Pod) => { - return p1?.spec?.nodeName?.localeCompare(p2?.spec?.nodeName || '') || 0; - }, }, { id: 'nominatedNode', label: t('glossary|Nominated Node'), - getter: (pod: Pod) => + getValue: pod => pod?.status?.nominatedNodeName, + render: pod => !!pod?.status?.nominatedNodeName && ( {pod?.status?.nominatedNodeName} ), - sort: (p1: Pod, p2: Pod) => { - return ( - p1?.status?.nominatedNodeName?.localeCompare(p2?.status?.nominatedNodeName || '') || 0 - ); - }, show: false, }, { id: 'readinessGates', label: t('glossary|Readiness Gates'), - getter: (pod: Pod) => { + getValue: pod => { + const readinessGatesStatus = getReadinessGatesStatus(pod); + const total = Object.keys(readinessGatesStatus).length; + + if (total === 0) { + return ''; + } + + const statusTrueCount = Object.values(readinessGatesStatus).filter( + status => status === 'True' + ).length; + + return statusTrueCount; + }, + render: (pod: Pod) => { const readinessGatesStatus = getReadinessGatesStatus(pod); const total = Object.keys(readinessGatesStatus).length; diff --git a/frontend/src/components/pod/__snapshots__/PodDetails.stories.storyshot b/frontend/src/components/pod/__snapshots__/PodDetails.stories.storyshot index 38dc8a8459b..f0f9fc69a32 100644 --- a/frontend/src/components/pod/__snapshots__/PodDetails.stories.storyshot +++ b/frontend/src/components/pod/__snapshots__/PodDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots Pod/PodDetailsView Error 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,836 +52,1641 @@ exports[`Storyshots Pod/PodListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Restarts - - Ready - - Status - - IP -
+ +
+ + + +
+
+ + 1-8 of 8 + +
+ + + + + + +
+ + + + diff --git a/frontend/src/components/pod/__snapshots__/PodLogs.stories.storyshot b/frontend/src/components/pod/__snapshots__/PodLogs.stories.storyshot index 5d91b56a476..e000d820adf 100644 --- a/frontend/src/components/pod/__snapshots__/PodLogs.stories.storyshot +++ b/frontend/src/components/pod/__snapshots__/PodLogs.stories.storyshot @@ -14,12 +14,12 @@ exports[`Storyshots Pod/PodLogs Logs 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,365 +52,1027 @@ exports[`Storyshots PDB/PDBListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Min Available - - Max Unavailable - - Allowed Disruptions - - Age -
- - - - - - - - - - - - - - - - - - - - - - + + - + +
+ +
+ + + + + + - - - + + + + + + + - 1 - - + + + + + + + - N/A - - + + + + + + + - 1 - - + + + + + + + -

+ + coredns-pdb + + +

+ + + - - + + + + +
- - coredns-pdb - - - - kube-system - - - 1 - - N/A - - 1 - -

- 3mo - -

-
- - coredns-pdb - - - - kube-system - - - 1 - - N/A - - 1 - -

+

+
+ +
+ + +
- 3mo - -

- -
- - coredns-pdb - - - - kube-system - - - 1 - - N/A - - 1 - -

+

+
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- 3mo - -

- -
+
+ +
+ +
+
+
- - coredns-pdb - - - - kube-system - - + + coredns-pdb + + + + kube-system + + + 1 + + N/A + + 1 + +

+ 3mo + +

+
+ + coredns-pdb + + + + kube-system + + + 1 + + N/A + + 1 + +

+ 3mo + +

+
+ + coredns-pdb + + + + kube-system + + + 1 + + N/A + + 1 + +

+ 3mo + +

+
+ + coredns-pdb + + + + kube-system + + + 1 + + N/A + + 1 + +

+ 3mo + +

+
+ + kube-system + + + 1 + + N/A + - 3mo - -

-
+

+ 3mo + +

+
+
+
+
+ +
- - - coredns-pdb - - - - - kube-system - - - - 1 - - - N/A - - - 1 - - -

+ +

+ + + +
+
+ + 1-5 of 5 + +
- 3mo - -

- - - - + + + + + + +
+
+
+ + diff --git a/frontend/src/components/priorityClass/List.tsx b/frontend/src/components/priorityClass/List.tsx index 3481579a2c3..baf7518135f 100644 --- a/frontend/src/components/priorityClass/List.tsx +++ b/frontend/src/components/priorityClass/List.tsx @@ -14,14 +14,12 @@ export default function PriorityClassList() { { id: 'value', label: t('translation|Value'), - getter: item => item.value, - sort: true, + getValue: item => item.value, }, { id: 'globalDefault', label: t('translation|Global Default'), - getter: item => item.globalDefault || 'False', - sort: true, + getValue: item => String(item.globalDefault || 'False'), }, 'age', ]} diff --git a/frontend/src/components/priorityClass/__snapshots__/priorityClassDetails.stories.storyshot b/frontend/src/components/priorityClass/__snapshots__/priorityClassDetails.stories.storyshot index 896fde7bf29..9cd14267934 100644 --- a/frontend/src/components/priorityClass/__snapshots__/priorityClassDetails.stories.storyshot +++ b/frontend/src/components/priorityClass/__snapshots__/priorityClassDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots PriorityClass/PriorityClassDetailsView Default 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,278 +52,788 @@ exports[`Storyshots PriorityClass/PriorityClassListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Value -
- Global Default - - Age -
- - - - - - - - - - + +
+ +
+ + + + + - - - - + - - - + + + - + + high-priority-apps + + + - + + + - 1000000 - - + + + + + - False - - + + + + + -

- 3mo - -

- - - + high-priority-apps + + + + + + + + +
- - high-priority-apps - - - 1000000 - - False - -

+

+
+ +
+ + +
- 3mo - -

- -
- + +
+ +
+ + +
- high-priority-apps - - - - 1000000 - - False - -

+

+
+ +
+ + +
- 3mo - -

- -
- - high-priority-apps - - - 1000000 - - False - -

+ high-priority-apps + +

- 3mo - -

-
+ + False + +

+ 3mo + +

+
- high-priority-apps - - + + False + +

+ 3mo + +

+
+ + high-priority-apps + + + 1000000 + + False + +

+ 3mo + +

+
+ + high-priority-apps + + + 1000000 + + False + +

+ 3mo + +

+
+ 1000000 + + False + +

+ 3mo + +

+
+
+
+
+ +
- - - high-priority-apps - - - - 1000000 - - - False - - -

+ Rows per page + +

+ + + +
+
+ - 3mo - -

- - - - + 1-5 of 5 +
+
+ + + + + + +
+
+
+ + diff --git a/frontend/src/components/replicaset/List.tsx b/frontend/src/components/replicaset/List.tsx index fa72b9973db..040d6e48507 100644 --- a/frontend/src/components/replicaset/List.tsx +++ b/frontend/src/components/replicaset/List.tsx @@ -17,35 +17,33 @@ export default function ReplicaSetList() { { id: 'generation', label: t('Generation'), - getter: replicaSet => replicaSet?.status?.observedGeneration, - sort: true, + getValue: replicaSet => replicaSet?.status?.observedGeneration, show: false, }, { id: 'currentReplicas', label: t('translation|Current', { context: 'replicas' }), - getter: replicaSet => replicaSet?.status?.replicas || 0, - gridTemplate: 0.6, - sort: true, + getValue: replicaSet => replicaSet?.status?.replicas || 0, }, { id: 'desiredReplicas', label: t('translation|Desired', { context: 'replicas' }), - getter: replicaSet => replicaSet?.spec?.replicas || 0, - gridTemplate: 0.6, - sort: true, + getValue: replicaSet => replicaSet?.spec?.replicas || 0, }, { id: 'readyReplicas', label: t('translation|Ready'), - getter: replicaSet => replicaSet?.status?.readyReplicas || 0, - gridTemplate: 0.6, - sort: true, + getValue: replicaSet => replicaSet?.status?.readyReplicas || 0, }, { id: 'containers', label: t('Containers'), - getter: replicaSet => { + getValue: replicaSet => + replicaSet + .getContainers() + .map(c => c.name) + .join(''), + render: replicaSet => { const containerText = replicaSet .getContainers() .map((c: KubeContainer) => c.name) @@ -56,22 +54,16 @@ export default function ReplicaSetList() { ); }, - sort: (rs1, rs2) => { - const containers1 = rs1 - .getContainers() - .map((c: KubeContainer) => c.name) - .join(''); - const containers2 = rs2 - .getContainers() - .map((c: KubeContainer) => c.name) - .join(''); - return containers1.localeCompare(containers2); - }, }, { id: 'images', label: t('Images'), - getter: replicaSet => { + getValue: replicaSet => + replicaSet + .getContainers() + .map((c: KubeContainer) => c.image) + .join(''), + render: replicaSet => { const imageText = replicaSet .getContainers() .map((c: KubeContainer) => c.image) @@ -82,22 +74,12 @@ export default function ReplicaSetList() { ); }, - sort: (rs1, rs2) => { - const images1 = rs1 - .getContainers() - .map((c: KubeContainer) => c.image) - .join(''); - const images2 = rs2 - .getContainers() - .map((c: KubeContainer) => c.image) - .join(''); - return images1.localeCompare(images2); - }, }, { id: 'selector', label: t('Selector'), - getter: replicaSet => { + getValue: replicaSet => replicaSet.getMatchLabelsList().join(''), + render: replicaSet => { const selectorText = replicaSet.getMatchLabelsList().join('\n'); return ( selectorText && ( @@ -107,7 +89,6 @@ export default function ReplicaSetList() { ) ); }, - sort: true, }, 'age', ]} diff --git a/frontend/src/components/replicaset/__snapshots__/List.stories.storyshot b/frontend/src/components/replicaset/__snapshots__/List.stories.storyshot index ba650fc9ddc..2d5e20d05e1 100644 --- a/frontend/src/components/replicaset/__snapshots__/List.stories.storyshot +++ b/frontend/src/components/replicaset/__snapshots__/List.stories.storyshot @@ -36,45 +36,17 @@ exports[`Storyshots ReplicaSet/List Replica Sets 1`] = `
-
-
-
- -
-
- -
-
-
+ + +
@@ -83,354 +55,1162 @@ exports[`Storyshots ReplicaSet/List Replica Sets 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Current - - Desired - + + + +
+ + + - Ready - - - + - + - + - + - - - - + +
+ +
+ + + + + + + + + - - - - - - - + - + + + + + + - + - - - - - - - - + + - - headlamp - - - + - + + + + + + + + + + +
- Containers - + + + - - - - - Images - + + + - - - - - Selector - + + + - - - - - Age - + + + - - - -
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- - headlamp-release-b123456 - - - - default - - - 0 - - 1 - - 0 - - - headlamp - - - + headlamp-release-b123456 + + - ghcr.io/headlamp-k8s/headlamp:v0.18.0 - - - + default + + + 0 + + 1 + + 0 + + + headlamp + + + + ghcr.io/headlamp-k8s/headlamp:v0.18.0 + + + - app.kubernetes.io/instance=headlamp-release + class="" + data-mui-internal-clone-element="true" + > + app.kubernetes.io/instance=headlamp-release app.kubernetes.io/name=headlamp pod-template-hash=b123456 - - -

+

- 3mo - -

-
- - headlamp-a123456 - - - - default - - - 0 - - 2 - - 0 - + 3mo + +

+
- + headlamp-a123456 + + - ghcr.io/headlamp-k8s/headlamp:latest - - + default + + + 0 + + 2 + + 0 + + + headlamp + + + + ghcr.io/headlamp-k8s/headlamp:latest + + + + k8s-app=headlamp +pod-template-hash=a123456 + + +

+ 3mo + +

+
+
+
+
+ +
+
+
+ +
+ + + +
+
- k8s-app=headlamp -pod-template-hash=a123456 + 1-2 of 2 - -
-

- 3mo - -

-
+ + + + + + +
+ + + + diff --git a/frontend/src/components/resourceQuota/List.tsx b/frontend/src/components/resourceQuota/List.tsx index c882b39eac1..1e9a1e378c6 100644 --- a/frontend/src/components/resourceQuota/List.tsx +++ b/frontend/src/components/resourceQuota/List.tsx @@ -48,7 +48,8 @@ export function ResourceQuotaRenderer(props: ResourceQuotaProps) { { id: 'requests', label: t('translation|Request'), - getter: (item: ResourceQuota) => { + getValue: item => item.requests.join(', '), + render: item => { const requests: JSX.Element[] = []; item.requests.forEach((request: string) => { requests.push(); @@ -65,7 +66,8 @@ export function ResourceQuotaRenderer(props: ResourceQuotaProps) { { id: 'limits', label: t('translation|Limit'), - getter: (item: ResourceQuota) => { + getValue: item => item.limits.join(', '), + render: item => { const limits: JSX.Element[] = []; item.limits.forEach((limit: string) => { limits.push(); diff --git a/frontend/src/components/resourceQuota/__snapshots__/resourceQuotaDetails.stories.storyshot b/frontend/src/components/resourceQuota/__snapshots__/resourceQuotaDetails.stories.storyshot index 6eec658b9ee..aa6c26fde93 100644 --- a/frontend/src/components/resourceQuota/__snapshots__/resourceQuotaDetails.stories.storyshot +++ b/frontend/src/components/resourceQuota/__snapshots__/resourceQuotaDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots ResourceQuota/ResourceQuotaDetailsView Default 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,449 +52,1046 @@ exports[`Storyshots ResourceQuota/ResourceQuotaListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name -
- Namespace - - Request - - Limit - - Age -
- - - - - + - + +
+ +
+ + + + + + - - - + + - - - - - - - + + - + - - - - - - - + + - + - - - - - - + + - - test - - - + + + + + + - + - + + + + +
- - test-cpu-quota - - - - test - - -
- - requests.cpu: 0.5 cores/0.2 cores - +
+ Name +
+ + + + + + 0 + + +
+
+ +
- -
-
+
- +
+ Namespace +
+ + + + + + 0 + + +
+
- limits.cpu: 0 cores/0.3 cores - + +
- - -
-

+

+
+ +
+ +
+
+
- 3mo - -

- -
+
+ +
+ +
+
+
- - test-cpu-quota - - - - test - - - + + test + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
-

+

- 3mo - -

-
- - test-cpu-quota - - - - test - - + 3mo + +

+
+ + test + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
-

+

- 3mo - -

-
- - test-cpu-quota - - - - test - - + 3mo + +

+
+ + test + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
-
+
- - limits.cpu: 0 cores/0.3 cores - + + limits.cpu: 0 cores/0.3 cores + +
- -
-

+

- 3mo - -

-
- - test-cpu-quota - - + 3mo + +

+
+ + test-cpu-quota + + + + test + + +
+
+ + requests.cpu: 0.5 cores/0.2 cores + +
+
+
+
+
+ + limits.cpu: 0 cores/0.3 cores + +
+
+
+

+ 3mo + +

+
+ + test + +
- - requests.cpu: 0.5 cores/0.2 cores - + + requests.cpu: 0.5 cores/0.2 cores + +
- -
+ +
+
+ + limits.cpu: 0 cores/0.3 cores + +
+
+
+

+ 3mo + +

+
+
+
+
+ +
+
+
- + 15 +
+ +
- - -

- 3mo - -

- - - - + 1-5 of 5 + +
+ + + + + + +
+
+
+
+ diff --git a/frontend/src/components/role/BindingList.tsx b/frontend/src/components/role/BindingList.tsx index 0002cd50a10..1a6aedb5adf 100644 --- a/frontend/src/components/role/BindingList.tsx +++ b/frontend/src/components/role/BindingList.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import ClusterRoleBinding from '../../lib/k8s/clusterRoleBinding'; -import RoleBinding, { KubeRoleBinding } from '../../lib/k8s/roleBinding'; +import RoleBinding from '../../lib/k8s/roleBinding'; import { useErrorState, useFilterFunc } from '../../lib/util'; import { Link } from '../common'; import LabelListItem from '../common/LabelListItem'; @@ -35,7 +35,7 @@ export default function RoleBindingList() { const [clusterRoleBindingError, onClusterRoleBindingError] = useErrorState(setupClusterRoleBindings); const { t } = useTranslation(['glossary', 'translation']); - const filterFunc = useFilterFunc(['.jsonData.kind']); + const filterFunc = useFilterFunc(['.jsonData.kind']); function setRoleBindings(newBindings: RoleBinding[] | null, kind: string) { setBindings(currentBindings => ({ ...currentBindings, [kind]: newBindings })); @@ -74,22 +74,24 @@ export default function RoleBindingList() { return null; } - function sortBindings(kind: string, r1: RoleBinding, r2: RoleBinding) { - const groups1 = r1?.subjects - ?.filter(subject => subject.kind === kind) - .map(subject => subject.name); - const groups2 = r2?.subjects - ?.filter(subject => subject.kind === kind) - .map(subject => subject.name); - if (groups1 && groups2) { - return groups1.join('').localeCompare(groups2.join('')); - } else if (groups1) { - return 1; - } else if (groups2) { - return -1; - } else { - return 0; - } + function sortBindings(kind: string) { + return function (r1: RoleBinding, r2: RoleBinding) { + const groups1 = r1?.subjects + ?.filter(subject => subject.kind === kind) + .map(subject => subject.name); + const groups2 = r2?.subjects + ?.filter(subject => subject.kind === kind) + .map(subject => subject.name); + if (groups1 && groups2) { + return groups1.join('').localeCompare(groups2.join('')); + } else if (groups1) { + return 1; + } else if (groups2) { + return -1; + } else { + return 0; + } + }; } RoleBinding.useApiList(setupRoleBindings, onRoleBindingError); @@ -106,7 +108,8 @@ export default function RoleBindingList() { { id: 'namespace', label: t('glossary|Namespace'), - getter: item => + getValue: item => item.getNamespace() ?? t('translation|All namespaces'), + render: item => item.getNamespace() ? ( {item.getNamespace()} @@ -114,18 +117,22 @@ export default function RoleBindingList() { ) : ( t('translation|All namespaces') ), - sort: true, }, { id: 'role', label: t('glossary|Role'), - getter: item => , - sort: true, + getValue: item => item.roleRef.name, + render: item => , }, { id: 'users', label: t('translation|Users'), - getter: (item: KubeRoleBinding) => ( + getValue: item => + item?.subjects + ?.filter(s => s.kind === 'User') + ?.map(s => s.name) + ?.join(' '), + render: item => ( ), - sort: (r1, r2) => sortBindings('User', r1, r2), + sort: sortBindings('User'), }, { id: 'groups', label: t('glossary|Groups'), - getter: (item: KubeRoleBinding) => ( + getValue: item => + item?.subjects + ?.filter(subject => subject.kind === 'Group') + ?.map(subject => subject.name) + ?.join(' '), + render: item => ( ), - sort: (r1, r2) => sortBindings('Group', r1, r2), + sort: sortBindings('Group'), }, { id: 'serviceaccounts', label: t('glossary|Service Accounts'), - getter: (item: KubeRoleBinding) => ( + getValue: item => + item?.subjects + ?.filter(subject => subject.kind === 'ServiceAccount') + ?.map(subject => subject.name) + ?.join(' '), + render: item => ( ), - sort: (r1, r2) => sortBindings('ServiceAccount', r1, r2), + sort: sortBindings('Service Accounts'), }, 'age', ]} diff --git a/frontend/src/components/role/List.tsx b/frontend/src/components/role/List.tsx index b5c801c8bd7..8463ead2ea9 100644 --- a/frontend/src/components/role/List.tsx +++ b/frontend/src/components/role/List.tsx @@ -15,7 +15,7 @@ export default function RoleList() { const [roleError, setRolesError] = useErrorState(setupRoles); const [clusterRoleError, setClusterRolesError] = useErrorState(setupClusterRoles); const { t } = useTranslation('glossary'); - const filterFunc = useFilterFunc(['.jsonData.kind']); + const filterFunc = useFilterFunc(['.jsonData.kind']); function setupRolesWithKind(newRoles: Role[] | null, kind: string) { setRoles(oldRoles => ({ ...(oldRoles || {}), [kind]: newRoles })); @@ -67,7 +67,8 @@ export default function RoleList() { 'type', { label: t('translation|Name'), - getter: item => ( + getValue: item => item.metadata.namespace, + render: item => ( ), - sort: (r1: Role, r2: Role) => { - if (r1.metadata.name < r2.metadata.name) { - return -1; - } else if (r1.metadata.name > r2.metadata.name) { - return 1; - } - return 0; - }, }, 'namespace', 'age', diff --git a/frontend/src/components/runtimeClass/List.tsx b/frontend/src/components/runtimeClass/List.tsx index 2faf53ce098..2f596d21e4c 100644 --- a/frontend/src/components/runtimeClass/List.tsx +++ b/frontend/src/components/runtimeClass/List.tsx @@ -14,7 +14,7 @@ export function RuntimeClassList() { { id: 'handler', label: t('translation|Handler'), - getter: item => item?.jsonData?.handler, + getValue: item => item?.jsonData?.handler, }, 'age', ]} diff --git a/frontend/src/components/runtimeClass/__snapshots__/Details.stories.storyshot b/frontend/src/components/runtimeClass/__snapshots__/Details.stories.storyshot index 71ccece0680..b8f21a8ba5f 100644 --- a/frontend/src/components/runtimeClass/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/runtimeClass/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots RuntimeClass/DetailsView Base 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,97 +52,541 @@ exports[`Storyshots RuntimeClass/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - + + + + + + + +
+
+ + + + + +
+ +
+
- Name -
- Handler - - Age -
- - + + + + - handler - - + + + + + +
- +
+ +
+ +
+
+ +
- runtime-class - - - + +
+ +
+ + +
+
+ +
+ +
+
+
+ + runtime-class + + + handler + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ - 3mo - -

- - - - + 1-1 of 1 +
+
+ + + + + + +
+
+
+
+ diff --git a/frontend/src/components/secret/List.tsx b/frontend/src/components/secret/List.tsx index 9b601a52733..c0206a9f25f 100644 --- a/frontend/src/components/secret/List.tsx +++ b/frontend/src/components/secret/List.tsx @@ -4,7 +4,7 @@ import { useFilterFunc } from '../../lib/util'; import ResourceListView from '../common/Resource/ResourceListView'; export default function SecretList() { - const filterFunc = useFilterFunc(['.jsonData.type']); + const filterFunc = useFilterFunc(['.jsonData.type']); const { t } = useTranslation(['glossary', 'translation']); return ( @@ -18,14 +18,12 @@ export default function SecretList() { { id: 'type', label: t('translation|Type'), - getter: secret => secret.type, - sort: true, + getValue: secret => secret.type, }, { id: 'data', label: t('translation|Data'), - getter: (secret: Secret) => Object.keys(secret.data || {}).length || 0, - sort: true, + getValue: (secret: Secret) => Object.keys(secret.data || {}).length || 0, }, 'age', ]} diff --git a/frontend/src/components/secret/__snapshots__/Details.stories.storyshot b/frontend/src/components/secret/__snapshots__/Details.stories.storyshot index 27e69978c70..c03580a268a 100644 --- a/frontend/src/components/secret/__snapshots__/Details.stories.storyshot +++ b/frontend/src/components/secret/__snapshots__/Details.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots Secret/DetailsView Empty 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,204 +52,764 @@ exports[`Storyshots Secret/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - + + + +
+
- Name - - - Namespace - - +
+
+ +
+
+ + + + + + +
+ +
+
- Type -
- Data - - Age -
- - - - - + + - + +
+ +
+ + + + + - - + - - + + + + + - 3 - - + + + + + + + +
- - my-pvc - - - + +
+ +
+ + +
- default - - - - bla - - 0 - -

+

+
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- 3mo - -

- -
- - my-pvc - - - + my-pvc + + - default - - - test - + default + + + bla + + 0 + +

+ 3mo + +

+
+ + my-pvc + + + + default + + + test + + 3 + +

+ 3mo + +

+
+
+
+
+ +
+
-

+ +

+ + + +
+
+ + 1-2 of 2 + +
- 3mo - -

- - - - + + + + + + +
+
+
+
+ diff --git a/frontend/src/components/service/List.tsx b/frontend/src/components/service/List.tsx index 2edb4df507f..ca63ebf413e 100644 --- a/frontend/src/components/service/List.tsx +++ b/frontend/src/components/service/List.tsx @@ -16,32 +16,29 @@ export default function ServiceList() { { id: 'type', label: t('translation|Type'), - getter: service => service.spec.type, - sort: true, + getValue: service => service.spec.type, }, { id: 'clusterIP', label: t('Cluster IP'), - getter: service => service.spec.clusterIP, - sort: true, + getValue: service => service.spec.clusterIP, }, { id: 'externalIP', label: t('External IP'), - getter: service => service.getExternalAddresses(), - sort: true, + getValue: service => service.getExternalAddresses(), }, { id: 'ports', label: t('Ports'), - getter: service => , - sort: true, + getValue: service => service.getPorts().join(', '), + render: service => , }, { id: 'selector', label: t('Selector'), - getter: service => , - sort: true, + getValue: service => service.getSelector().join(', '), + render: service => , }, 'age', ]} diff --git a/frontend/src/components/serviceaccount/List.tsx b/frontend/src/components/serviceaccount/List.tsx index bdf9302a577..471eefe6827 100644 --- a/frontend/src/components/serviceaccount/List.tsx +++ b/frontend/src/components/serviceaccount/List.tsx @@ -15,9 +15,7 @@ export default function ServiceAccountList() { { id: 'secrets', label: t('Secrets'), - getter: (serviceaccount: ServiceAccount) => serviceaccount?.secrets?.length || 0, - sort: true, - gridTemplate: 0.5, + getValue: (serviceaccount: ServiceAccount) => serviceaccount?.secrets?.length || 0, }, 'age', ]} diff --git a/frontend/src/components/statefulset/List.tsx b/frontend/src/components/statefulset/List.tsx index 58a6c084afd..8eb6b424026 100644 --- a/frontend/src/components/statefulset/List.tsx +++ b/frontend/src/components/statefulset/List.tsx @@ -23,21 +23,18 @@ export default function StatefulSetList() { { id: 'pods', label: t('Pods'), - getter: statefulSet => renderPods(statefulSet), - gridTemplate: 0.6, - sort: true, + getValue: statefulSet => renderPods(statefulSet), }, { id: 'replicas', label: t('Replicas'), - getter: statefulSet => statefulSet.spec.replicas, - gridTemplate: 0.6, - sort: true, + getValue: statefulSet => statefulSet.spec.replicas, }, { id: 'containers', label: t('Containers'), - getter: statefulSet => { + getValue: statefulSet => statefulSet.containerNames.join(', '), + render: statefulSet => { const containerNames = statefulSet.getContainers().map((c: KubeContainer) => c.name); const containerTooltip = containerNames.join('\n'); const containerText = containerNames.join(', '); @@ -52,7 +49,12 @@ export default function StatefulSetList() { { id: 'images', label: t('Images'), - getter: statefulSet => { + getValue: statefulSet => + statefulSet + .getContainers() + .map(it => it.image) + .join(', '), + render: statefulSet => { const containerImages = statefulSet.getContainers().map((c: KubeContainer) => c.image); const containerTooltip = containerImages.join('\n'); const containerText = containerImages.join(', '); diff --git a/frontend/src/components/storage/ClaimList.tsx b/frontend/src/components/storage/ClaimList.tsx index bfea60cdcc6..8d609a8bf2c 100644 --- a/frontend/src/components/storage/ClaimList.tsx +++ b/frontend/src/components/storage/ClaimList.tsx @@ -18,7 +18,8 @@ export default function VolumeClaimList() { { id: 'className', label: t('Class Name'), - getter: volumeClaim => { + getValue: volumeClaim => volumeClaim.spec.storageClassName, + render: volumeClaim => { const name = volumeClaim.spec.storageClassName; if (!name) { return ''; @@ -29,32 +30,28 @@ export default function VolumeClaimList() { ); }, - sort: (v1, v2) => v1.spec.storageClassName.localeCompare(v2.spec.storageClassName), }, { id: 'capacity', label: t('Capacity'), - getter: volumeClaim => volumeClaim.status.capacity?.storage, - sort: true, - gridTemplate: 0.8, + getValue: volumeClaim => volumeClaim.status.capacity?.storage, }, { id: 'accessModes', label: t('Access Modes'), - getter: volumeClaim => , - sort: (v1, v2) => - v1.spec.accessModes.join('').localeCompare(v2.spec.accessModes.join('')), + getValue: volumeClaim => volumeClaim.spec.accessModes.join(', '), + render: volumeClaim => , }, { id: 'volumeMode', label: t('Volume Mode'), - getter: volumeClaim => volumeClaim.spec.volumeMode, - sort: true, + getValue: volumeClaim => volumeClaim.spec.volumeMode, }, { id: 'volume', label: t('Volume'), - getter: volumeClaim => { + getValue: volumeClaim => volumeClaim.spec.volumeName, + render: volumeClaim => { const name = volumeClaim.spec.volumeName; if (!name) { return ''; @@ -69,9 +66,8 @@ export default function VolumeClaimList() { { id: 'status', label: t('translation|Status'), - getter: volume => makePVCStatusLabel(volume), - gridTemplate: 0.3, - sort: true, + getValue: volume => volume.status.phase, + render: volume => makePVCStatusLabel(volume), }, 'age', ]} diff --git a/frontend/src/components/storage/ClassList.tsx b/frontend/src/components/storage/ClassList.tsx index 07a475be832..d9c07df2ce2 100644 --- a/frontend/src/components/storage/ClassList.tsx +++ b/frontend/src/components/storage/ClassList.tsx @@ -17,26 +17,22 @@ export default function ClassList() { { id: 'provisioner', label: t('Provisioner'), - getter: storageClass => storageClass.provisioner, - sort: true, + getValue: storageClass => storageClass.provisioner, }, { id: 'reclaimPolicy', label: t('Reclaim Policy'), - getter: storageClass => storageClass.reclaimPolicy, - sort: true, + getValue: storageClass => storageClass.reclaimPolicy, }, { id: 'volumeBindingMode', label: t('Volume Binding Mode'), - getter: storageClass => storageClass.volumeBindingMode, - sort: true, + getValue: storageClass => storageClass.volumeBindingMode, }, { id: 'allowVolumeExpansion', label: t('Allow Volume Expansion'), - getter: storageClass => storageClass.allowVolumeExpansion, - sort: true, + getValue: storageClass => storageClass.allowVolumeExpansion, }, 'age', ]} diff --git a/frontend/src/components/storage/VolumeList.tsx b/frontend/src/components/storage/VolumeList.tsx index d326568164d..b56e116e3c7 100644 --- a/frontend/src/components/storage/VolumeList.tsx +++ b/frontend/src/components/storage/VolumeList.tsx @@ -20,7 +20,8 @@ export default function VolumeList() { { id: 'className', label: t('Class Name'), - getter: volume => { + getValue: volume => volume.spec.storageClassName ?? '', + render: volume => { const name = volume.spec.storageClassName; if (!name) { return ''; @@ -31,40 +32,38 @@ export default function VolumeList() { ); }, - sort: (v1, v2) => v1.spec.storageClassName.localeCompare(v2.spec.storageClassName), }, { id: 'capacity', label: t('Capacity'), - getter: volume => volume.spec.capacity.storage, - sort: true, + getValue: volume => volume.spec.capacity.storage, }, { id: 'accessModes', label: t('Access Modes'), - getter: volume => , - sort: true, + getValue: volume => volume?.spec?.accesModes?.join(', '), + render: volume => , }, { id: 'reclaimPolicy', label: t('Reclaim Policy'), - getter: volume => volume.spec.persistentVolumeReclaimPolicy, - sort: true, + getValue: volume => volume.spec.persistentVolumeReclaimPolicy, }, { id: 'reason', label: t('translation|Reason'), - getter: volume => { + getValue: volume => volume.status.reason, + render: volume => { const reason = volume.status.reason; return {reason}; }, show: false, - sort: true, }, { id: 'claim', label: t('Claim'), - getter: volume => { + getValue: volume => volume.spec?.claimRef?.name ?? '', + render: volume => { const claim = volume.spec.claimRef?.name; if (!claim) { return null; @@ -81,14 +80,12 @@ export default function VolumeList() { ); }, - sort: true, }, { id: 'status', label: t('translation|Status'), - getter: volume => makePVStatusLabel(volume), - gridTemplate: 0.3, - sort: true, + getValue: volume => volume.status?.phase, + render: volume => makePVStatusLabel(volume), }, 'age', ]} diff --git a/frontend/src/components/storage/__snapshots__/ClaimDetails.stories.storyshot b/frontend/src/components/storage/__snapshots__/ClaimDetails.stories.storyshot index 9bb13fedeee..b57a4f35538 100644 --- a/frontend/src/components/storage/__snapshots__/ClaimDetails.stories.storyshot +++ b/frontend/src/components/storage/__snapshots__/ClaimDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots PersistentVolumeClaim/DetailsView Base 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,195 +52,860 @@ exports[`Storyshots PersistentVolumeClaim/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - - - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- Class Name - - Capacity - + + + +
+ + + - Access Modes - - - + - - + - + - - - - + +
+ +
+ + + + + + + + + + - - - + - - - - + + + + + + + + - - pvc-abc-1234 + no-storage-class-name-pvc - - - - + - - - - - - - - - + + + + + + - - pvc-abc-1234 + no-volume-name-pvc - - - - + - - + + + + + + + + + +
- Volume Mode - + + + - - - - - Volume - - Status - + + + - - - - - Age - + + + - - - -
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- - my-pvc - - - - default - - - + + my-pvc + + default - - - 8Gi - - + - ReadWriteOnce - - - Filesystem - + + default + + + + 8Gi + + + ReadWriteOnce + + + Filesystem + + + + pvc-abc-1234 + + + + + Bound + + +

+ 3mo + +

+
- + - Bound - - -

+ default + +

- 3mo - -

-
- - no-storage-class-name-pvc - - - - default - - - - - 8Gi - - + - ReadWriteOnce - - - Filesystem - + + + ReadWriteOnce + + + Filesystem + + + + pvc-abc-1234 + + + + + Bound + + +

+ 3mo + +

+
- + - Bound - - -

+ default + +

- 3mo - -

-
+ 8Gi + + + ReadWriteOnce + + + Block + + + + + Bound + + +

+ 3mo + +

+
+
+
+
+ +
-
- - no-volume-name-pvc - - - - default - - - - - 8Gi - - - ReadWriteOnce - - - Block - - - + +
+ + + +
+ - Bound + 1-3 of 3 -
-

- 3mo - -

-
+ + + + + + +
+ + + + diff --git a/frontend/src/components/storage/__snapshots__/ClassDetails.stories.storyshot b/frontend/src/components/storage/__snapshots__/ClassDetails.stories.storyshot index b36e11d3512..0f8799731ed 100644 --- a/frontend/src/components/storage/__snapshots__/ClassDetails.stories.storyshot +++ b/frontend/src/components/storage/__snapshots__/ClassDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots StorageClass/DetailsView Base 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,172 +52,788 @@ exports[`Storyshots StorageClass/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - +
-
- - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Provisioner -
- Reclaim Policy - - Volume Binding Mode - + + + +
+ + + - Allow Volume Expansion - - - + + + + + + + + + - Age - - - - - + my-pvc + + + + + + + + + +
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ csi.test + + Delete + + WaitForFirstConsumer + + +

+ 3mo + +

+
+
+
+
-
- - my-pvc - - - csi.test - - Delete - - WaitForFirstConsumer - - -

+ +

+ + + +
+ + + 1-1 of 1 + +
- 3mo - -

-
+ + + + + + +
+ + + + diff --git a/frontend/src/components/storage/__snapshots__/VolumeDetails.stories.storyshot b/frontend/src/components/storage/__snapshots__/VolumeDetails.stories.storyshot index fc65fc077c6..09407c07577 100644 --- a/frontend/src/components/storage/__snapshots__/VolumeDetails.stories.storyshot +++ b/frontend/src/components/storage/__snapshots__/VolumeDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots PersistentVolume/DetailsView Base 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,172 +52,788 @@ exports[`Storyshots PersistentVolume/ListView Items 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - +
-
- - - - - - -
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Provisioner -
- Reclaim Policy - - Volume Binding Mode - + + + +
+ + + - Allow Volume Expansion - - - + + + + + + + + + - Age - - - - - + my-pvc + + + + + + + + + +
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ csi.test + + Delete + + WaitForFirstConsumer + + +

+ 3mo + +

+
+
+
+
-
- - my-pvc - - - csi.test - - Delete - - WaitForFirstConsumer - - -

+ +

+ + + +
+ + + 1-1 of 1 + +
- 3mo - -

-
+ + + + + + +
+ + + + diff --git a/frontend/src/components/verticalPodAutoscaler/List.tsx b/frontend/src/components/verticalPodAutoscaler/List.tsx index d6ded38f3ec..49e1a91dc12 100644 --- a/frontend/src/components/verticalPodAutoscaler/List.tsx +++ b/frontend/src/components/verticalPodAutoscaler/List.tsx @@ -40,18 +40,17 @@ export default function VpaList() { { id: 'cpu', label: t('glossary|CPU'), - getter: item => item?.targetRecommendations?.cpu, + getValue: item => item?.targetRecommendations?.cpu ?? null, }, { id: 'memory', label: t('glossary|Memory'), - getter: item => item?.targetRecommendations?.memory, + getValue: item => item?.targetRecommendations?.memory ?? null, }, { id: 'provided', label: t('translation|Provided'), - getter: item => item?.status?.conditions?.[0]?.status, - sort: true, + getValue: item => item?.status?.conditions?.[0]?.status ?? null, }, 'age', ]} diff --git a/frontend/src/components/verticalPodAutoscaler/__snapshots__/VPADetails.stories.storyshot b/frontend/src/components/verticalPodAutoscaler/__snapshots__/VPADetails.stories.storyshot index 02497ec194d..61c1ce41112 100644 --- a/frontend/src/components/verticalPodAutoscaler/__snapshots__/VPADetails.stories.storyshot +++ b/frontend/src/components/verticalPodAutoscaler/__snapshots__/VPADetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots VPA/VPADetailsView Default 1`] = ` class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -80,365 +52,1027 @@ exports[`Storyshots VPA/VPAListView List 1`] = ` class="MuiBox-root css-1txv3mw" >
- - - - - - - - - - - - + + + +
+
- Name - - +
+
+ +
+
+ + + + + + +
+ +
+
- Namespace -
- CPU - - Memory - - Provided - - Age -
- - - - - - - - - - - - - - - - - - - - - - + + - + +
+ +
+ + + + + + - - - + + + + + + + - 1 - - + + + + + + + - 2Gi - - + + + + + + + - True - - + + + + + + + -

+ + multi-container-vpa + + +

+ + + - - + + + + +
- - multi-container-vpa - - - - default - - - 1 - - 2Gi - - True - -

- 3mo - -

-
- - multi-container-vpa - - - - default - - - 1 - - 2Gi - - True - -

+

+
+ +
+ + +
- 3mo - -

- -
- - multi-container-vpa - - - - default - - - 1 - - 2Gi - - True - -

+

+
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
- 3mo - -

- -
+
+ +
+ +
+
+
- - multi-container-vpa - - - - default - - + + multi-container-vpa + + + + default + + + 1 + + 2Gi + + True + +

+ 3mo + +

+
+ + multi-container-vpa + + + + default + + + 1 + + 2Gi + + True + +

+ 3mo + +

+
+ + multi-container-vpa + + + + default + + + 1 + + 2Gi + + True + +

+ 3mo + +

+
+ + multi-container-vpa + + + + default + + + 1 + + 2Gi + + True + +

+ 3mo + +

+
+ + default + + + 1 + + 2Gi + - 3mo - -

-
+

+ 3mo + +

+
+
+
+
+ +
- - - multi-container-vpa - - - - - default - - - - 1 - - - 2Gi - - - True - - -

+ +

+ + + +
+
+ + 1-5 of 5 + +
- 3mo - -

- - - - + + + + + + +
+
+
+ + diff --git a/frontend/src/components/webhookconfiguration/MutatingWebhookConfigList.tsx b/frontend/src/components/webhookconfiguration/MutatingWebhookConfigList.tsx index f1563285f5f..7ca856f734c 100644 --- a/frontend/src/components/webhookconfiguration/MutatingWebhookConfigList.tsx +++ b/frontend/src/components/webhookconfiguration/MutatingWebhookConfigList.tsx @@ -14,7 +14,7 @@ export default function MutatingWebhookConfigurationList() { { id: 'webhooks', label: t('Webhooks'), - getter: mutatingWebhookConfig => mutatingWebhookConfig.webhooks?.length || 0, + getValue: mutatingWebhookConfig => mutatingWebhookConfig.webhooks?.length || 0, }, 'age', ]} diff --git a/frontend/src/components/webhookconfiguration/ValidatingWebhookConfigList.tsx b/frontend/src/components/webhookconfiguration/ValidatingWebhookConfigList.tsx index 75d85c54053..6123dde71b6 100644 --- a/frontend/src/components/webhookconfiguration/ValidatingWebhookConfigList.tsx +++ b/frontend/src/components/webhookconfiguration/ValidatingWebhookConfigList.tsx @@ -14,7 +14,7 @@ export default function ValidatingWebhookConfigurationList() { { id: 'webhooks', label: t('Webhooks'), - getter: mutatingWebhookConfig => mutatingWebhookConfig.webhooks?.length || 0, + getValue: mutatingWebhookConfig => mutatingWebhookConfig.webhooks?.length || 0, }, 'age', ]} diff --git a/frontend/src/components/webhookconfiguration/__snapshots__/MutatingWebhookConfigDetails.stories.storyshot b/frontend/src/components/webhookconfiguration/__snapshots__/MutatingWebhookConfigDetails.stories.storyshot index 60ede0d92d7..044bfa6f5af 100644 --- a/frontend/src/components/webhookconfiguration/__snapshots__/MutatingWebhookConfigDetails.stories.storyshot +++ b/frontend/src/components/webhookconfiguration/__snapshots__/MutatingWebhookConfigDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots WebhookConfiguration/MutatingWebhookConfig/Details With Serv class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -83,257 +55,716 @@ exports[`Storyshots WebhookConfiguration/MutatingWebhookConfig/List Items 1`] = class="MuiBox-root css-1txv3mw" >
- - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name + -
- Webhooks - - Age -
- - - - - + +
+ +
+ + + + + + - - - + - - - - - + + -

- 3mo - -

- - - - + - - + + -

- 3mo - -

- - - - + + + + - + + mwc-test-with-service-0 + + + + - + + - 1 - - + + + + -

+ + mwc-test-with-service-2 + + +

+ - - + 3mo + +

+ +
+ + +
- - mwc-test-0 - - - 1 - -

+

+
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
- - mwc-test-1 - - - 1 - -

+ mwc-test-0 + +

- 3mo - -

-
- + - mwc-test-2 - - - 1 - + 3mo + +

+
- + mwc-test-1 + + - mwc-test-with-service-0 - - - 1 - + +

+ 3mo + +

+
+ mwc-test-2 + + + 1 + +

+ 3mo + +

+
+ 1 + - mwc-test-with-service-1 - - + 3mo + +

+
+ + mwc-test-with-service-1 + + + 1 + +

+ 3mo + +

+
+ 1 + - 3mo - -

-
+
+
+
+ +
- - - mwc-test-with-service-2 - - - - 1 - - -

+ Rows per page + +

+ + + +
+
+ - 3mo - -

- - - - + 1-6 of 6 +
+
+ + + + + + +
+
+
+ + diff --git a/frontend/src/components/webhookconfiguration/__snapshots__/ValidatingWebhookConfigDetails.stories.storyshot b/frontend/src/components/webhookconfiguration/__snapshots__/ValidatingWebhookConfigDetails.stories.storyshot index 0cdc58e5bcf..37b4643eb1a 100644 --- a/frontend/src/components/webhookconfiguration/__snapshots__/ValidatingWebhookConfigDetails.stories.storyshot +++ b/frontend/src/components/webhookconfiguration/__snapshots__/ValidatingWebhookConfigDetails.stories.storyshot @@ -12,12 +12,12 @@ exports[`Storyshots WebhookConfiguration/ValidatingWebhookConfig/Details With Se class="MuiBox-root css-p0cik4" > - -
- -
- - + + + @@ -83,257 +55,716 @@ exports[`Storyshots WebhookConfiguration/ValidatingWebhookConfig/List Items 1`] class="MuiBox-root css-1txv3mw" >
- - - - - - - - - + + + +
+
+ + + + + +
+ +
+
- Name + -
- Webhooks - - Age -
- - - - - + +
+ +
+ + + + + + - - - + - - - - - + + -

- 3mo - -

- - - - + - - + + -

- 3mo - -

- - - - + + + + - + + vwc-test-with-service-0 + + + + - + + - 1 - - + + + + -

+ + vwc-test-with-service-2 + + +

+ - - + 3mo + +

+ +
+ + +
- - vwc-test-0 - - - 1 - -

+

+
+ +
+ + +
- 3mo - -

- -
+
+ +
+ +
+
+
- - vwc-test-1 - - - 1 - -

+ vwc-test-0 + +

- 3mo - -

-
- + - vwc-test-2 - - - 1 - + 3mo + +

+
- + vwc-test-1 + + - vwc-test-with-service-0 - - - 1 - + +

+ 3mo + +

+
+ vwc-test-2 + + + 1 + +

+ 3mo + +

+
+ 1 + - vwc-test-with-service-1 - - + 3mo + +

+
+ + vwc-test-with-service-1 + + + 1 + +

+ 3mo + +

+
+ 1 + - 3mo - -

-
+
+
+
+ +
- - - vwc-test-with-service-2 - - - - 1 - - -

+ Rows per page + +

+ + + +
+
+ - 3mo - -

- - - - + 1-6 of 6 +
+
+ + + + + + +
+
+
+ + diff --git a/frontend/src/components/workload/Overview.tsx b/frontend/src/components/workload/Overview.tsx index de49cec30b3..7b569657d0a 100644 --- a/frontend/src/components/workload/Overview.tsx +++ b/frontend/src/components/workload/Overview.tsx @@ -25,7 +25,7 @@ interface WorkloadDict { export default function Overview() { const [workloadsData, setWorkloadsData] = React.useState({}); const location = useLocation(); - const filterFunc = useFilterFunc(['.jsonData.kind']); + const filterFunc = useFilterFunc(['.jsonData.kind']); const { t } = useTranslation('glossary'); const cluster = useCluster(); @@ -119,21 +119,16 @@ export default function Overview() { { id: 'name', label: t('translation|Name'), - getter: item => , - sort: (w1: Workload, w2: Workload) => { - if (w1.metadata.name < w2.metadata.name) { - return -1; - } else if (w1.metadata.name > w2.metadata.name) { - return 1; - } - return 0; - }, + getValue: item => item.metadata.name, + render: item => ( + + ), }, 'namespace', { id: 'pods', label: t('Pods'), - getter: item => item && getPods(item), + getValue: item => item && getPods(item), sort: sortByReplicas, }, 'age', diff --git a/frontend/src/i18n/LocaleSelect/__snapshots__/LocaleSelect.stories.storyshot b/frontend/src/i18n/LocaleSelect/__snapshots__/LocaleSelect.stories.storyshot index 4dd8ada1edd..839dbbb44fe 100644 --- a/frontend/src/i18n/LocaleSelect/__snapshots__/LocaleSelect.stories.storyshot +++ b/frontend/src/i18n/LocaleSelect/__snapshots__/LocaleSelect.stories.storyshot @@ -6,7 +6,7 @@ exports[`Storyshots LocaleSelect Initial 1`] = ` class="MuiFormControl-root css-k2e4wk-MuiFormControl-root" >
{ + * // return plain value to allow filtering and sorting + * getValue: (pod: Pod) => { * return pod.spec.initContainers.length; - * }, + * } + * // (optional) customise how the cell value is rendered + * render: (pod: Pod) =>
{pod.spec.initContainers.length}
* }); * } * diff --git a/plugins/examples/tables/src/index.tsx b/plugins/examples/tables/src/index.tsx index d1e8b2219cb..ade07cea45a 100644 --- a/plugins/examples/tables/src/index.tsx +++ b/plugins/examples/tables/src/index.tsx @@ -71,7 +71,8 @@ registerResourceTableColumnsProcessor(function setupContextMenuForPodsList({ id, if (id === 'headlamp-pods') { columns.push({ label: '', - getter: (pod: Pod) => { + getValue: (pod: Pod) => pod.getDetailsLink(), + render: (pod: Pod) => { return ; }, });