From 07e7fbd270f8d5c3f83da8e17a7704d6bec31e13 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Tue, 4 Jan 2022 14:16:09 +0200 Subject: [PATCH] refactor(containers): replace containers datatable with react component [EE-1815] (#6059) --- .eslintrc.yml | 2 + app/assets/css/app.css | 11 + app/assets/css/index.js | 1 + app/docker/__module.js | 6 +- .../ContainerQuickActions.module.css | 3 + .../ContainerQuickActions.tsx | 140 +++++ .../containerQuickActions.html | 65 --- .../containerQuickActions.js | 10 - .../container-quick-actions/index.ts | 7 + .../actions/containersDatatableActions.html | 73 --- .../actions/containersDatatableActions.js | 12 - .../containersDatatableActionsController.js | 112 ---- .../containersDatatable.html | 312 ------------ .../containersDatatable.js | 18 - .../containersDatatableController.js | 210 -------- .../ContainersDatatable.tsx | 249 +++++++++ .../ContainersDatatableActions.tsx | 288 +++++++++++ .../ContainersDatatableContainer.tsx | 52 ++ .../ContainersDatatableSettings.tsx | 35 ++ .../ContainersDatatable/columns/created.tsx | 14 + .../ContainersDatatable/columns/host.tsx | 13 + .../ContainersDatatable/columns/image.tsx | 51 ++ .../ContainersDatatable/columns/index.tsx | 30 ++ .../ContainersDatatable/columns/ip.tsx | 12 + .../ContainersDatatable/columns/name.tsx | 54 ++ .../ContainersDatatable/columns/ownership.tsx | 34 ++ .../ContainersDatatable/columns/ports.tsx | 41 ++ .../columns/quick-actions.tsx | 70 +++ .../ContainersDatatable/columns/stack.tsx | 13 + .../ContainersDatatable/columns/state.tsx | 60 +++ app/docker/containers/containers.service.ts | 101 ++++ app/docker/containers/index.ts | 7 + app/docker/containers/types.ts | 45 ++ app/docker/rest/container.js | 35 -- app/docker/services/containerService.js | 380 +++++++------- app/docker/views/containers/containers.html | 14 +- .../containers/edit/containerController.js | 4 +- .../components/Button/ButtonGroup.tsx | 2 +- .../components/ColumnVisibilityMenu.tsx | 65 +++ .../datatables/components/Filter.tsx | 93 ++++ .../components/QuickActionsSettings.tsx | 49 ++ .../datatables/components/SearchBar.tsx | 59 +++ .../components/SelectedRowsCount.tsx | 9 + .../datatables/components/Table.tsx | 29 ++ .../datatables/components/TableActions.tsx | 9 + .../datatables/components/TableContainer.tsx | 25 + .../datatables/components/TableFooter.tsx | 9 + .../components/TableHeaderCell.module.css | 5 + .../datatables/components/TableHeaderCell.tsx | 90 ++++ .../datatables/components/TableHeaderRow.tsx | 46 ++ .../datatables/components/TableRow.tsx | 35 ++ .../components/TableSettingsMenu.tsx | 44 ++ .../TableSettingsMenuAutoRefresh.module.css | 9 + .../TableSettingsMenuAutoRefresh.tsx | 65 +++ .../datatables/components/TableTitle.tsx | 27 + .../components/TableTitleActions.tsx | 9 + .../datatables/components/filter-types.ts | 14 + .../datatables/components/index.tsx | 9 + .../datatables/components/useRepeater.ts | 42 ++ .../datatables/components/useRowSelect.ts | 478 ++++++++++++++++++ .../components/useTableSettings.tsx | 77 +++ .../components/datatables/datatable.css | 26 + .../components/form-components/Checkbox.tsx | 57 +++ .../ItemsPerPageSelector.tsx | 26 + .../pagination-controls/PageButton.tsx | 29 ++ .../pagination-controls/PageSelector.tsx | 87 ++++ .../PaginationControls.tsx | 46 ++ .../calculatePageNumber.ts | 37 ++ .../pagination-controls/generatePagesArray.ts | 55 ++ .../components/pagination-controls/index.ts | 3 + .../pagination-controls.css | 72 +++ app/portainer/environments/types.ts | 12 + app/portainer/environments/useEnvironment.tsx | 27 + app/portainer/error.js | 6 - app/portainer/error.ts | 8 + app/portainer/hooks/useDebounce.ts | 15 + app/portainer/hooks/useUser.tsx | 7 +- app/react-table-config.d.ts | 156 ++++++ package.json | 5 + yarn.lock | 141 +++++- 80 files changed, 3614 insertions(+), 1084 deletions(-) create mode 100644 app/docker/components/container-quick-actions/ContainerQuickActions.module.css create mode 100644 app/docker/components/container-quick-actions/ContainerQuickActions.tsx delete mode 100644 app/docker/components/container-quick-actions/containerQuickActions.html delete mode 100644 app/docker/components/container-quick-actions/containerQuickActions.js create mode 100644 app/docker/components/container-quick-actions/index.ts delete mode 100644 app/docker/components/datatables/containers-datatable/actions/containersDatatableActions.html delete mode 100644 app/docker/components/datatables/containers-datatable/actions/containersDatatableActions.js delete mode 100644 app/docker/components/datatables/containers-datatable/actions/containersDatatableActionsController.js delete mode 100644 app/docker/components/datatables/containers-datatable/containersDatatable.html delete mode 100644 app/docker/components/datatables/containers-datatable/containersDatatable.js delete mode 100644 app/docker/components/datatables/containers-datatable/containersDatatableController.js create mode 100644 app/docker/containers/components/ContainersDatatable/ContainersDatatable.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/ContainersDatatableActions.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/ContainersDatatableContainer.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/ContainersDatatableSettings.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/created.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/host.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/image.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/index.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/ip.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/name.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/ownership.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/ports.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/quick-actions.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/stack.tsx create mode 100644 app/docker/containers/components/ContainersDatatable/columns/state.tsx create mode 100644 app/docker/containers/containers.service.ts create mode 100644 app/docker/containers/index.ts create mode 100644 app/docker/containers/types.ts create mode 100644 app/portainer/components/datatables/components/ColumnVisibilityMenu.tsx create mode 100644 app/portainer/components/datatables/components/Filter.tsx create mode 100644 app/portainer/components/datatables/components/QuickActionsSettings.tsx create mode 100644 app/portainer/components/datatables/components/SearchBar.tsx create mode 100644 app/portainer/components/datatables/components/SelectedRowsCount.tsx create mode 100644 app/portainer/components/datatables/components/Table.tsx create mode 100644 app/portainer/components/datatables/components/TableActions.tsx create mode 100644 app/portainer/components/datatables/components/TableContainer.tsx create mode 100644 app/portainer/components/datatables/components/TableFooter.tsx create mode 100644 app/portainer/components/datatables/components/TableHeaderCell.module.css create mode 100644 app/portainer/components/datatables/components/TableHeaderCell.tsx create mode 100644 app/portainer/components/datatables/components/TableHeaderRow.tsx create mode 100644 app/portainer/components/datatables/components/TableRow.tsx create mode 100644 app/portainer/components/datatables/components/TableSettingsMenu.tsx create mode 100644 app/portainer/components/datatables/components/TableSettingsMenuAutoRefresh.module.css create mode 100644 app/portainer/components/datatables/components/TableSettingsMenuAutoRefresh.tsx create mode 100644 app/portainer/components/datatables/components/TableTitle.tsx create mode 100644 app/portainer/components/datatables/components/TableTitleActions.tsx create mode 100644 app/portainer/components/datatables/components/filter-types.ts create mode 100644 app/portainer/components/datatables/components/index.tsx create mode 100644 app/portainer/components/datatables/components/useRepeater.ts create mode 100644 app/portainer/components/datatables/components/useRowSelect.ts create mode 100644 app/portainer/components/datatables/components/useTableSettings.tsx create mode 100644 app/portainer/components/form-components/Checkbox.tsx create mode 100644 app/portainer/components/pagination-controls/ItemsPerPageSelector.tsx create mode 100644 app/portainer/components/pagination-controls/PageButton.tsx create mode 100644 app/portainer/components/pagination-controls/PageSelector.tsx create mode 100644 app/portainer/components/pagination-controls/PaginationControls.tsx create mode 100644 app/portainer/components/pagination-controls/calculatePageNumber.ts create mode 100644 app/portainer/components/pagination-controls/generatePagesArray.ts create mode 100644 app/portainer/components/pagination-controls/index.ts create mode 100644 app/portainer/components/pagination-controls/pagination-controls.css create mode 100644 app/portainer/environments/types.ts create mode 100644 app/portainer/environments/useEnvironment.tsx delete mode 100644 app/portainer/error.js create mode 100644 app/portainer/error.ts create mode 100644 app/portainer/hooks/useDebounce.ts create mode 100644 app/react-table-config.d.ts diff --git a/.eslintrc.yml b/.eslintrc.yml index 5ccead36c..cc4e73a73 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -88,6 +88,8 @@ overrides: 'jsx-a11y/label-has-associated-control': ['error', { 'assert': 'either' }] 'react/function-component-definition': ['error', { 'namedComponents': 'function-declaration' }] 'react/jsx-no-bind': off + 'no-await-in-loop': 'off' + 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }] - files: - app/**/*.test.* extends: diff --git a/app/assets/css/app.css b/app/assets/css/app.css index b043f74ba..7a8122f14 100644 --- a/app/assets/css/app.css +++ b/app/assets/css/app.css @@ -82,6 +82,13 @@ input[type='checkbox'] { margin-top: -1px; } +.md-checkbox input[type='checkbox']:indeterminate + label:before { + content: '-'; + align-content: center; + line-height: 16px; + text-align: center; +} + a[ng-click] { cursor: pointer; } @@ -885,3 +892,7 @@ json-tree .branch-preview { word-break: break-all; white-space: normal; } + +.space-x-1 { + margin-left: 0.25rem; +} diff --git a/app/assets/css/index.js b/app/assets/css/index.js index c48ded8c2..9cd17ecec 100644 --- a/app/assets/css/index.js +++ b/app/assets/css/index.js @@ -13,6 +13,7 @@ import 'angular-loading-bar/build/loading-bar.css'; import 'angular-moment-picker/dist/angular-moment-picker.min.css'; import 'angular-multiselect/isteven-multi-select.css'; import 'spinkit/spinkit.min.css'; +import '@reach/menu-button/styles.css'; import './rdash.css'; import './app.css'; diff --git a/app/docker/__module.js b/app/docker/__module.js index a34a8e4cd..828862870 100644 --- a/app/docker/__module.js +++ b/app/docker/__module.js @@ -1,4 +1,8 @@ -angular.module('portainer.docker', ['portainer.app']).config([ +import angular from 'angular'; + +import containersModule from './containers'; + +angular.module('portainer.docker', ['portainer.app', containersModule]).config([ '$stateRegistryProvider', function ($stateRegistryProvider) { 'use strict'; diff --git a/app/docker/components/container-quick-actions/ContainerQuickActions.module.css b/app/docker/components/container-quick-actions/ContainerQuickActions.module.css new file mode 100644 index 000000000..dfc0a60d1 --- /dev/null +++ b/app/docker/components/container-quick-actions/ContainerQuickActions.module.css @@ -0,0 +1,3 @@ +.root { + display: inline-flex; +} diff --git a/app/docker/components/container-quick-actions/ContainerQuickActions.tsx b/app/docker/components/container-quick-actions/ContainerQuickActions.tsx new file mode 100644 index 000000000..41e411bef --- /dev/null +++ b/app/docker/components/container-quick-actions/ContainerQuickActions.tsx @@ -0,0 +1,140 @@ +import clsx from 'clsx'; + +import { Authorized } from '@/portainer/hooks/useUser'; +import { Link } from '@/portainer/components/Link'; +import { react2angular } from '@/react-tools/react2angular'; +import { DockerContainerStatus } from '@/docker/containers/types'; + +import styles from './ContainerQuickActions.module.css'; + +interface QuickActionsState { + showQuickActionAttach: boolean; + showQuickActionExec: boolean; + showQuickActionInspect: boolean; + showQuickActionLogs: boolean; + showQuickActionStats: boolean; +} + +interface Props { + taskId?: string; + containerId?: string; + nodeName: string; + state: QuickActionsState; + status: DockerContainerStatus; +} + +export function ContainerQuickActions({ + taskId, + containerId, + nodeName, + state, + status, +}: Props) { + if (taskId) { + return ; + } + + const isActive = ['starting', 'running', 'healthy', 'unhealthy'].includes( + status + ); + + return ( +
+ {state.showQuickActionLogs && ( + + +