diff --git a/src/common/k8s-api/endpoints/nodes.api.ts b/src/common/k8s-api/endpoints/nodes.api.ts index 01571a7d16..8e3e72af3f 100644 --- a/src/common/k8s-api/endpoints/nodes.api.ts +++ b/src/common/k8s-api/endpoints/nodes.api.ts @@ -20,7 +20,7 @@ */ import { KubeObject } from "../kube-object"; -import { autoBind, cpuUnitsToNumber, unitsToBytes } from "../../../renderer/utils"; +import { autoBind, cpuUnitsToNumber, iter, unitsToBytes } from "../../../renderer/utils"; import { IMetrics, metricsApi } from "./metrics.api"; import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; @@ -151,16 +151,19 @@ export class Node extends KubeObject { autoBind(this); } - getNodeConditionText() { - const { conditions } = this.status; + getNodeConditionText(): string { + const { conditions = [] } = this.status; - if (!conditions) return ""; - - return conditions.reduce((types, current) => { - if (current.status !== "True") return ""; - - return types += ` ${current.type}`; - }, ""); + return iter.join( + iter.map( + iter.filter( + conditions.values(), + ({ status }) => status === "True", + ), + ({ type }) => type, + ), + " ", + ); } getTaints() { diff --git a/src/common/utils/iter.ts b/src/common/utils/iter.ts index 65b0937726..dd97c8feef 100644 --- a/src/common/utils/iter.ts +++ b/src/common/utils/iter.ts @@ -25,7 +25,7 @@ export type Falsey = false | 0 | "" | null | undefined; * Create a new type safe empty Iterable * @returns An `Iterable` that yields 0 items */ -export function* newEmpty(): Iterable { +export function* newEmpty(): IterableIterator { return; } @@ -35,7 +35,7 @@ export function* newEmpty(): Iterable { * @param src An initial iterator * @param n The maximum number of elements to take from src. Yields up to the floor of `n` and 0 items if n < 0 */ -export function* take(src: Iterable, n: number): Iterable { +export function* take(src: Iterable, n: number): IterableIterator { outer: for (let i = 0; i < n; i += 1) { for (const item of src) { yield item; @@ -53,7 +53,7 @@ export function* take(src: Iterable, n: number): Iterable { * @param src A type that can be iterated over * @param fn The function that is called for each value */ -export function* map(src: Iterable, fn: (from: T) => U): Iterable { +export function* map(src: Iterable, fn: (from: T) => U): IterableIterator { for (const from of src) { yield fn(from); } @@ -64,7 +64,7 @@ export function* map(src: Iterable, fn: (from: T) => U): Iterable { * @param src A type that can be iterated over * @param fn The function that returns either an iterable over items that should be filtered out or a `Falsey` value indicating that it should be ignored */ -export function* filterFlatMap(src: Iterable, fn: (from: T) => Iterable | Falsey): Iterable { +export function* filterFlatMap(src: Iterable, fn: (from: T) => Iterable | Falsey): IterableIterator { for (const from of src) { if (!from) { continue; @@ -89,7 +89,7 @@ export function* filterFlatMap(src: Iterable, fn: (from: T) => Iterable * @param src A type that can be iterated over * @param fn A function that returns an iterator */ -export function* flatMap(src: Iterable, fn: (from: T) => Iterable): Iterable { +export function* flatMap(src: Iterable, fn: (from: T) => Iterable): IterableIterator { for (const from of src) { yield* fn(from); } @@ -101,7 +101,7 @@ export function* flatMap(src: Iterable, fn: (from: T) => Iterable): * @param src A type that can be iterated over * @param fn The function that is called for each value */ -export function* filter(src: Iterable, fn: (from: T) => any): Iterable { +export function* filter(src: Iterable, fn: (from: T) => any): IterableIterator { for (const from of src) { if (fn(from)) { yield from; @@ -115,7 +115,7 @@ export function* filter(src: Iterable, fn: (from: T) => any): Iterable * @param src A type that can be iterated over * @param fn The function that is called for each value */ -export function* filterMap(src: Iterable, fn: (from: T) => U | Falsey): Iterable { +export function* filterMap(src: Iterable, fn: (from: T) => U | Falsey): IterableIterator { for (const from of src) { const res = fn(from); @@ -131,7 +131,7 @@ export function* filterMap(src: Iterable, fn: (from: T) => U | Falsey): * @param src A type that can be iterated over * @param fn The function that is called for each value */ -export function* filterMapStrict(src: Iterable, fn: (from: T) => U | null | undefined): Iterable { +export function* filterMapStrict(src: Iterable, fn: (from: T) => U | null | undefined): IterableIterator { for (const from of src) { const res = fn(from); @@ -164,7 +164,7 @@ export function find(src: Iterable, match: (i: T) => any): T | undefined { * @param reducer A function for producing the next item from an accumilation and the current item * @param initial The initial value for the iteration */ -export function reduce(src: Iterable, reducer: (acc: Iterable, cur: T) => Iterable, initial: Iterable): Iterable; +export function reduce>(src: Iterable, reducer: (acc: R, cur: T) => R, initial: R): R; export function reduce(src: Iterable, reducer: (acc: R, cur: T) => R, initial: R): R { let acc = initial; @@ -175,3 +175,13 @@ export function reduce(src: Iterable, reducer: (acc: R, cur: T) => return acc; } + +/** + * A convenience function for reducing over an iterator of strings and concatenating them together + * @param src The value to iterate over + * @param connector The string value to intersperse between the yielded values + * @returns The concatenated entries of `src` interspersed with copies of `connector` + */ +export function join(src: Iterable, connector = ","): string { + return reduce(src, (acc, cur) => `${acc}${connector}${cur}`, ""); +} diff --git a/src/renderer/api/catalog-entity-registry.ts b/src/renderer/api/catalog-entity-registry.ts index 1b7e79e67c..acf65219a5 100644 --- a/src/renderer/api/catalog-entity-registry.ts +++ b/src/renderer/api/catalog-entity-registry.ts @@ -130,7 +130,7 @@ export class CatalogEntityRegistry { iter.reduce( this.filters, iter.filter, - this.items, + this.items.values(), ) ); }