mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Replace KubeObjectStatusRegistry with reactive solution (#4815)
This commit is contained in:
parent
d72ebac5f3
commit
54b87efd89
@ -6,7 +6,7 @@ export type { StatusBarRegistration } from "../../renderer/components/status-bar
|
|||||||
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
|
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
|
||||||
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../../renderer/components/+preferences/app-preferences/app-preference-registration";
|
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../../renderer/components/+preferences/app-preferences/app-preference-registration";
|
||||||
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
|
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
|
||||||
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry";
|
export type { KubeObjectStatusRegistration } from "../../renderer/components/kube-object-status-icon/kube-object-status-registration";
|
||||||
export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry";
|
export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry";
|
||||||
export type { ClusterPageMenuRegistration, ClusterPageMenuComponents } from "../registries/page-menu-registry";
|
export type { ClusterPageMenuRegistration, ClusterPageMenuComponents } from "../registries/page-menu-registry";
|
||||||
export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler";
|
export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler";
|
||||||
|
|||||||
@ -277,7 +277,6 @@ export class ExtensionLoader {
|
|||||||
registries.ClusterPageRegistry.getInstance().add(extension.clusterPages, extension),
|
registries.ClusterPageRegistry.getInstance().add(extension.clusterPages, extension),
|
||||||
registries.ClusterPageMenuRegistry.getInstance().add(extension.clusterPageMenus, extension),
|
registries.ClusterPageMenuRegistry.getInstance().add(extension.clusterPageMenus, extension),
|
||||||
registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems),
|
registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems),
|
||||||
registries.KubeObjectStatusRegistry.getInstance().add(extension.kubeObjectStatusTexts),
|
|
||||||
registries.WorkloadsOverviewDetailRegistry.getInstance().add(extension.kubeWorkloadsOverviewItems),
|
registries.WorkloadsOverviewDetailRegistry.getInstance().add(extension.kubeWorkloadsOverviewItems),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -20,12 +20,13 @@ import type { AdditionalCategoryColumnRegistration } from "../renderer/component
|
|||||||
import type { CustomCategoryViewRegistration } from "../renderer/components/+catalog/custom-views";
|
import type { CustomCategoryViewRegistration } from "../renderer/components/+catalog/custom-views";
|
||||||
import type { StatusBarRegistration } from "../renderer/components/status-bar/status-bar-registration";
|
import type { StatusBarRegistration } from "../renderer/components/status-bar/status-bar-registration";
|
||||||
import type { KubeObjectMenuRegistration } from "../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
|
import type { KubeObjectMenuRegistration } from "../renderer/components/kube-object-menu/dependencies/kube-object-menu-items/kube-object-menu-registration";
|
||||||
|
import type { KubeObjectStatusRegistration } from "../renderer/components/kube-object-status-icon/kube-object-status-registration";
|
||||||
|
|
||||||
export class LensRendererExtension extends LensExtension {
|
export class LensRendererExtension extends LensExtension {
|
||||||
globalPages: registries.PageRegistration[] = [];
|
globalPages: registries.PageRegistration[] = [];
|
||||||
clusterPages: registries.PageRegistration[] = [];
|
clusterPages: registries.PageRegistration[] = [];
|
||||||
clusterPageMenus: registries.ClusterPageMenuRegistration[] = [];
|
clusterPageMenus: registries.ClusterPageMenuRegistration[] = [];
|
||||||
kubeObjectStatusTexts: registries.KubeObjectStatusRegistration[] = [];
|
kubeObjectStatusTexts: KubeObjectStatusRegistration[] = [];
|
||||||
appPreferences: AppPreferenceRegistration[] = [];
|
appPreferences: AppPreferenceRegistration[] = [];
|
||||||
entitySettings: registries.EntitySettingRegistration[] = [];
|
entitySettings: registries.EntitySettingRegistration[] = [];
|
||||||
statusBarItems: StatusBarRegistration[] = [];
|
statusBarItems: StatusBarRegistration[] = [];
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
export * from "./page-registry";
|
export * from "./page-registry";
|
||||||
export * from "./page-menu-registry";
|
export * from "./page-menu-registry";
|
||||||
export * from "./kube-object-detail-registry";
|
export * from "./kube-object-detail-registry";
|
||||||
export * from "./kube-object-status-registry";
|
|
||||||
export * from "./entity-setting-registry";
|
export * from "./entity-setting-registry";
|
||||||
export * from "./catalog-entity-detail-registry";
|
export * from "./catalog-entity-detail-registry";
|
||||||
export * from "./workloads-overview-detail-registry";
|
export * from "./workloads-overview-detail-registry";
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { KubeObject, KubeObjectStatus } from "../renderer-api/k8s-api";
|
|
||||||
import { BaseRegistry } from "./base-registry";
|
|
||||||
|
|
||||||
export interface KubeObjectStatusRegistration {
|
|
||||||
kind: string;
|
|
||||||
apiVersions: string[];
|
|
||||||
resolve: (object: KubeObject) => KubeObjectStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class KubeObjectStatusRegistry extends BaseRegistry<KubeObjectStatusRegistration> {
|
|
||||||
getItemsForKind(kind: string, apiVersion: string) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,332 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given info and warning statuses are present, when rendered, renders with statuses 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="Icon KubeObjectStatusIcon warning material focusable"
|
||||||
|
id="tooltip_target_5"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="warning"
|
||||||
|
>
|
||||||
|
warning
|
||||||
|
</span>
|
||||||
|
<div />
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Tooltip narrow formatter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="KubeObjectStatusTooltip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="level warning"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Warning
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some warning status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="level info"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Info
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some info status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given level "critical" status, when rendered, renders with status 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="Icon KubeObjectStatusIcon error material focusable"
|
||||||
|
id="tooltip_target_1"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="error"
|
||||||
|
>
|
||||||
|
error
|
||||||
|
</span>
|
||||||
|
<div />
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Tooltip narrow formatter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="KubeObjectStatusTooltip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="level error"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Critical
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some critical status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given level "info" status, when rendered, renders with status 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="Icon KubeObjectStatusIcon info material focusable"
|
||||||
|
id="tooltip_target_2"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="info"
|
||||||
|
>
|
||||||
|
info
|
||||||
|
</span>
|
||||||
|
<div />
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Tooltip narrow formatter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="KubeObjectStatusTooltip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="level info"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Info
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some info status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given level "warning" status, when rendered, renders with status 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="Icon KubeObjectStatusIcon warning material focusable"
|
||||||
|
id="tooltip_target_3"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="warning"
|
||||||
|
>
|
||||||
|
warning
|
||||||
|
</span>
|
||||||
|
<div />
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Tooltip narrow formatter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="KubeObjectStatusTooltip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="level warning"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Warning
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some warning status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given no statuses, when rendered, renders as empty 1`] = `<div />`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given registration for wrong api version, when rendered, renders as empty 1`] = `
|
||||||
|
<body>
|
||||||
|
<div />
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given registration for wrong kind, when rendered, renders as empty 1`] = `
|
||||||
|
<body>
|
||||||
|
<div />
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given registration without status for exact kube object, when rendered, renders as empty 1`] = `
|
||||||
|
<body>
|
||||||
|
<div />
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`kube-object-status-icon given status for all levels is present, when rendered, renders with statuses 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="Icon KubeObjectStatusIcon error material focusable"
|
||||||
|
id="tooltip_target_4"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon"
|
||||||
|
data-icon-name="error"
|
||||||
|
>
|
||||||
|
error
|
||||||
|
</span>
|
||||||
|
<div />
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Tooltip narrow formatter"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="KubeObjectStatusTooltip"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="level error"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Critical
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some critical status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="level warning"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Warning
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some warning status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="level info"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
>
|
||||||
|
Info
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="status msg"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
Some info status for some-name
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="age"
|
||||||
|
>
|
||||||
|
·
|
||||||
|
2d
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
@ -0,0 +1,263 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||||
|
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||||
|
import { DiRender, renderFor } from "../test-utils/renderFor";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||||
|
import { KubeObjectStatusLevel } from "../../../extensions/renderer-api/kube-object-status";
|
||||||
|
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import { KubeObjectStatusIcon } from "./kube-object-status-icon";
|
||||||
|
import React from "react";
|
||||||
|
import type { KubeObjectStatusRegistration } from "./kube-object-status-registration";
|
||||||
|
|
||||||
|
describe("kube-object-status-icon", () => {
|
||||||
|
let render: DiRender;
|
||||||
|
let kubeObjectStatusRegistrations: KubeObjectStatusRegistration[];
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
// TODO: Make mocking of date in unit tests global
|
||||||
|
global.Date.now = () => new Date("2015-10-21T07:28:00Z").getTime();
|
||||||
|
|
||||||
|
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
|
render = renderFor(di);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations = [];
|
||||||
|
|
||||||
|
const someTestExtension = new SomeTestExtension(
|
||||||
|
kubeObjectStatusRegistrations,
|
||||||
|
);
|
||||||
|
|
||||||
|
di.override(rendererExtensionsInjectable, () =>
|
||||||
|
computed(() => [someTestExtension]),
|
||||||
|
);
|
||||||
|
|
||||||
|
await di.runSetups();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given no statuses, when rendered, renders as empty", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("irrelevant", "irrelevant");
|
||||||
|
|
||||||
|
const { container } = render(<KubeObjectStatusIcon object={kubeObject} />);
|
||||||
|
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given level "critical" status, when rendered, renders with status', () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
|
"critical",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given level "info" status, when rendered, renders with status', () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.INFO,
|
||||||
|
"info",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given level "warning" status, when rendered, renders with status', () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.WARNING,
|
||||||
|
"warning",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given status for all levels is present, when rendered, renders with statuses", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const critical = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
|
"critical",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
const warning = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.WARNING,
|
||||||
|
"warning",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
const info = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.INFO,
|
||||||
|
"info",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(critical);
|
||||||
|
kubeObjectStatusRegistrations.push(warning);
|
||||||
|
kubeObjectStatusRegistrations.push(info);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given info and warning statuses are present, when rendered, renders with statuses", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const warning = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.WARNING,
|
||||||
|
"warning",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
const info = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.INFO,
|
||||||
|
"info",
|
||||||
|
"some-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(warning);
|
||||||
|
kubeObjectStatusRegistrations.push(info);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("given registration for wrong api version, when rendered, renders as empty", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
|
"irrelevant",
|
||||||
|
"some-kind",
|
||||||
|
["some-other-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given registration for wrong kind, when rendered, renders as empty", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = getStatusRegistration(
|
||||||
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
|
"irrelevant",
|
||||||
|
"some-other-kind",
|
||||||
|
["some-api-version"],
|
||||||
|
);
|
||||||
|
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given registration without status for exact kube object, when rendered, renders as empty", () => {
|
||||||
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
|
const statusRegistration = {
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
kind: "some-kind",
|
||||||
|
resolve: (): void => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
kubeObjectStatusRegistrations.push(statusRegistration);
|
||||||
|
|
||||||
|
const { baseElement } = render(
|
||||||
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const getKubeObjectStub = (kind: string, apiVersion: string) => KubeObject.create({
|
||||||
|
apiVersion,
|
||||||
|
kind,
|
||||||
|
metadata: {
|
||||||
|
uid: "some-uid",
|
||||||
|
name: "some-name",
|
||||||
|
resourceVersion: "some-resource-version",
|
||||||
|
namespace: "some-namespace",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const getStatusRegistration = (level: KubeObjectStatusLevel, title: string, kind: string, apiVersions: string[]) => ({
|
||||||
|
apiVersions,
|
||||||
|
kind,
|
||||||
|
resolve: (kubeObject: KubeObject) => ({
|
||||||
|
level,
|
||||||
|
text: `Some ${title} status for ${kubeObject.getName()}`,
|
||||||
|
timestamp: "2015-10-19T07:28:00Z",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
class SomeTestExtension extends LensRendererExtension {
|
||||||
|
constructor(kubeObjectStatusTexts: KubeObjectStatusRegistration[]) {
|
||||||
|
super({
|
||||||
|
id: "some-id",
|
||||||
|
absolutePath: "irrelevant",
|
||||||
|
isBundled: false,
|
||||||
|
isCompatible: false,
|
||||||
|
isEnabled: false,
|
||||||
|
manifest: { name: "some-id", version: "some-version" },
|
||||||
|
manifestPath: "irrelevant",
|
||||||
|
});
|
||||||
|
|
||||||
|
this.kubeObjectStatusTexts = kubeObjectStatusTexts;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,8 @@ import React from "react";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { cssNames, formatDuration } from "../../utils";
|
import { cssNames, formatDuration } from "../../utils";
|
||||||
import { KubeObject, KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api";
|
import { KubeObject, KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api";
|
||||||
import { KubeObjectStatusRegistry } from "../../../extensions/registries";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import statusesForKubeObjectInjectable from "./statuses-for-kube-object.injectable";
|
||||||
|
|
||||||
function statusClassName(level: KubeObjectStatusLevel): string {
|
function statusClassName(level: KubeObjectStatusLevel): string {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -68,7 +69,11 @@ export interface KubeObjectStatusIconProps {
|
|||||||
object: KubeObject;
|
object: KubeObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class KubeObjectStatusIcon extends React.Component<KubeObjectStatusIconProps> {
|
interface Dependencies {
|
||||||
|
statuses: KubeObjectStatus[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class NonInjectedKubeObjectStatusIcon extends React.Component<KubeObjectStatusIconProps & Dependencies> {
|
||||||
renderStatuses(statuses: KubeObjectStatus[], level: number) {
|
renderStatuses(statuses: KubeObjectStatus[], level: number) {
|
||||||
const filteredStatuses = statuses.filter((item) => item.level == level);
|
const filteredStatuses = statuses.filter((item) => item.level == level);
|
||||||
|
|
||||||
@ -89,7 +94,7 @@ export class KubeObjectStatusIcon extends React.Component<KubeObjectStatusIconPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const statuses = KubeObjectStatusRegistry.getInstance().getItemsForObject(this.props.object);
|
const statuses = this.props.statuses;
|
||||||
|
|
||||||
if (statuses.length === 0) {
|
if (statuses.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -114,3 +119,14 @@ export class KubeObjectStatusIcon extends React.Component<KubeObjectStatusIconPr
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const KubeObjectStatusIcon = withInjectables<Dependencies, KubeObjectStatusIconProps>(
|
||||||
|
NonInjectedKubeObjectStatusIcon,
|
||||||
|
|
||||||
|
{
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
statuses: di.inject(statusesForKubeObjectInjectable, props.object),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import type { KubeObjectStatus } from "../../../extensions/renderer-api/kube-object-status";
|
||||||
|
|
||||||
|
export interface KubeObjectStatusRegistration {
|
||||||
|
kind: string;
|
||||||
|
apiVersions: string[];
|
||||||
|
resolve: (object: KubeObject) => KubeObjectStatus;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||||
|
|
||||||
|
const statusRegistrationsInjectable = getInjectable({
|
||||||
|
id: "status-registrations",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const extensions = di.inject(rendererExtensionsInjectable);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
extensions.get().flatMap((extension) => extension.kubeObjectStatusTexts),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.singleton,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default statusRegistrationsInjectable;
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||||
|
import statusRegistrationsInjectable from "./status-registrations.injectable";
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import { conforms, eq, includes } from "lodash/fp";
|
||||||
|
import type { KubeObjectStatusRegistration } from "./kube-object-status-registration";
|
||||||
|
|
||||||
|
const statusesForKubeObjectInjectable = getInjectable({
|
||||||
|
id: "statuses-for-kube-object",
|
||||||
|
|
||||||
|
instantiate: (di, kubeObject: KubeObject) =>
|
||||||
|
di
|
||||||
|
.inject(statusRegistrationsInjectable)
|
||||||
|
.get()
|
||||||
|
.filter(toKubeObjectRelated(kubeObject))
|
||||||
|
.map(toStatus(kubeObject))
|
||||||
|
.filter(Boolean),
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.transient,
|
||||||
|
});
|
||||||
|
|
||||||
|
const toKubeObjectRelated = (kubeObject: KubeObject) =>
|
||||||
|
conforms({
|
||||||
|
kind: eq(kubeObject.kind),
|
||||||
|
apiVersions: includes(kubeObject.apiVersion),
|
||||||
|
});
|
||||||
|
|
||||||
|
const toStatus =
|
||||||
|
(kubeObject: KubeObject) => (item: KubeObjectStatusRegistration) =>
|
||||||
|
item.resolve(kubeObject);
|
||||||
|
|
||||||
|
export default statusesForKubeObjectInjectable;
|
||||||
@ -12,6 +12,5 @@ export function initRegistries() {
|
|||||||
registries.EntitySettingRegistry.createInstance();
|
registries.EntitySettingRegistry.createInstance();
|
||||||
registries.GlobalPageRegistry.createInstance();
|
registries.GlobalPageRegistry.createInstance();
|
||||||
registries.KubeObjectDetailRegistry.createInstance();
|
registries.KubeObjectDetailRegistry.createInstance();
|
||||||
registries.KubeObjectStatusRegistry.createInstance();
|
|
||||||
registries.WorkloadsOverviewDetailRegistry.createInstance();
|
registries.WorkloadsOverviewDetailRegistry.createInstance();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user