From 1c1d2f7c562ad4db3726a9523f14054a450957e8 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 20 Apr 2021 09:24:25 -0400 Subject: [PATCH] Conditionally render status icon for kube meta (#2298) --- .../registries/kube-object-status-registry.ts | 14 +- .../kube-object-status-icon.tsx | 143 +++++++++--------- .../kube-object/kube-object-meta.tsx | 13 +- 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/src/extensions/registries/kube-object-status-registry.ts b/src/extensions/registries/kube-object-status-registry.ts index 5f7aab8d5d..3ca20f569a 100644 --- a/src/extensions/registries/kube-object-status-registry.ts +++ b/src/extensions/registries/kube-object-status-registry.ts @@ -9,9 +9,17 @@ export interface KubeObjectStatusRegistration { export class KubeObjectStatusRegistry extends BaseRegistry { getItemsForKind(kind: string, apiVersion: string) { - return this.getItems().filter((item) => { - return item.kind === kind && item.apiVersions.includes(apiVersion); - }); + return this.getItems() + .filter((item) => ( + item.kind === kind + && item.apiVersions.includes(apiVersion) + )); + } + + getItemsForObject(src: KubeObject) { + return this.getItemsForKind(src.kind, src.apiVersion) + .map(item => item.resolve(src)) + .filter(Boolean); } } diff --git a/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx b/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx index 386255d1eb..a9813d02db 100644 --- a/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx +++ b/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx @@ -2,105 +2,106 @@ import "./kube-object-status-icon.scss"; import React from "react"; import { Icon } from "../icon"; -import { KubeObject } from "../../api/kube-object"; import { cssNames, formatDuration } from "../../utils"; -import { KubeObjectStatusRegistration, kubeObjectStatusRegistry } from "../../../extensions/registries/kube-object-status-registry"; -import { KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api"; -import { computed } from "mobx"; +import { KubeObject, KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api"; +import { kubeObjectStatusRegistry } from "../../../extensions/registries"; + +function statusClassName(level: number): string { + switch (level) { + case KubeObjectStatusLevel.INFO: + return "info"; + case KubeObjectStatusLevel.WARNING: + return "warning"; + case KubeObjectStatusLevel.CRITICAL: + return "error"; + } +} + +function statusTitle(level: KubeObjectStatusLevel): string { + switch (level) { + case KubeObjectStatusLevel.INFO: + return "Info"; + case KubeObjectStatusLevel.WARNING: + return "Warning"; + case KubeObjectStatusLevel.CRITICAL: + return "Critical"; + } +} + +function getAge(timestamp: string) { + return timestamp + ? formatDuration(Date.now() - new Date(timestamp).getTime(), true) + : ""; +} + +interface SplitStatusesByLevel { + maxLevel: string, + criticals: KubeObjectStatus[]; + warnings: KubeObjectStatus[]; + infos: KubeObjectStatus[]; +} + +/** + * This fuction returns the class level for corresponding to the highest status level + * and the statuses split by their levels. + * @param src a list of status items + */ +function splitByLevel(src: KubeObjectStatus[]): SplitStatusesByLevel { + const parts = new Map(Object.values(KubeObjectStatusLevel).map(v => [v, []])); + + src.forEach(status => parts.get(status.level).push(status)); + + const criticals = parts.get(KubeObjectStatusLevel.CRITICAL); + const warnings = parts.get(KubeObjectStatusLevel.WARNING); + const infos = parts.get(KubeObjectStatusLevel.INFO); + const maxLevel = statusClassName(criticals[0]?.level ?? warnings[0]?.level ?? infos[0].level); + + return { maxLevel, criticals, warnings, infos }; +} interface Props { object: KubeObject; } export class KubeObjectStatusIcon extends React.Component { - @computed get objectStatuses() { - const { object } = this.props; - const registrations = kubeObjectStatusRegistry.getItemsForKind(object.kind, object.apiVersion); - - return registrations.map((item: KubeObjectStatusRegistration) => { return item.resolve(object); }).filter((item: KubeObjectStatus) => !!item); - } - - statusClassName(level: number): string { - switch (level) { - case KubeObjectStatusLevel.INFO: - return "info"; - case KubeObjectStatusLevel.WARNING: - return "warning"; - case KubeObjectStatusLevel.CRITICAL: - return "error"; - default: - return ""; - } - } - - statusTitle(level: number): string { - switch (level) { - case KubeObjectStatusLevel.INFO: - return "Info"; - case KubeObjectStatusLevel.WARNING: - return "Warning"; - case KubeObjectStatusLevel.CRITICAL: - return "Critical"; - default: - return ""; - } - } - - getAge(timestamp: string) { - if (!timestamp) return ""; - const diff = Date.now() - new Date(timestamp).getTime(); - - return formatDuration(diff, true); - } - renderStatuses(statuses: KubeObjectStatus[], level: number) { const filteredStatuses = statuses.filter((item) => item.level == level); return filteredStatuses.length > 0 && ( -
+
- {this.statusTitle(level)} + {statusTitle(level)} - { filteredStatuses.map((status, index) =>{ - return ( + { + filteredStatuses.map((status, index) => (
- - {status.text} · { this.getAge(status.timestamp) } + - {status.text} · {getAge(status.timestamp)}
- ); - })} + )) + }
); } render() { - const { objectStatuses} = this; + const statuses = kubeObjectStatusRegistry.getItemsForObject(this.props.object); - if (!objectStatuses.length) return null; + if (statuses.length === 0) { + return null; + } - const sortedStatuses = objectStatuses.sort((a: KubeObjectStatus, b: KubeObjectStatus) => { - if (a.level < b.level ) { - return 1; - } - - if (a.level > b.level ) { - return -1; - } - - return 0; - }); - - const level = this.statusClassName(sortedStatuses[0].level); + const { maxLevel, criticals, warnings, infos } = splitByLevel(statuses); return ( - {this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.CRITICAL)} - {this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.WARNING)} - {this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.INFO)} + {this.renderStatuses(criticals, KubeObjectStatusLevel.CRITICAL)} + {this.renderStatuses(warnings, KubeObjectStatusLevel.WARNING)} + {this.renderStatuses(infos, KubeObjectStatusLevel.INFO)}
) }} diff --git a/src/renderer/components/kube-object/kube-object-meta.tsx b/src/renderer/components/kube-object/kube-object-meta.tsx index 3403a6a48e..6d402f14a6 100644 --- a/src/renderer/components/kube-object/kube-object-meta.tsx +++ b/src/renderer/components/kube-object/kube-object-meta.tsx @@ -23,13 +23,11 @@ export class KubeObjectMeta extends React.Component { } render() { - const object = this.props.object; + const { object } = this.props; const { - getName, getNs, getLabels, getResourceVersion, selfLink, - getAnnotations, getFinalizers, getId, getAge, - metadata: { creationTimestamp }, + getNs, getLabels, getResourceVersion, selfLink, getAnnotations, + getFinalizers, getId, getAge, getName, metadata: { creationTimestamp }, } = object; - const ownerRefs = object.getOwnerRefs(); return ( @@ -38,7 +36,8 @@ export class KubeObjectMeta extends React.Component { {getAge(true, false)} ago ({creationTimestamp})