From 9c68c6c9f3f5fbc084d1875ac17a048644c6b951 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Tue, 2 Apr 2024 22:55:34 +0300 Subject: [PATCH] refactor(kube/namespaces): migrate item apps table to react [EE-4693] (#11012) --- .../resourcePoolApplicationsDatatable.html | 153 ------------------ .../resourcePoolApplicationsDatatable.js | 13 -- ...urcePoolApplicationsDatatableController.js | 47 ------ app/kubernetes/filters/applicationFilters.js | 6 +- app/kubernetes/react/components/namespaces.ts | 10 +- .../resource-pools/edit/resourcePool.html | 16 +- .../applications/utils/cpuHumanValue.ts | 5 + .../kubernetes/namespaces/ItemView/.keep | 0 .../ItemView/NamespaceAppsDatatable.tsx | 55 +++++++ .../namespaces/ItemView/columns.tsx | 55 +++++++ .../kubernetes/namespaces/ItemView/types.ts | 6 + 11 files changed, 135 insertions(+), 231 deletions(-) delete mode 100644 app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.html delete mode 100644 app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.js delete mode 100644 app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatableController.js create mode 100644 app/react/kubernetes/applications/utils/cpuHumanValue.ts delete mode 100644 app/react/kubernetes/namespaces/ItemView/.keep create mode 100644 app/react/kubernetes/namespaces/ItemView/NamespaceAppsDatatable.tsx create mode 100644 app/react/kubernetes/namespaces/ItemView/columns.tsx create mode 100644 app/react/kubernetes/namespaces/ItemView/types.ts diff --git a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.html b/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.html deleted file mode 100644 index babdb3e46..000000000 --- a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.html +++ /dev/null @@ -1,153 +0,0 @@ -
- - -
-
-
- -
- {{ $ctrl.titleText }} -
- -
- - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - -
- {{ item.Name }} - external - {{ item.StackName || '-' }}{{ item.Image | truncate: 64 }} + {{ item.Containers.length - 1 }}{{ item.CPU | kubernetesApplicationCPUValue }}{{ item.Memory | humansize }}
Loading...
No application available.
-
- -
-
-
diff --git a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.js b/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.js deleted file mode 100644 index 02dba5e79..000000000 --- a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatable.js +++ /dev/null @@ -1,13 +0,0 @@ -angular.module('portainer.kubernetes').component('kubernetesResourcePoolApplicationsDatatable', { - templateUrl: './resourcePoolApplicationsDatatable.html', - controller: 'KubernetesResourcePoolApplicationsDatatableController', - bindings: { - titleText: '@', - titleIcon: '@', - dataset: '<', - tableKey: '@', - orderBy: '@', - reverseOrder: '<', - refreshCallback: '<', - }, -}); diff --git a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatableController.js b/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatableController.js deleted file mode 100644 index e97cf734d..000000000 --- a/app/kubernetes/components/datatables/resource-pool-applications-datatable/resourcePoolApplicationsDatatableController.js +++ /dev/null @@ -1,47 +0,0 @@ -import KubernetesApplicationHelper from 'Kubernetes/helpers/application'; - -angular.module('portainer.docker').controller('KubernetesResourcePoolApplicationsDatatableController', [ - '$scope', - '$controller', - 'DatatableService', - function ($scope, $controller, DatatableService) { - angular.extend(this, $controller('GenericDatatableController', { $scope: $scope })); - - this.isExternalApplication = function (item) { - return KubernetesApplicationHelper.isExternalApplication(item); - }; - - this.$onInit = function () { - this.setDefaults(); - this.prepareTableFromDataset(); - - this.state.orderBy = this.orderBy; - var storedOrder = DatatableService.getDataTableOrder(this.tableKey); - if (storedOrder !== null) { - this.state.reverseOrder = storedOrder.reverse; - this.state.orderBy = storedOrder.orderBy; - } - - var textFilter = DatatableService.getDataTableTextFilters(this.tableKey); - if (textFilter !== null) { - this.state.textFilter = textFilter; - this.onTextFilterChange(); - } - - var storedFilters = DatatableService.getDataTableFilters(this.tableKey); - if (storedFilters !== null) { - this.filters = storedFilters; - } - if (this.filters && this.filters.state) { - this.filters.state.open = false; - } - - var storedSettings = DatatableService.getDataTableSettings(this.tableKey); - if (storedSettings !== null) { - this.settings = storedSettings; - this.settings.open = false; - } - this.onSettingsRepeaterChange(); - }; - }, -]); diff --git a/app/kubernetes/filters/applicationFilters.js b/app/kubernetes/filters/applicationFilters.js index 4b1c97649..c6c354394 100644 --- a/app/kubernetes/filters/applicationFilters.js +++ b/app/kubernetes/filters/applicationFilters.js @@ -1,13 +1,11 @@ -import _ from 'lodash-es'; +import { cpuHumanValue } from '@/react/kubernetes/applications/utils/cpuHumanValue'; import { nodeAffinityValues } from './application'; angular .module('portainer.kubernetes') .filter('kubernetesApplicationCPUValue', function () { 'use strict'; - return function (value) { - return _.round(value, 2); - }; + return cpuHumanValue; }) .filter('kubernetesApplicationDataAccessPolicyIcon', function () { 'use strict'; diff --git a/app/kubernetes/react/components/namespaces.ts b/app/kubernetes/react/components/namespaces.ts index 0f42c5164..3a3c445c1 100644 --- a/app/kubernetes/react/components/namespaces.ts +++ b/app/kubernetes/react/components/namespaces.ts @@ -3,11 +3,11 @@ import angular from 'angular'; import { r2a } from '@/react-tools/react2angular'; import { withUIRouter } from '@/react-tools/withUIRouter'; import { NamespacesDatatable } from '@/react/kubernetes/namespaces/ListView/NamespacesDatatable'; +import { NamespaceAppsDatatable } from '@/react/kubernetes/namespaces/ItemView/NamespaceAppsDatatable'; import { withCurrentUser } from '@/react-tools/withCurrentUser'; export const namespacesModule = angular .module('portainer.kubernetes.react.components.namespaces', []) - .component( 'kubernetesNamespacesDatatable', r2a(withUIRouter(withCurrentUser(NamespacesDatatable)), [ @@ -15,4 +15,12 @@ export const namespacesModule = angular 'onRemove', 'onRefresh', ]) + ) + .component( + 'kubernetesNamespaceApplicationsDatatable', + r2a(withUIRouter(withCurrentUser(NamespaceAppsDatatable)), [ + 'dataset', + 'isLoading', + 'onRefresh', + ]) ).name; diff --git a/app/kubernetes/views/resource-pools/edit/resourcePool.html b/app/kubernetes/views/resource-pools/edit/resourcePool.html index eb77d2ffb..e531ecacc 100644 --- a/app/kubernetes/views/resource-pools/edit/resourcePool.html +++ b/app/kubernetes/views/resource-pools/edit/resourcePool.html @@ -309,18 +309,8 @@ -
-
- - -
+
+ +
diff --git a/app/react/kubernetes/applications/utils/cpuHumanValue.ts b/app/react/kubernetes/applications/utils/cpuHumanValue.ts new file mode 100644 index 000000000..d5d611ef1 --- /dev/null +++ b/app/react/kubernetes/applications/utils/cpuHumanValue.ts @@ -0,0 +1,5 @@ +import _ from 'lodash'; + +export function cpuHumanValue(value: number) { + return _.round(value, 2); +} diff --git a/app/react/kubernetes/namespaces/ItemView/.keep b/app/react/kubernetes/namespaces/ItemView/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/react/kubernetes/namespaces/ItemView/NamespaceAppsDatatable.tsx b/app/react/kubernetes/namespaces/ItemView/NamespaceAppsDatatable.tsx new file mode 100644 index 000000000..dd7f2b572 --- /dev/null +++ b/app/react/kubernetes/namespaces/ItemView/NamespaceAppsDatatable.tsx @@ -0,0 +1,55 @@ +import { Code } from 'lucide-react'; + +import { Datatable, TableSettingsMenu } from '@@/datatables'; +import { useRepeater } from '@@/datatables/useRepeater'; +import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh'; +import { useTableStateWithStorage } from '@@/datatables/useTableState'; +import { + BasicTableSettings, + refreshableSettings, + RefreshableTableSettings, +} from '@@/datatables/types'; + +import { NamespaceApp } from './types'; +import { columns } from './columns'; + +interface TableSettings extends BasicTableSettings, RefreshableTableSettings {} + +export function NamespaceAppsDatatable({ + dataset, + onRefresh, + isLoading, +}: { + dataset: Array; + onRefresh: () => void; + isLoading: boolean; +}) { + const tableState = useTableStateWithStorage( + 'kube-namespace-apps', + 'Name', + (set) => ({ + ...refreshableSettings(set), + }) + ); + useRepeater(tableState.autoRefreshRate, onRefresh); + + return ( + ( + + + + )} + /> + ); +} diff --git a/app/react/kubernetes/namespaces/ItemView/columns.tsx b/app/react/kubernetes/namespaces/ItemView/columns.tsx new file mode 100644 index 000000000..cc61d3152 --- /dev/null +++ b/app/react/kubernetes/namespaces/ItemView/columns.tsx @@ -0,0 +1,55 @@ +import { createColumnHelper } from '@tanstack/react-table'; + +import { humanize, truncate } from '@/portainer/filters/filters'; + +import { Link } from '@@/Link'; +import { ExternalBadge } from '@@/Badge/ExternalBadge'; + +import { isExternalApplication } from '../../applications/utils'; +import { cpuHumanValue } from '../../applications/utils/cpuHumanValue'; + +import { NamespaceApp } from './types'; + +const columnHelper = createColumnHelper(); + +export const columns = [ + columnHelper.accessor('Name', { + header: 'Name', + cell: ({ row: { original: item } }) => ( + <> + + {item.Name} + + {isExternalApplication({ metadata: item.Metadata }) && ( +
+ +
+ )} + + ), + }), + columnHelper.accessor('StackName', { + header: 'Stack', + cell: ({ getValue }) => getValue() || '-', + }), + columnHelper.accessor('Image', { + header: 'Image', + cell: ({ row: { original: item } }) => ( + <> + {truncate(item.Image, 64)} + {item.Containers?.length > 1 && <>+ {item.Containers.length - 1}} + + ), + }), + columnHelper.accessor('CPU', { + header: 'CPU', + cell: ({ getValue }) => cpuHumanValue(getValue()), + }), + columnHelper.accessor('Memory', { + header: 'Memory', + cell: ({ getValue }) => humanize(getValue()), + }), +]; diff --git a/app/react/kubernetes/namespaces/ItemView/types.ts b/app/react/kubernetes/namespaces/ItemView/types.ts new file mode 100644 index 000000000..02cd68470 --- /dev/null +++ b/app/react/kubernetes/namespaces/ItemView/types.ts @@ -0,0 +1,6 @@ +import { KubernetesApplication } from '@/kubernetes/models/application/models'; + +export interface NamespaceApp extends KubernetesApplication { + CPU: number; + Memory: number; +}