From 4f0f53b9aac94fd4fd083003bca8e91f9330d4de Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Wed, 19 Jul 2023 18:26:18 +0300 Subject: [PATCH] feat(edge/stacks): ui for status [EE-5593] (#9214) --- .../DeploymentCounter.module.css | 28 ---- .../EdgeStacksDatatable/DeploymentCounter.tsx | 58 +++++-- .../EdgeStacksDatatable.tsx | 7 +- .../ListView/EdgeStacksDatatable/columns.tsx | 151 ++++++++++-------- .../ListView/EdgeStacksDatatable/types.ts | 11 +- 5 files changed, 132 insertions(+), 123 deletions(-) delete mode 100644 app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.module.css diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.module.css b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.module.css deleted file mode 100644 index 7676eee2b..000000000 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.root { - padding: 2px 10px; - border-radius: 10px; -} - -.status-acknowledged { - color: #337ab7; - background-color: rgba(51, 122, 183, 0.1); -} - -.status-images-pulled { - color: #e1a800; - background-color: rgba(238, 192, 32, 0.1); -} - -.status-ok { - color: #23ae89; - background-color: rgba(35, 174, 137, 0.1); -} - -.status-error { - color: #ae2323; - background-color: rgba(174, 35, 35, 0.1); -} - -.status-total { - background-color: rgba(168, 167, 167, 0.1); -} diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx index ec25cb777..c6ea944a4 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx @@ -1,28 +1,30 @@ import clsx from 'clsx'; +import { ReactNode } from 'react'; import { Link } from '@@/Link'; +import { TooltipWithChildren } from '@@/Tip/TooltipWithChildren'; import { EdgeStack, StatusType } from '../../types'; -import styles from './DeploymentCounter.module.css'; - export function DeploymentCounterLink({ count, + total, type, stackId, }: { count: number; + total: number; type: StatusType; stackId: EdgeStack['Id']; }) { return ( -
+
- +
); @@ -30,22 +32,48 @@ export function DeploymentCounterLink({ export function DeploymentCounter({ count, + total, type, }: { count: number; + total: number; type?: StatusType; }) { return ( - - • {count} - + +
+
+
+ ); } + +function getTooltip(count: number, total: number, type?: StatusType) { + const label = getLabel(type); + return `${count} of ${total} ${label}`; + + function getLabel(type?: StatusType): ReactNode { + switch (type) { + case StatusType.Running: + return 'deployments running'; + case StatusType.DeploymentReceived: + return 'deployments received'; + case StatusType.Error: + return 'deployments failed'; + case StatusType.Acknowledged: + return 'deployments acknowledged'; + case StatusType.ImagesPulled: + return 'images pre-pulled'; + default: + return ''; + } + } +} diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/EdgeStacksDatatable.tsx b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/EdgeStacksDatatable.tsx index 2e908a45f..e1f334ba7 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/EdgeStacksDatatable.tsx +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/EdgeStacksDatatable.tsx @@ -50,15 +50,12 @@ export function EdgeStacksDatatable() { } function aggregateStackStatus(stackStatus: EdgeStack['Status']) { - const aggregateStatus = { ok: 0, error: 0, acknowledged: 0, imagesPulled: 0 }; + const aggregateStatus: Partial> = {}; return Object.values(stackStatus).reduce( (acc, envStatus) => envStatus.Status.reduce((acc, status) => { const { Type } = status; - acc.ok += Number(Type === StatusType.Running); - acc.error += Number(Type === StatusType.Error); - acc.acknowledged += Number(Type === StatusType.Acknowledged); - acc.imagesPulled += Number(Type === StatusType.ImagesPulled); + acc[Type] = (acc[Type] || 0) + 1; return acc; }, acc), aggregateStatus diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx index b66e5aae0..b140de240 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx @@ -5,12 +5,13 @@ import { isoDateFromTimestamp } from '@/portainer/filters/filters'; import { isBE } from '@/react/portainer/feature-flags/feature-flags.service'; import { buildNameColumn } from '@@/datatables/NameCell'; +import { Link } from '@@/Link'; import { StatusType } from '../../types'; import { EdgeStackStatus } from './EdgeStacksStatus'; import { DecoratedEdgeStack } from './types'; -import { DeploymentCounter, DeploymentCounterLink } from './DeploymentCounter'; +import { DeploymentCounter } from './DeploymentCounter'; const columnHelper = createColumnHelper(); @@ -21,29 +22,52 @@ export const columns = _.compact([ 'edge.stacks.edit', 'stackId' ), - columnHelper.accessor('aggregatedStatus.acknowledged', { - header: 'Acknowledged', - enableSorting: false, - enableHiding: false, - cell: ({ getValue, row }) => ( - - ), - meta: { - className: '[&>*]:justify-center', - }, - }), - isBE && - columnHelper.accessor('aggregatedStatus.imagesPulled', { - header: 'Images Pre-pulled', + columnHelper.accessor( + (item) => item.aggregatedStatus[StatusType.Acknowledged] || 0, + { + header: 'Acknowledged', + enableSorting: false, + enableHiding: false, cell: ({ getValue, row }) => ( - + ), + meta: { + className: '[&>*]:justify-center', + }, + } + ), + isBE && + columnHelper.accessor( + (item) => item.aggregatedStatus[StatusType.ImagesPulled] || 0, + { + header: 'Images pre-pulled', + cell: ({ getValue, row }) => ( + + ), + enableSorting: false, + enableHiding: false, + meta: { + className: '[&>*]:justify-center', + }, + } + ), + columnHelper.accessor( + (item) => item.aggregatedStatus[StatusType.DeploymentReceived] || 0, + { + header: 'Deployments received', + cell: ({ getValue, row }) => ( + ), enableSorting: false, @@ -51,37 +75,45 @@ export const columns = _.compact([ meta: { className: '[&>*]:justify-center', }, - }), - columnHelper.accessor('aggregatedStatus.ok', { - header: 'Deployed', - cell: ({ getValue, row }) => ( - - ), - enableSorting: false, - enableHiding: false, - meta: { - className: '[&>*]:justify-center', - }, - }), - columnHelper.accessor('aggregatedStatus.error', { - header: 'Failed', - cell: ({ getValue, row }) => ( - - ), - enableSorting: false, - enableHiding: false, - meta: { - className: '[&>*]:justify-center', - }, - }), + } + ), + columnHelper.accessor( + (item) => item.aggregatedStatus[StatusType.Error] || 0, + { + header: 'Deployments failed', + cell: ({ getValue, row }) => { + const count = getValue(); + + return ( +
+ + {count > 0 && ( + + ({count}/{row.original.NumDeployments}) + + )} +
+ ); + }, + enableSorting: false, + enableHiding: false, + meta: { + className: '[&>*]:justify-center', + }, + } + ), columnHelper.accessor('Status', { header: 'Status', cell: ({ row }) => ( @@ -95,19 +127,6 @@ export const columns = _.compact([ className: '[&>*]:justify-center', }, }), - columnHelper.accessor('NumDeployments', { - header: 'Deployments', - cell: ({ getValue }) => ( -
- -
- ), - enableSorting: false, - enableHiding: false, - meta: { - className: '[&>*]:justify-center', - }, - }), columnHelper.accessor('CreationDate', { header: 'Creation Date', cell: ({ getValue }) => isoDateFromTimestamp(getValue()), diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/types.ts b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/types.ts index 6b1463061..89b360342 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/types.ts +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/types.ts @@ -1,12 +1,5 @@ -import { EdgeStack } from '../../types'; - -interface AggregateStackStatus { - ok: number; - error: number; - acknowledged: number; - imagesPulled: number; -} +import { EdgeStack, StatusType } from '../../types'; export type DecoratedEdgeStack = EdgeStack & { - aggregatedStatus: AggregateStackStatus; + aggregatedStatus: Partial>; };