/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import styles from "./cluster-issues.module.scss"; import React from "react"; import { observer } from "mobx-react"; import type { IComputedValue } from "mobx"; import { computed, makeObservable } from "mobx"; import { Icon } from "../icon"; import { SubHeader } from "../layout/sub-header"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { cssNames, prevDefault } from "../../utils"; import type { ItemObject } from "../../../common/item.store"; import { Spinner } from "../spinner"; import type { ApiManager } from "../../../common/k8s-api/api-manager"; import { KubeObjectAge } from "../kube-object/age"; import { withInjectables } from "@ogre-tools/injectable-react"; import type { NodeStore } from "../+nodes/store"; import type { EventStore } from "../+events/store"; import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable"; import eventStoreInjectable from "../+events/store.injectable"; import nodeStoreInjectable from "../+nodes/store.injectable"; import type { PageParam } from "../../navigation/page-param"; import type { ToggleKubeDetailsPane } from "../kube-detail-params/toggle-details.injectable"; import kubeSelectedUrlParamInjectable from "../kube-detail-params/kube-selected-url.injectable"; import toggleKubeDetailsPaneInjectable from "../kube-detail-params/toggle-details.injectable"; import type { LensTheme } from "../../themes/lens-theme"; import activeThemeInjectable from "../../themes/active.injectable"; export interface ClusterIssuesProps { className?: string; } interface Warning extends ItemObject { kind: string; message: string | undefined; selfLink: string; renderAge: () => React.ReactElement; ageMs: number; } enum sortBy { type = "type", object = "object", age = "age", } interface Dependencies { activeTheme: IComputedValue; nodeStore: NodeStore; eventStore: EventStore; apiManager: ApiManager; kubeSelectedUrlParam: PageParam; toggleKubeDetailsPane: ToggleKubeDetailsPane; } @observer class NonInjectedClusterIssues extends React.Component { constructor(props: ClusterIssuesProps & Dependencies) { super(props); makeObservable(this); } @computed get warnings(): Warning[] { return [ ...this.props.nodeStore.items.flatMap(node => ( node.getWarningConditions() .map(({ message }) => ({ selfLink: node.selfLink, getId: node.getId, getName: node.getName, kind: node.kind, message, renderAge: () => , ageMs: -node.getCreationTimestamp(), })) )), ...this.props.eventStore.getWarnings().map(warning => ({ getId: () => warning.involvedObject.uid, getName: () => warning.involvedObject.name, renderAge: () => , ageMs: -warning.getCreationTimestamp(), message: warning.message, kind: warning.kind, selfLink: this.props.apiManager.lookupApiLink(warning.involvedObject, warning), })), ]; } getTableRow = (uid: string) => { const { warnings } = this; const { kubeSelectedUrlParam, toggleKubeDetailsPane: toggleDetails } = this.props; const warning = warnings.find(warn => warn.getId() == uid); if (!warning) { return undefined; } const { getId, getName, message, kind, selfLink, renderAge } = warning; return ( toggleDetails(selfLink))} > {message ?? ""} {getName()} {kind} {renderAge()} ); }; renderContent() { const { warnings } = this; if (!this.props.eventStore.isLoaded) { return ( ); } if (!warnings.length) { return (

No issues found

Everything is fine in the Cluster

); } return ( <> {` Warnings: ${warnings.length}`} warning.kind, [sortBy.object]: warning => warning.getName(), [sortBy.age]: warning => warning.ageMs, }} sortByDefault={{ sortBy: sortBy.object, orderBy: "asc" }} sortSyncWithUrl={false} getTableRow={this.getTableRow} className={cssNames("box grow", this.props.activeTheme.get().type)} > Message Object Type Age
); } render() { return (
{this.renderContent()}
); } } export const ClusterIssues = withInjectables(NonInjectedClusterIssues, { getProps: (di, props) => ({ ...props, activeTheme: di.inject(activeThemeInjectable), apiManager: di.inject(apiManagerInjectable), eventStore: di.inject(eventStoreInjectable), nodeStore: di.inject(nodeStoreInjectable), kubeSelectedUrlParam: di.inject(kubeSelectedUrlParamInjectable), toggleKubeDetailsPane: di.inject(toggleKubeDetailsPaneInjectable), }), });