From 4eb9a689bad62598ff1ede09c0c3aba01c83bf0b Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 Nov 2021 21:05:14 +0200 Subject: [PATCH] Allow to scroll table columns with labels (badges) (#4358) --- .../components/+catalog/catalog-entity-item.tsx | 1 + src/renderer/components/+catalog/catalog.tsx | 2 +- .../components/+config-autoscalers/hpa.tsx | 3 ++- .../components/+config-secrets/secrets.tsx | 4 ++-- src/renderer/components/+namespaces/namespaces.tsx | 4 ++-- .../+workloads-daemonsets/daemonsets.tsx | 12 ++++-------- src/renderer/components/badge/badge.module.css | 12 ++++++++++++ src/renderer/components/badge/badge.tsx | 4 +++- .../item-object-list/item-list-layout.scss | 6 ------ src/renderer/components/table/table-cell.scss | 14 ++++++++++++++ src/renderer/components/table/table-cell.tsx | 5 ++++- 11 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/renderer/components/+catalog/catalog-entity-item.tsx b/src/renderer/components/+catalog/catalog-entity-item.tsx index 56b12c9ad1..9518131375 100644 --- a/src/renderer/components/+catalog/catalog-entity-item.tsx +++ b/src/renderer/components/+catalog/catalog-entity-item.tsx @@ -76,6 +76,7 @@ export class CatalogEntityItem implements ItemObject { return this.labels .map(label => ( { { title: "Name", className: styles.entityName, sortBy: sortBy.name, id: "name" }, !activeCategory && { title: "Kind", sortBy: sortBy.kind, id: "kind" }, { title: "Source", className: styles.sourceCell, sortBy: sortBy.source, id: "source" }, - { title: "Labels", className: styles.labelsCell, id: "labels" }, + { title: "Labels", className: `${styles.labelsCell} scrollable`, id: "labels" }, { title: "Status", className: styles.statusCell, sortBy: sortBy.status, id: "status" }, ].filter(Boolean)} customizeTableRowProps={item => ({ diff --git a/src/renderer/components/+config-autoscalers/hpa.tsx b/src/renderer/components/+config-autoscalers/hpa.tsx index 5133aa1d4e..4424540d2e 100644 --- a/src/renderer/components/+config-autoscalers/hpa.tsx +++ b/src/renderer/components/+config-autoscalers/hpa.tsx @@ -87,7 +87,7 @@ export class HorizontalPodAutoscalers extends React.Component { { title: "Max Pods", className: "max-pods", sortBy: columnId.maxPods, id: columnId.maxPods }, { title: "Replicas", className: "replicas", sortBy: columnId.replicas, id: columnId.replicas }, { title: "Age", className: "age", sortBy: columnId.age, id: columnId.age }, - { title: "Status", className: "status", id: columnId.status }, + { title: "Status", className: "status scrollable", id: columnId.status }, ]} renderTableContents={hpa => [ hpa.getName(), @@ -108,6 +108,7 @@ export class HorizontalPodAutoscalers extends React.Component { tooltip={tooltip} className={cssNames(type.toLowerCase())} expandable={false} + scrollable={true} /> ); }), diff --git a/src/renderer/components/+config-secrets/secrets.tsx b/src/renderer/components/+config-secrets/secrets.tsx index 8b4cd1f01f..cc242c515e 100644 --- a/src/renderer/components/+config-secrets/secrets.tsx +++ b/src/renderer/components/+config-secrets/secrets.tsx @@ -69,7 +69,7 @@ export class Secrets extends React.Component { { title: "Name", className: "name", sortBy: columnId.name, id: columnId.name }, { className: "warning", showWithColumn: columnId.name }, { title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace }, - { title: "Labels", className: "labels", sortBy: columnId.labels, id: columnId.labels }, + { title: "Labels", className: "labels scrollable", sortBy: columnId.labels, id: columnId.labels }, { title: "Keys", className: "keys", sortBy: columnId.keys, id: columnId.keys }, { title: "Type", className: "type", sortBy: columnId.type, id: columnId.type }, { title: "Age", className: "age", sortBy: columnId.age, id: columnId.age }, @@ -78,7 +78,7 @@ export class Secrets extends React.Component { secret.getName(), , secret.getNs(), - secret.getLabels().map(label => ), + secret.getLabels().map(label => ), secret.getKeys().join(", "), secret.type, secret.getAge(), diff --git a/src/renderer/components/+namespaces/namespaces.tsx b/src/renderer/components/+namespaces/namespaces.tsx index 53e38b95b6..7c47ddef80 100644 --- a/src/renderer/components/+namespaces/namespaces.tsx +++ b/src/renderer/components/+namespaces/namespaces.tsx @@ -64,14 +64,14 @@ export class Namespaces extends React.Component { renderTableHeader={[ { title: "Name", className: "name", sortBy: columnId.name, id: columnId.name }, { className: "warning", showWithColumn: columnId.name }, - { title: "Labels", className: "labels", sortBy: columnId.labels, id: columnId.labels }, + { title: "Labels", className: "labels scrollable", sortBy: columnId.labels, id: columnId.labels }, { title: "Age", className: "age", sortBy: columnId.age, id: columnId.age }, { title: "Status", className: "status", sortBy: columnId.status, id: columnId.status }, ]} renderTableContents={item => [ item.getName(), , - item.getLabels().map(label => ), + item.getLabels().map(label => ), item.getAge(), { title: item.getStatus(), className: item.getStatus().toLowerCase() }, ]} diff --git a/src/renderer/components/+workloads-daemonsets/daemonsets.tsx b/src/renderer/components/+workloads-daemonsets/daemonsets.tsx index 31f3203113..c0ec6e21df 100644 --- a/src/renderer/components/+workloads-daemonsets/daemonsets.tsx +++ b/src/renderer/components/+workloads-daemonsets/daemonsets.tsx @@ -50,12 +50,6 @@ export class DaemonSets extends React.Component { return daemonSetStore.getChildPods(daemonSet).length; } - renderNodeSelector(daemonSet: DaemonSet) { - return daemonSet.getNodeSelectors().map(selector => ( - - )); - } - render() { return ( { { title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace }, { title: "Pods", className: "pods", sortBy: columnId.pods, id: columnId.pods }, { className: "warning", showWithColumn: columnId.pods }, - { title: "Node Selector", className: "labels", id: columnId.labels }, + { title: "Node Selector", className: "labels scrollable", id: columnId.labels }, { title: "Age", className: "age", sortBy: columnId.age, id: columnId.age }, ]} renderTableContents={daemonSet => [ @@ -87,7 +81,9 @@ export class DaemonSets extends React.Component { daemonSet.getNs(), this.getPodsLength(daemonSet), , - this.renderNodeSelector(daemonSet), + daemonSet.getNodeSelectors().map(selector => ( + + )), daemonSet.getAge(), ]} /> diff --git a/src/renderer/components/badge/badge.module.css b/src/renderer/components/badge/badge.module.css index 8fe7a0a022..5dfa6d1219 100644 --- a/src/renderer/components/badge/badge.module.css +++ b/src/renderer/components/badge/badge.module.css @@ -25,6 +25,18 @@ max-width: 100%; } +// might be used in a scrollable area with {overflow: auto} +.badge.scrollable { + max-width: unset; + + &:not(.isExpanded) { + white-space: unset; + overflow: unset; + text-overflow: unset; + } +} + + .badge.interactive:hover { background-color: var(--mainBackground); cursor: pointer; diff --git a/src/renderer/components/badge/badge.tsx b/src/renderer/components/badge/badge.tsx index ec1b523704..fe722c3032 100644 --- a/src/renderer/components/badge/badge.tsx +++ b/src/renderer/components/badge/badge.tsx @@ -34,6 +34,7 @@ export interface BadgeProps extends React.HTMLAttributes, TooltipDecoratorP label?: React.ReactNode; expandable?: boolean; disabled?: boolean; + scrollable?: boolean; } // Common handler for all Badge instances @@ -81,7 +82,7 @@ export class Badge extends React.Component { } render() { - const { className, label, disabled, small, children, flat, expandable, ...elemProps } = this.props; + const { className, label, disabled, scrollable, small, children, flat, expandable, ...elemProps } = this.props; const clickable = Boolean(this.props.onClick) || this.isExpandable; const classNames = cssNames(styles.badge, className, { [styles.small]: small, @@ -90,6 +91,7 @@ export class Badge extends React.Component { [styles.interactive]: this.isExpandable, [styles.isExpanded]: this.isExpanded, [styles.disabled]: disabled, + [styles.scrollable]: scrollable, }); return ( diff --git a/src/renderer/components/item-object-list/item-list-layout.scss b/src/renderer/components/item-object-list/item-list-layout.scss index 9318f9e482..05afcccbd2 100644 --- a/src/renderer/components/item-object-list/item-list-layout.scss +++ b/src/renderer/components/item-object-list/item-list-layout.scss @@ -49,12 +49,6 @@ position: relative; min-height: 200px; } - - .TableCell { - &.menu { - @include table-cell-action; - } - } } .ItemListLayoutVisibilityMenu { diff --git a/src/renderer/components/table/table-cell.scss b/src/renderer/components/table/table-cell.scss index f0cce05e91..5bfd419b91 100644 --- a/src/renderer/components/table/table-cell.scss +++ b/src/renderer/components/table/table-cell.scss @@ -25,6 +25,20 @@ overflow: hidden; text-overflow: ellipsis; + &.menu { + @include table-cell-action; + } + + &.scrollable { + @include hidden-scrollbar; + display: flex; + align-items: center; + + :not(:last-of-type) { + margin-right: 0.5em; + } + } + &.checkbox { display: flex; flex: 0 0 32px !important; diff --git a/src/renderer/components/table/table-cell.tsx b/src/renderer/components/table/table-cell.tsx index 7919b94cbf..57b18ac3d1 100644 --- a/src/renderer/components/table/table-cell.tsx +++ b/src/renderer/components/table/table-cell.tsx @@ -33,6 +33,7 @@ export interface TableCellProps extends React.DOMAttributes { id?: string; // used for configuration visibility of columns className?: string; title?: ReactNode; + scrollable?: boolean; // content inside could be scrolled checkbox?: boolean; // render cell with a checkbox isChecked?: boolean; // mark checkbox as checked or not renderBoolean?: boolean; // show "true" or "false" for all of the children elements are "typeof boolean" @@ -88,9 +89,11 @@ export class TableCell extends React.Component { } render() { - const { className, checkbox, isChecked, sortBy, _sort, _sorting, _nowrap, children, title, renderBoolean: displayBoolean, showWithColumn, ...cellProps } = this.props; + const { className, checkbox, isChecked, scrollable, sortBy, _sort, _sorting, _nowrap, children, title, renderBoolean: displayBoolean, showWithColumn, ...cellProps } = this.props; + const classNames = cssNames("TableCell", className, { checkbox, + scrollable, nowrap: _nowrap, sorting: this.isSortable, });