mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introduce kludge to make "isEnabledForCluster" work again for cluster pages PART 1 (#5800)
* Kludge "isEnabledForCluster" work again for cluster pages Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce kludge to make "isEnabledForCluster" work again for cluster page menus PART 2 (#5801) * Kludge "isEnabledForCluster" work again for cluster page menus (sidebar items) Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce kludge to make "isEnabledForCluster" work again for kube object status texts PART 3 (#5802) * Kludge "isEnabledForCluster" work again for kube object status texts Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kludge "isEnabledForCluster" work again for kube object menu items (#5803) Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce kludge to make "isEnabledForCluster" work again for workload overview details PART 5 (#5804) * Kludge "isEnabledForCluster" work again for cluster page menus (sidebar items) Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kludge "isEnabledForCluster" work again for kube object status texts Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kludge "isEnabledForCluster" work again for kube object menu items Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kludge "isEnabledForCluster" work again for workload overview details Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kludge "isEnabledForCluster" work again for kube object details (#5805) Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
27cb7d1ca9
commit
ca40c51117
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import type { TestExtensionRenderer } from "../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import { getExtensionFakeFor } from "../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import type { KubernetesCluster } from "../../../common/catalog-entities";
|
||||||
|
import React from "react";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
|
||||||
|
describe("disable-cluster-pages-when-cluster-is-not-relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let rendererTestExtension: TestExtensionRenderer;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<(cluster: KubernetesCluster) => Promise<boolean>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
builder.dis.rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
clusterPages: [{
|
||||||
|
components: {
|
||||||
|
Page: () => <div data-testid="some-test-page">Some page</div>,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendererTestExtension = testExtension.renderer;
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster, when navigating", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
rendererTestExtension.navigate();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the page", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-test-page");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster, when navigating", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
|
||||||
|
rendererTestExtension.navigate();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the page", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-test-page");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster, when navigating", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
|
||||||
|
rendererTestExtension.navigate();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the page", () => {
|
||||||
|
const actual = rendered.getByTestId("some-test-page");
|
||||||
|
|
||||||
|
expect(actual).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import type { KubernetesCluster } from "../../../common/catalog-entities";
|
||||||
|
import React from "react";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
|
||||||
|
describe("disable sidebar items when cluster is not relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<(cluster: KubernetesCluster) => Promise<boolean>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
builder.dis.rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
clusterPages: [{
|
||||||
|
components: {
|
||||||
|
Page: () => <div data-testid="some-test-page">Some page</div>,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
|
||||||
|
clusterPageMenus: [
|
||||||
|
{
|
||||||
|
id: "some-sidebar-item",
|
||||||
|
title: "Some sidebar item",
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Icon: () => <div>Some icon</div>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the sidebar item", () => {
|
||||||
|
const actual = rendered.queryByTestId(
|
||||||
|
"sidebar-item-some-extension-name-some-sidebar-item",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the sidebar item", () => {
|
||||||
|
const actual = rendered.queryByTestId(
|
||||||
|
"sidebar-item-some-extension-name-some-sidebar-item",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the sidebar item", () => {
|
||||||
|
const actual = rendered.getByTestId(
|
||||||
|
"sidebar-item-test-extension-some-sidebar-item",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(actual).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,172 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||||
|
import { getApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { frontEndRouteInjectionToken } from "../../../../common/front-end-routing/front-end-route-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import React from "react";
|
||||||
|
import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
|
import { routeSpecificComponentInjectionToken } from "../../../../renderer/routes/route-specific-component-injection-token";
|
||||||
|
import { KubeObject } from "../../../../common/k8s-api/kube-object";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
|
import { KubeObjectDetails } from "../../../../renderer/components/kube-object-details";
|
||||||
|
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
|
||||||
|
|
||||||
|
describe("disable kube object detail items when cluster is not relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<
|
||||||
|
(cluster: KubernetesCluster) => Promise<boolean>
|
||||||
|
>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.beforeApplicationStart(({ rendererDi }) => {
|
||||||
|
rendererDi.override(
|
||||||
|
apiManagerInjectable,
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
getStore: () => ({
|
||||||
|
getByPath: () =>
|
||||||
|
getKubeObjectStub("some-kind", "some-api-version"),
|
||||||
|
}),
|
||||||
|
} as unknown as ApiManager),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const rendererDi = builder.dis.rendererDi;
|
||||||
|
|
||||||
|
rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
rendererDi.register(testRouteInjectable, testRouteComponentInjectable);
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
kubeObjectDetailItems: [
|
||||||
|
{
|
||||||
|
kind: "some-kind",
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
components: {
|
||||||
|
Details: () => (
|
||||||
|
<div data-testid="some-kube-object-detail-item">
|
||||||
|
Some detail
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken);
|
||||||
|
const testRoute = rendererDi.inject(testRouteInjectable);
|
||||||
|
|
||||||
|
navigateToRoute(testRoute);
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the kube object detail item", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-kube-object-detail-item");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the kube object detail item", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-kube-object-detail-item");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the kube object detail item", () => {
|
||||||
|
const actual = rendered.getByTestId("some-kube-object-detail-item");
|
||||||
|
|
||||||
|
expect(actual).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteInjectable = getInjectable({
|
||||||
|
id: "test-route",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
path: "/test-route",
|
||||||
|
clusterFrame: true,
|
||||||
|
isEnabled: computed(() => true),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: frontEndRouteInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteComponentInjectable = getInjectable({
|
||||||
|
id: "test-route-component",
|
||||||
|
|
||||||
|
instantiate: (di) => ({
|
||||||
|
route: di.inject(testRouteInjectable),
|
||||||
|
|
||||||
|
Component: () => <KubeObjectDetails />,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: routeSpecificComponentInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getKubeObjectStub = (kind: string, apiVersion: string) =>
|
||||||
|
KubeObject.create({
|
||||||
|
apiVersion,
|
||||||
|
kind,
|
||||||
|
metadata: {
|
||||||
|
uid: "some-uid",
|
||||||
|
name: "some-name",
|
||||||
|
resourceVersion: "some-resource-version",
|
||||||
|
namespace: "some-namespace",
|
||||||
|
selfLink: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,165 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||||
|
import { getApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { frontEndRouteInjectionToken } from "../../../../common/front-end-routing/front-end-route-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import React from "react";
|
||||||
|
import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
|
import { routeSpecificComponentInjectionToken } from "../../../../renderer/routes/route-specific-component-injection-token";
|
||||||
|
import { KubeObject } from "../../../../common/k8s-api/kube-object";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { KubeObjectMenu } from "../../../../renderer/components/kube-object-menu";
|
||||||
|
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
|
|
||||||
|
describe("disable kube object menu items when cluster is not relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<
|
||||||
|
(cluster: KubernetesCluster) => Promise<boolean>
|
||||||
|
>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.beforeApplicationStart(({ mainDi }) => {
|
||||||
|
mainDi.override(apiManagerInjectable, () => ({}));
|
||||||
|
});
|
||||||
|
|
||||||
|
const rendererDi = builder.dis.rendererDi;
|
||||||
|
|
||||||
|
rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
rendererDi.register(testRouteInjectable, testRouteComponentInjectable);
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
kubeObjectMenuItems: [
|
||||||
|
{
|
||||||
|
kind: "some-kind",
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
components: {
|
||||||
|
MenuItem: () => (
|
||||||
|
<div data-testid="some-test-id">Some menu item</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken);
|
||||||
|
const testRoute = rendererDi.inject(testRouteInjectable);
|
||||||
|
|
||||||
|
navigateToRoute(testRoute);
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the kube object menu item", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-test-id");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the kube object menu item", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-test-id");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the kube object menu item", () => {
|
||||||
|
const actual = rendered.getByTestId("some-test-id");
|
||||||
|
|
||||||
|
expect(actual).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteInjectable = getInjectable({
|
||||||
|
id: "test-route",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
path: "/test-route",
|
||||||
|
clusterFrame: true,
|
||||||
|
isEnabled: computed(() => true),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: frontEndRouteInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteComponentInjectable = getInjectable({
|
||||||
|
id: "test-route-component",
|
||||||
|
|
||||||
|
instantiate: (di) => ({
|
||||||
|
route: di.inject(testRouteInjectable),
|
||||||
|
|
||||||
|
Component: () => (
|
||||||
|
<KubeObjectMenu
|
||||||
|
toolbar={true}
|
||||||
|
object={getKubeObjectStub("some-kind", "some-api-version")}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: routeSpecificComponentInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getKubeObjectStub = (kind: string, apiVersion: string) =>
|
||||||
|
KubeObject.create({
|
||||||
|
apiVersion,
|
||||||
|
kind,
|
||||||
|
metadata: {
|
||||||
|
uid: "some-uid",
|
||||||
|
name: "some-name",
|
||||||
|
resourceVersion: "some-resource-version",
|
||||||
|
namespace: "some-namespace",
|
||||||
|
selfLink: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||||
|
import { getApplicationBuilder } from "../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { frontEndRouteInjectionToken } from "../../../../common/front-end-routing/front-end-route-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import React from "react";
|
||||||
|
import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
|
import { routeSpecificComponentInjectionToken } from "../../../../renderer/routes/route-specific-component-injection-token";
|
||||||
|
import { KubeObjectStatusIcon } from "../../../../renderer/components/kube-object-status-icon/kube-object-status-icon";
|
||||||
|
import { KubeObject } from "../../../../common/k8s-api/kube-object";
|
||||||
|
import { KubeObjectStatusLevel } from "../../../../common/k8s-api/kube-object-status";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
|
||||||
|
describe("disable kube object statuses when cluster is not relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<
|
||||||
|
(cluster: KubernetesCluster) => Promise<boolean>
|
||||||
|
>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
const rendererDi = builder.dis.rendererDi;
|
||||||
|
|
||||||
|
rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
rendererDi.register(testRouteInjectable, testRouteComponentInjectable);
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
kubeObjectStatusTexts: [
|
||||||
|
{
|
||||||
|
kind: "some-kind",
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
|
||||||
|
resolve: () => ({
|
||||||
|
level: KubeObjectStatusLevel.CRITICAL,
|
||||||
|
text: "some-kube-object-status-text",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken);
|
||||||
|
const testRoute = rendererDi.inject(testRouteInjectable);
|
||||||
|
|
||||||
|
navigateToRoute(testRoute);
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the status", () => {
|
||||||
|
const actual = rendered.baseElement.querySelectorAll(".KubeObjectStatusIcon");
|
||||||
|
|
||||||
|
expect(actual).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the status", () => {
|
||||||
|
const actual = rendered.baseElement.querySelectorAll(".KubeObjectStatusIcon");
|
||||||
|
|
||||||
|
expect(actual).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the status", () => {
|
||||||
|
const actual = rendered.baseElement.querySelectorAll(".KubeObjectStatusIcon");
|
||||||
|
|
||||||
|
expect(actual).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteInjectable = getInjectable({
|
||||||
|
id: "test-route",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
path: "/test-route",
|
||||||
|
clusterFrame: true,
|
||||||
|
isEnabled: computed(() => true),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: frontEndRouteInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const testRouteComponentInjectable = getInjectable({
|
||||||
|
id: "test-route-component",
|
||||||
|
|
||||||
|
instantiate: (di) => ({
|
||||||
|
route: di.inject(testRouteInjectable),
|
||||||
|
|
||||||
|
Component: () => (
|
||||||
|
<KubeObjectStatusIcon
|
||||||
|
object={getKubeObjectStub("some-kind", "some-api-version")}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: routeSpecificComponentInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getKubeObjectStub = (kind: string, apiVersion: string) =>
|
||||||
|
KubeObject.create({
|
||||||
|
apiVersion,
|
||||||
|
kind,
|
||||||
|
metadata: {
|
||||||
|
uid: "some-uid",
|
||||||
|
name: "some-name",
|
||||||
|
resourceVersion: "some-resource-version",
|
||||||
|
namespace: "some-namespace",
|
||||||
|
selfLink: "/foo",
|
||||||
|
},
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
|
import asyncFn from "@async-fn/jest";
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ApplicationBuilder } from "../../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import type { KubernetesCluster } from "../../../../../common/catalog-entities";
|
||||||
|
import { getApplicationBuilder } from "../../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import apiManagerInjectable from "../../../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
|
import navigateToWorkloadsOverviewInjectable from "../../../../../common/front-end-routing/routes/cluster/workloads/overview/navigate-to-workloads-overview.injectable";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
describe("disable workloads overview details when cluster is not relevant", () => {
|
||||||
|
let builder: ApplicationBuilder;
|
||||||
|
let rendered: RenderResult;
|
||||||
|
let isEnabledForClusterMock: AsyncFnMock<
|
||||||
|
(cluster: KubernetesCluster) => Promise<boolean>
|
||||||
|
>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.beforeApplicationStart(({ mainDi }) => {
|
||||||
|
mainDi.override(apiManagerInjectable, () => ({}));
|
||||||
|
});
|
||||||
|
|
||||||
|
const rendererDi = builder.dis.rendererDi;
|
||||||
|
|
||||||
|
rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
const getExtensionFake = getExtensionFakeFor(builder);
|
||||||
|
|
||||||
|
isEnabledForClusterMock = asyncFn();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFake({
|
||||||
|
id: "test-extension-id",
|
||||||
|
name: "test-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
isEnabledForCluster: isEnabledForClusterMock,
|
||||||
|
|
||||||
|
kubeWorkloadsOverviewItems: [
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
Details: () => (
|
||||||
|
<div data-testid="some-detail-component">Some detail component</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
const navigateToWorkloadsOverview = rendererDi.inject(
|
||||||
|
navigateToWorkloadsOverviewInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
navigateToWorkloadsOverview();
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given not yet known if extension should be enabled for the cluster", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the detail", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-detail-component");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension shouldn't be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show the detail", () => {
|
||||||
|
const actual = rendered.queryByTestId("some-detail-component");
|
||||||
|
|
||||||
|
expect(actual).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given extension should be enabled for the cluster", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await isEnabledForClusterMock.resolve(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders", () => {
|
||||||
|
expect(rendered.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the detail", () => {
|
||||||
|
const actual = rendered.getByTestId("some-detail-component");
|
||||||
|
|
||||||
|
expect(actual).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import { getApplicationBuilder } from "../../../../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import { getExtensionFakeFor } from "../../../../../renderer/components/test-utils/get-extension-fake";
|
||||||
|
import React from "react";
|
||||||
|
import getRandomIdInjectable from "../../../../../common/utils/get-random-id.injectable";
|
||||||
|
import { workloadOverviewDetailInjectionToken } from "../../../../../renderer/components/+workloads-overview/workload-overview-details/workload-overview-detail-injection-token";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
describe("order of workload overview details", () => {
|
||||||
|
let rendered: RenderResult;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const builder = getApplicationBuilder();
|
||||||
|
|
||||||
|
builder.beforeApplicationStart(({ rendererDi }) => {
|
||||||
|
rendererDi.unoverride(getRandomIdInjectable);
|
||||||
|
rendererDi.permitSideEffects(getRandomIdInjectable);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setEnvironmentToClusterFrame();
|
||||||
|
|
||||||
|
rendered = await builder.render();
|
||||||
|
|
||||||
|
const testExtension = getExtensionFakeFor(builder)({
|
||||||
|
id: "some-extension-id",
|
||||||
|
name: "some-extension",
|
||||||
|
|
||||||
|
rendererOptions: {
|
||||||
|
kubeWorkloadsOverviewItems: [
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
Details: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-extension-item-without-priority"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 70,
|
||||||
|
components: {
|
||||||
|
Details: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-extension-item-with-high-priority"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 10,
|
||||||
|
components: {
|
||||||
|
Details: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-extension-item-with-low-priority"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.extensions.enable(testExtension);
|
||||||
|
|
||||||
|
|
||||||
|
builder.dis.rendererDi.register(
|
||||||
|
someCoreItemWithLowOrderNumberInjectable,
|
||||||
|
someCoreItemWithHighOrderNumberInjectable,
|
||||||
|
someCoreItemWithDefaultOrderNumberInjectable,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows items in correct order", () => {
|
||||||
|
const actual = rendered.queryAllByTestId("workload-overview-detail").map(x => x.id);
|
||||||
|
|
||||||
|
expect(actual).toEqual([
|
||||||
|
"some-core-item-with-low-order-number",
|
||||||
|
"some-extension-item-with-high-priority",
|
||||||
|
"some-core-item-with-default-order-number",
|
||||||
|
"some-extension-item-without-priority",
|
||||||
|
"some-core-item-with-high-order-number",
|
||||||
|
"some-extension-item-with-low-priority",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const someCoreItemWithLowOrderNumberInjectable = getInjectable({
|
||||||
|
id: "some-core-item-with-low-order-number",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
orderNumber: 30,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
|
||||||
|
Component: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-core-item-with-low-order-number"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const someCoreItemWithDefaultOrderNumberInjectable = getInjectable({
|
||||||
|
id: "some-core-item-with-default-order-number",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
orderNumber: 50,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
|
||||||
|
Component: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-core-item-with-default-order-number"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const someCoreItemWithHighOrderNumberInjectable = getInjectable({
|
||||||
|
id: "some-core-item-high-order-number",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
orderNumber: 60,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
|
||||||
|
Component: () => (
|
||||||
|
<div
|
||||||
|
data-testid="workload-overview-detail"
|
||||||
|
id="some-core-item-with-high-order-number"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
@ -5,7 +5,7 @@
|
|||||||
export type { StatusBarRegistration } from "../../renderer/components/status-bar/status-bar-registration";
|
export type { StatusBarRegistration } from "../../renderer/components/status-bar/status-bar-registration";
|
||||||
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../../renderer/components/kube-object-menu/kube-object-menu-registration";
|
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../../renderer/components/kube-object-menu/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 "../../renderer/components/kube-object-details/kube-object-detail-registration";
|
||||||
export type { KubeObjectStatusRegistration } from "../../renderer/components/kube-object-status-icon/kube-object-status-registration";
|
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";
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { KubernetesCluster } from "../../common/catalog-entities";
|
||||||
|
import type { LensRendererExtension } from "../lens-renderer-extension";
|
||||||
|
|
||||||
|
interface ExtensionIsEnabledForCluster {
|
||||||
|
extension: LensRendererExtension;
|
||||||
|
cluster: KubernetesCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extensionIsEnabledForClusterInjectable = getInjectable({
|
||||||
|
id: "extension-is-enabled-for-cluster",
|
||||||
|
|
||||||
|
instantiate: async (
|
||||||
|
di,
|
||||||
|
{ extension, cluster }: ExtensionIsEnabledForCluster,
|
||||||
|
) => (await extension.isEnabledForCluster(cluster)) as boolean,
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (
|
||||||
|
di,
|
||||||
|
{ extension, cluster }: ExtensionIsEnabledForCluster,
|
||||||
|
) => `${extension.sanitizedExtensionId}-${cluster.getId()}`,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default extensionIsEnabledForClusterInjectable;
|
||||||
@ -12,7 +12,6 @@ import { broadcastMessage, ipcMainOn, ipcRendererOn, ipcMainHandle } from "../..
|
|||||||
import type { Disposer } from "../../common/utils";
|
import type { Disposer } from "../../common/utils";
|
||||||
import { isDefined, toJS } from "../../common/utils";
|
import { isDefined, toJS } from "../../common/utils";
|
||||||
import logger from "../../main/logger";
|
import logger from "../../main/logger";
|
||||||
import type { CatalogEntity, KubernetesCluster } from "../common-api/catalog";
|
|
||||||
import type { InstalledExtension } from "../extension-discovery/extension-discovery";
|
import type { InstalledExtension } from "../extension-discovery/extension-discovery";
|
||||||
import type { LensExtension, LensExtensionConstructor, LensExtensionId } from "../lens-extension";
|
import type { LensExtension, LensExtensionConstructor, LensExtensionId } from "../lens-extension";
|
||||||
import type { LensRendererExtension } from "../lens-renderer-extension";
|
import type { LensRendererExtension } from "../lens-renderer-extension";
|
||||||
@ -274,32 +273,10 @@ export class ExtensionLoader {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
loadOnClusterRenderer = (getCluster: () => CatalogEntity) => {
|
loadOnClusterRenderer = () => {
|
||||||
logger.debug(`${logModule}: load on cluster renderer (dashboard)`);
|
logger.debug(`${logModule}: load on cluster renderer (dashboard)`);
|
||||||
|
|
||||||
this.autoInitExtensions(async (ext) => {
|
this.autoInitExtensions(async () => []);
|
||||||
const entity = getCluster() as KubernetesCluster;
|
|
||||||
const extension = ext as LensRendererExtension;
|
|
||||||
|
|
||||||
// getCluster must be a callback, as the entity might be available only after an extension has been loaded
|
|
||||||
if ((await extension.isEnabledForCluster(entity)) === false) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeItems = [
|
|
||||||
registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems),
|
|
||||||
];
|
|
||||||
|
|
||||||
this.onRemoveExtensionId.addListener((removedExtensionId) => {
|
|
||||||
if (removedExtensionId === extension.id) {
|
|
||||||
removeItems.forEach(remove => {
|
|
||||||
remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return removeItems;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected async loadExtensions(installedExtensions: Map<string, InstalledExtension>, register: (ext: LensExtension) => Promise<Disposer[]>) {
|
protected async loadExtensions(installedExtensions: Map<string, InstalledExtension>, register: (ext: LensExtension) => Promise<Disposer[]>) {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import { getExtensionRoutePath } from "../renderer/routes/for-extension";
|
|||||||
import type { LensRendererExtensionDependencies } from "./lens-extension-set-dependencies";
|
import type { LensRendererExtensionDependencies } from "./lens-extension-set-dependencies";
|
||||||
import type { KubeObjectHandlerRegistration } from "../renderer/kube-object/handler";
|
import type { KubeObjectHandlerRegistration } from "../renderer/kube-object/handler";
|
||||||
import type { AppPreferenceTabRegistration } from "../renderer/components/+preferences/app-preference-tab/app-preference-tab-registration";
|
import type { AppPreferenceTabRegistration } from "../renderer/components/+preferences/app-preference-tab/app-preference-tab-registration";
|
||||||
|
import type { KubeObjectDetailRegistration } from "../renderer/components/kube-object-details/kube-object-detail-registration";
|
||||||
|
|
||||||
export class LensRendererExtension extends LensExtension<LensRendererExtensionDependencies> {
|
export class LensRendererExtension extends LensExtension<LensRendererExtensionDependencies> {
|
||||||
globalPages: registries.PageRegistration[] = [];
|
globalPages: registries.PageRegistration[] = [];
|
||||||
@ -37,7 +38,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
|||||||
appPreferenceTabs: AppPreferenceTabRegistration[] = [];
|
appPreferenceTabs: AppPreferenceTabRegistration[] = [];
|
||||||
entitySettings: registries.EntitySettingRegistration[] = [];
|
entitySettings: registries.EntitySettingRegistration[] = [];
|
||||||
statusBarItems: StatusBarRegistration[] = [];
|
statusBarItems: StatusBarRegistration[] = [];
|
||||||
kubeObjectDetailItems: registries.KubeObjectDetailRegistration[] = [];
|
kubeObjectDetailItems: KubeObjectDetailRegistration[] = [];
|
||||||
kubeObjectMenuItems: KubeObjectMenuRegistration[] = [];
|
kubeObjectMenuItems: KubeObjectMenuRegistration[] = [];
|
||||||
kubeWorkloadsOverviewItems: WorkloadsOverviewDetailRegistration[] = [];
|
kubeWorkloadsOverviewItems: WorkloadsOverviewDetailRegistration[] = [];
|
||||||
commands: CommandRegistration[] = [];
|
commands: CommandRegistration[] = [];
|
||||||
|
|||||||
@ -7,7 +7,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 "./entity-setting-registry";
|
export * from "./entity-setting-registry";
|
||||||
export * from "./catalog-entity-detail-registry";
|
export * from "./catalog-entity-detail-registry";
|
||||||
export * from "./protocol-handler";
|
export * from "./protocol-handler";
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type React from "react";
|
|
||||||
import type { Disposer } from "../../common/utils";
|
|
||||||
import type { KubeObjectDetailsProps } from "../renderer-api/components";
|
|
||||||
import type { KubeObject } from "../renderer-api/k8s-api";
|
|
||||||
import { BaseRegistry } from "./base-registry";
|
|
||||||
|
|
||||||
export interface KubeObjectDetailComponents<T extends KubeObject = KubeObject> {
|
|
||||||
Details: React.ComponentType<KubeObjectDetailsProps<T>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface KubeObjectDetailRegistration<T extends KubeObject = KubeObject> {
|
|
||||||
kind: string;
|
|
||||||
apiVersions: string[];
|
|
||||||
components: KubeObjectDetailComponents<T>;
|
|
||||||
priority?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class KubeObjectDetailRegistry extends BaseRegistry<KubeObjectDetailRegistration> {
|
|
||||||
add(items: KubeObjectDetailRegistration[]): Disposer;
|
|
||||||
add<T extends KubeObject>(item: KubeObjectDetailRegistration<T>): Disposer;
|
|
||||||
add(items: KubeObjectDetailRegistration | KubeObjectDetailRegistration[]): Disposer {
|
|
||||||
return super.add(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
getItemsForKind(kind: string, apiVersion: string) {
|
|
||||||
const items = this.getItems().filter((item) => {
|
|
||||||
return item.kind === kind && item.apiVersions.includes(apiVersion);
|
|
||||||
});
|
|
||||||
|
|
||||||
return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export { KubeObjectDetailRegistry } from "../../extensions/registries/kube-object-detail-registry";
|
|
||||||
@ -102,9 +102,6 @@ export async function bootstrap(di: DiContainer) {
|
|||||||
logger.info(`${logPrefix} initializing EntitySettingsRegistry`);
|
logger.info(`${logPrefix} initializing EntitySettingsRegistry`);
|
||||||
initializers.initEntitySettingsRegistry();
|
initializers.initEntitySettingsRegistry();
|
||||||
|
|
||||||
logger.info(`${logPrefix} initializing KubeObjectDetailRegistry`);
|
|
||||||
initializers.initKubeObjectDetailRegistry();
|
|
||||||
|
|
||||||
logger.info(`${logPrefix} initializing CatalogEntityDetailRegistry`);
|
logger.info(`${logPrefix} initializing CatalogEntityDetailRegistry`);
|
||||||
initializers.initCatalogEntityDetailRegistry();
|
initializers.initCatalogEntityDetailRegistry();
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import catalogEntityRegistryInjectable from "../api/catalog/entity/registry.injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { isKubernetesCluster } from "../../common/catalog-entities";
|
||||||
|
|
||||||
|
const activeKubernetesClusterInjectable = getInjectable({
|
||||||
|
id: "active-kubernetes-cluster",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
const activeEntity = catalogEntityRegistry.activeEntity;
|
||||||
|
|
||||||
|
if (!isKubernetesCluster(activeEntity)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeEntity;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default activeKubernetesClusterInjectable;
|
||||||
@ -1,68 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
|
||||||
import { computed } from "mobx";
|
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
|
||||||
import { OverviewStatuses } from "./overview-statuses";
|
|
||||||
import { WorkloadEvents } from "../../initializers/workload-events";
|
|
||||||
import { orderBy } from "lodash/fp";
|
|
||||||
import type { WorkloadsOverviewDetailRegistration } from "./workloads-overview-detail-registration";
|
|
||||||
|
|
||||||
const detailComponentsInjectable = getInjectable({
|
|
||||||
id: "workload-detail-components",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const extensions = di.inject(rendererExtensionsInjectable);
|
|
||||||
|
|
||||||
return computed(() => {
|
|
||||||
const extensionRegistrations = extensions
|
|
||||||
.get()
|
|
||||||
.flatMap((extension) => extension.kubeWorkloadsOverviewItems);
|
|
||||||
|
|
||||||
const allRegistrations = [
|
|
||||||
...coreRegistrations,
|
|
||||||
...extensionRegistrations,
|
|
||||||
];
|
|
||||||
|
|
||||||
return getRegistrationsInPriorityOrder(allRegistrations).map(
|
|
||||||
(item) => item.components.Details,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const coreRegistrations = [
|
|
||||||
{
|
|
||||||
components: {
|
|
||||||
Details: OverviewStatuses,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: WorkloadEvents,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const toRegistrationWithDefaultPriority = ({
|
|
||||||
priority = 50,
|
|
||||||
...rest
|
|
||||||
}: WorkloadsOverviewDetailRegistration) => ({
|
|
||||||
priority,
|
|
||||||
...rest,
|
|
||||||
});
|
|
||||||
|
|
||||||
const getRegistrationsInPriorityOrder = (
|
|
||||||
allRegistrations: WorkloadsOverviewDetailRegistration[],
|
|
||||||
) =>
|
|
||||||
orderBy(
|
|
||||||
"priority",
|
|
||||||
"desc",
|
|
||||||
|
|
||||||
allRegistrations.map(toRegistrationWithDefaultPriority),
|
|
||||||
);
|
|
||||||
|
|
||||||
export default detailComponentsInjectable;
|
|
||||||
@ -20,7 +20,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
|
|||||||
import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable";
|
import clusterFrameContextInjectable from "../../cluster-frame-context/cluster-frame-context.injectable";
|
||||||
import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
|
import type { ClusterFrameContext } from "../../cluster-frame-context/cluster-frame-context";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
import detailComponentsInjectable from "./detail-components.injectable";
|
import workloadOverviewDetailsInjectable from "./workload-overview-details/workload-overview-details.injectable";
|
||||||
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
|
||||||
import type { PodStore } from "../+workloads-pods/store";
|
import type { PodStore } from "../+workloads-pods/store";
|
||||||
import type { DaemonSetStore } from "../+workloads-daemonsets/store";
|
import type { DaemonSetStore } from "../+workloads-daemonsets/store";
|
||||||
@ -37,7 +37,7 @@ import type { EventStore } from "../+events/store";
|
|||||||
import eventStoreInjectable from "../+events/store.injectable";
|
import eventStoreInjectable from "../+events/store.injectable";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
detailComponents: IComputedValue<React.ComponentType<{}>[]>;
|
detailComponents: IComputedValue<React.ElementType<{}>[]>;
|
||||||
clusterFrameContext: ClusterFrameContext;
|
clusterFrameContext: ClusterFrameContext;
|
||||||
subscribeStores: SubscribeStores;
|
subscribeStores: SubscribeStores;
|
||||||
podStore: PodStore;
|
podStore: PodStore;
|
||||||
@ -122,7 +122,7 @@ class NonInjectedWorkloadsOverview extends React.Component<Dependencies> {
|
|||||||
|
|
||||||
export const WorkloadsOverview = withInjectables<Dependencies>(NonInjectedWorkloadsOverview, {
|
export const WorkloadsOverview = withInjectables<Dependencies>(NonInjectedWorkloadsOverview, {
|
||||||
getProps: (di) => ({
|
getProps: (di) => ({
|
||||||
detailComponents: di.inject(detailComponentsInjectable),
|
detailComponents: di.inject(workloadOverviewDetailsInjectable),
|
||||||
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
||||||
subscribeStores: di.inject(subscribeStoresInjectable),
|
subscribeStores: di.inject(subscribeStoresInjectable),
|
||||||
daemonSetStore: di.inject(daemonSetStoreInjectable),
|
daemonSetStore: di.inject(daemonSetStoreInjectable),
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { workloadOverviewDetailInjectionToken } from "../workload-overview-detail-injection-token";
|
||||||
|
import { OverviewStatuses } from "../../overview-statuses";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const overviewStatusesInjectable = getInjectable({
|
||||||
|
id: "overview-statuses",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
Component: OverviewStatuses,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 50,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default overviewStatusesInjectable;
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { workloadOverviewDetailInjectionToken } from "../workload-overview-detail-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { WorkloadEvents } from "../../../../initializers/workload-events";
|
||||||
|
|
||||||
|
const workloadEventsInjectable = getInjectable({
|
||||||
|
id: "workload-events",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
Component: WorkloadEvents,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 300,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default workloadEventsInjectable;
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
interface WorkloadOverviewDetail {
|
||||||
|
orderNumber: number;
|
||||||
|
Component: React.ElementType<{}>;
|
||||||
|
enabled: IComputedValue<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const workloadOverviewDetailInjectionToken =
|
||||||
|
getInjectionToken<WorkloadOverviewDetail>({
|
||||||
|
id: "workload-overview-detail-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import getRandomIdInjectable from "../../../../common/utils/get-random-id.injectable";
|
||||||
|
import type { LensRendererExtension } from "../../../../extensions/lens-renderer-extension";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { workloadOverviewDetailInjectionToken } from "./workload-overview-detail-injection-token";
|
||||||
|
import { extensionRegistratorInjectionToken } from "../../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||||
|
|
||||||
|
const workloadOverviewDetailRegistratorInjectable = getInjectable({
|
||||||
|
id: "workload-overview-detail-registrator",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const getRandomId = di.inject(getRandomIdInjectable);
|
||||||
|
|
||||||
|
const getExtensionShouldBeEnabledForClusterFrame = (
|
||||||
|
extension: LensRendererExtension,
|
||||||
|
) =>
|
||||||
|
di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
|
||||||
|
|
||||||
|
return (ext) => {
|
||||||
|
const extension = ext as LensRendererExtension;
|
||||||
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrame =
|
||||||
|
getExtensionShouldBeEnabledForClusterFrame(extension);
|
||||||
|
|
||||||
|
return extension.kubeWorkloadsOverviewItems.map((registration) => {
|
||||||
|
const id = `workload-overview-detail-from-${
|
||||||
|
extension.sanitizedExtensionId
|
||||||
|
}-${getRandomId()}`;
|
||||||
|
|
||||||
|
return getInjectable({
|
||||||
|
id,
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
Component: registration.components.Details,
|
||||||
|
|
||||||
|
enabled: computed(() =>
|
||||||
|
extensionShouldBeEnabledForClusterFrame.value.get(),
|
||||||
|
),
|
||||||
|
|
||||||
|
orderNumber:
|
||||||
|
0.5 + (registration.priority ? 100 - registration.priority : 50),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: workloadOverviewDetailInjectionToken,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default workloadOverviewDetailRegistratorInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { filter, map, sortBy } from "lodash/fp";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { workloadOverviewDetailInjectionToken } from "./workload-overview-detail-injection-token";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
|
||||||
|
const workloadOverviewDetailsInjectable = getInjectable({
|
||||||
|
id: "workload-overview-details",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const details = computedInjectMany(workloadOverviewDetailInjectionToken);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
pipeline(
|
||||||
|
details.get(),
|
||||||
|
filter((detail) => detail.enabled.get()),
|
||||||
|
sortBy((detail) => detail.orderNumber),
|
||||||
|
map((detail) => detail.Component),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default workloadOverviewDetailsInjectable;
|
||||||
@ -28,7 +28,7 @@ export const FlexVolume: VolumeVariantComponent<"flexVolume"> = (
|
|||||||
{readOnly.toString()}
|
{readOnly.toString()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{
|
{
|
||||||
...Object.entries(options)
|
Object.entries(options)
|
||||||
.map(([key, value]) => (
|
.map(([key, value]) => (
|
||||||
<DrawerItem key={key} name={`Option: ${key}`}>
|
<DrawerItem key={key} name={`Option: ${key}`}>
|
||||||
{value}
|
{value}
|
||||||
|
|||||||
@ -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 } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
||||||
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
|
||||||
|
const currentKubeObjectInDetailsInjectable = getInjectable({
|
||||||
|
id: "current-kube-object-in-details",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const urlParam = di.inject(kubeDetailsUrlParamInjectable);
|
||||||
|
const apiManager = di.inject(apiManagerInjectable);
|
||||||
|
const logger = di.inject(loggerInjectable);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
const path = urlParam.get();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return apiManager.getStore(path)?.getByPath(path);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
`[KUBE-OBJECT-DETAILS]: failed to get store or object ${path}: ${error}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default currentKubeObjectInDetailsInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ClusterRoleBindingDetails } from "../../../+user-management/+cluster-role-bindings";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const clusterRoleBindingDetailItemInjectable = getInjectable({
|
||||||
|
id: "cluster-role-binding-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ClusterRoleBindingDetails,
|
||||||
|
enabled: computed(() => isClusterRoleBinding(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterRoleBindingDetailItemInjectable;
|
||||||
|
|
||||||
|
export const isClusterRoleBinding = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"ClusterRoleBinding",
|
||||||
|
["rbac.authorization.k8s.io/v1"],
|
||||||
|
);
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ClusterRoleDetails } from "../../../+user-management/+cluster-roles";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const clusterRoleDetailItemInjectable = getInjectable({
|
||||||
|
id: "cluster-role-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ClusterRoleDetails,
|
||||||
|
enabled: computed(() => isClusterRole(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterRoleDetailItemInjectable;
|
||||||
|
|
||||||
|
export const isClusterRole = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"ClusterRole",
|
||||||
|
["rbac.authorization.k8s.io/v1"],
|
||||||
|
);
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ConfigMapDetails } from "../../../+config-maps";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const configMapDetailItemInjectable = getInjectable({
|
||||||
|
id: "config-map-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ConfigMapDetails,
|
||||||
|
enabled: computed(() => isConfigMap(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default configMapDetailItemInjectable;
|
||||||
|
|
||||||
|
const isConfigMap = kubeObjectMatchesToKindAndApiVersion("ConfigMap", ["v1"]);
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { CronJobDetails } from "../../../+workloads-cronjobs";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const cronJobDetailItemInjectable = getInjectable({
|
||||||
|
id: "cron-job-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: CronJobDetails,
|
||||||
|
enabled: computed(() => isCronJob(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default cronJobDetailItemInjectable;
|
||||||
|
|
||||||
|
export const isCronJob = kubeObjectMatchesToKindAndApiVersion("CronJob", [
|
||||||
|
"batch/v1beta1",
|
||||||
|
]);
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { CRDDetails } from "../../../+custom-resources";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const customResourceDefinitionsDetailItemInjectable = getInjectable({
|
||||||
|
id: "custom-resource-definitions-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: CRDDetails,
|
||||||
|
enabled: computed(() => isCustomResourceDefinition(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default customResourceDefinitionsDetailItemInjectable;
|
||||||
|
|
||||||
|
const isCustomResourceDefinition = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"CustomResourceDefinition",
|
||||||
|
["apiextensions.k8s.io/v1", "apiextensions.k8s.io/v1beta1"],
|
||||||
|
);
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { DaemonSetDetails } from "../../../+workloads-daemonsets";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const daemonSetDetailItemInjectable = getInjectable({
|
||||||
|
id: "daemon-set-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: DaemonSetDetails,
|
||||||
|
enabled: computed(() => isDaemonSet(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default daemonSetDetailItemInjectable;
|
||||||
|
|
||||||
|
export const isDaemonSet = kubeObjectMatchesToKindAndApiVersion("DaemonSet", [
|
||||||
|
"apps/v1",
|
||||||
|
]);
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { DeploymentDetails } from "../../../+workloads-deployments";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const deploymentDetailItemInjectable = getInjectable({
|
||||||
|
id: "deployment-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: DeploymentDetails,
|
||||||
|
enabled: computed(() => isDeployment(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isDeployment = kubeObjectMatchesToKindAndApiVersion("Deployment", [
|
||||||
|
"apps/v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default deploymentDetailItemInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { EndpointsDetails } from "../../../+network-endpoints";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const endpointsDetailItemInjectable = getInjectable({
|
||||||
|
id: "endpoints-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: EndpointsDetails,
|
||||||
|
enabled: computed(() => isEndpoint(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isEndpoint = kubeObjectMatchesToKindAndApiVersion("Endpoints", [
|
||||||
|
"v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default endpointsDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { EventDetails } from "../../../+events";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const eventsDetailItemInjectable = getInjectable({
|
||||||
|
id: "events-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: EventDetails,
|
||||||
|
enabled: computed(() => isEvent(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isEvent = kubeObjectMatchesToKindAndApiVersion("Event", ["v1"]);
|
||||||
|
|
||||||
|
export default eventsDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { HpaDetails } from "../../../+config-autoscalers";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const horizontalPodAutoscalerDetailItemInjectable = getInjectable({
|
||||||
|
id: "horizontal-pod-autoscaler-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: HpaDetails,
|
||||||
|
enabled: computed(() => isHorizontalPodAutoscaler(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isHorizontalPodAutoscaler = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"HorizontalPodAutoscaler",
|
||||||
|
["autoscaling/v2beta1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default horizontalPodAutoscalerDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { IngressDetails } from "../../../+network-ingresses";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const ingressDetailItemInjectable = getInjectable({
|
||||||
|
id: "ingress-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: IngressDetails,
|
||||||
|
enabled: computed(() => isIngress(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isIngress = kubeObjectMatchesToKindAndApiVersion("Ingress", [
|
||||||
|
"networking.k8s.io/v1",
|
||||||
|
"extensions/v1beta1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default ingressDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { JobDetails } from "../../../+workloads-jobs";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const jobDetailItemInjectable = getInjectable({
|
||||||
|
id: "job-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: JobDetails,
|
||||||
|
enabled: computed(() => isJob(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isJob = kubeObjectMatchesToKindAndApiVersion("Job", ["batch/v1"]);
|
||||||
|
|
||||||
|
export default jobDetailItemInjectable;
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { KubeEventDetails } from "../../../+events/kube-event-details";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { isClusterRole } from "./cluster-role-detail-item.injectable";
|
||||||
|
import { isClusterRoleBinding } from "./cluster-role-binding-detail-item.injectable";
|
||||||
|
import { isCronJob } from "./cron-job-detail-item.injectable";
|
||||||
|
import { isDaemonSet } from "./daemon-set-detail-item.injectable";
|
||||||
|
import { isDeployment } from "./deployment-detail-item.injectable";
|
||||||
|
import { isEndpoint } from "./endpoints-detail-item.injectable";
|
||||||
|
import { isHorizontalPodAutoscaler } from "./horizontal-pod-autoscaler-detail-item.injectable";
|
||||||
|
import { isIngress } from "./ingress-detail-item.injectable";
|
||||||
|
import { isJob } from "./job-detail-item.injectable";
|
||||||
|
import { isNetworkPolicy } from "./network-policy-detail-item.injectable";
|
||||||
|
import { isPersistentVolume } from "./persistent-volume-detail-item.injectable";
|
||||||
|
import { isPersistentVolumeClaim } from "./persistent-volume-claim-detail-item.injectable";
|
||||||
|
import { isNode } from "./node-detail-item.injectable";
|
||||||
|
import { isPod } from "./pod-detail-item.injectable";
|
||||||
|
import { isReplicaSet } from "./replica-set-detail-item.injectable";
|
||||||
|
import { isRole } from "./role-detail-item.injectable";
|
||||||
|
import { isRoleBinding } from "./role-binding-detail-item.injectable";
|
||||||
|
import { isService } from "./service-detail-item.injectable";
|
||||||
|
import { isServiceAccount } from "./service-account-detail-item.injectable";
|
||||||
|
import { isStatefulSet } from "./stateful-set-detail-item.injectable";
|
||||||
|
import { isStorageClass } from "./storage-class-detail-item.injectable";
|
||||||
|
|
||||||
|
const kubeEventDetailItemInjectable = getInjectable({
|
||||||
|
id: "kube-event-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const currentKubeObjectInDetails = di.inject(
|
||||||
|
currentKubeObjectInDetailsInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: KubeEventDetails,
|
||||||
|
|
||||||
|
enabled: computed(() => {
|
||||||
|
const kubeObject = currentKubeObjectInDetails.get();
|
||||||
|
|
||||||
|
if (!kubeObject) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const predicates = [
|
||||||
|
isClusterRole,
|
||||||
|
isClusterRoleBinding,
|
||||||
|
isCronJob,
|
||||||
|
isDaemonSet,
|
||||||
|
isDeployment,
|
||||||
|
isEndpoint,
|
||||||
|
isHorizontalPodAutoscaler,
|
||||||
|
isIngress,
|
||||||
|
isJob,
|
||||||
|
isNetworkPolicy,
|
||||||
|
isNode,
|
||||||
|
isPersistentVolume,
|
||||||
|
isPersistentVolumeClaim,
|
||||||
|
isPod,
|
||||||
|
isReplicaSet,
|
||||||
|
isRole,
|
||||||
|
isRoleBinding,
|
||||||
|
isService,
|
||||||
|
isServiceAccount,
|
||||||
|
isStatefulSet,
|
||||||
|
isStorageClass,
|
||||||
|
];
|
||||||
|
|
||||||
|
return predicates.some((predicate) => predicate(kubeObject));
|
||||||
|
}),
|
||||||
|
|
||||||
|
orderNumber: 355,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeEventDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { LimitRangeDetails } from "../../../+config-limit-ranges";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const limitRangeDetailItemInjectable = getInjectable({
|
||||||
|
id: "limit-range-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: LimitRangeDetails,
|
||||||
|
enabled: computed(() => isLimitRange(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLimitRange = kubeObjectMatchesToKindAndApiVersion("LimitRange", ["v1"]);
|
||||||
|
|
||||||
|
export default limitRangeDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { NamespaceDetails } from "../../../+namespaces";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const namespacesDetailItemInjectable = getInjectable({
|
||||||
|
id: "namespaces-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: NamespaceDetails,
|
||||||
|
enabled: computed(() => isNamespace(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isNamespace = kubeObjectMatchesToKindAndApiVersion("Namespace", ["v1"]);
|
||||||
|
|
||||||
|
export default namespacesDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { NetworkPolicyDetails } from "../../../+network-policies";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const networkPolicyDetailItemInjectable = getInjectable({
|
||||||
|
id: "network-policy-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: NetworkPolicyDetails,
|
||||||
|
enabled: computed(() => isNetworkPolicy(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isNetworkPolicy = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"NetworkPolicy",
|
||||||
|
["networking.k8s.io/v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default networkPolicyDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { NodeDetails } from "../../../+nodes/details";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const nodeDetailItemInjectable = getInjectable({
|
||||||
|
id: "node-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: NodeDetails,
|
||||||
|
enabled: computed(() => isNode(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isNode = kubeObjectMatchesToKindAndApiVersion("Node", ["v1"]);
|
||||||
|
|
||||||
|
export default nodeDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { PersistentVolumeClaimDetails } from "../../../+storage-volume-claims";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const persistentVolumeClaimDetailItemInjectable = getInjectable({
|
||||||
|
id: "persistent-volume-claim-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: PersistentVolumeClaimDetails,
|
||||||
|
enabled: computed(() => isPersistentVolumeClaim(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isPersistentVolumeClaim = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"PersistentVolumeClaim",
|
||||||
|
["v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default persistentVolumeClaimDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { PersistentVolumeDetails } from "../../../+storage-volumes";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const persistentVolumeDetailItemInjectable = getInjectable({
|
||||||
|
id: "persistent-volume-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: PersistentVolumeDetails,
|
||||||
|
enabled: computed(() => isPersistentVolume(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isPersistentVolume = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"PersistentVolume",
|
||||||
|
["v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default persistentVolumeDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { PodDetails } from "../../../+workloads-pods";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const podDetailItemInjectable = getInjectable({
|
||||||
|
id: "pod-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: PodDetails,
|
||||||
|
enabled: computed(() => isPod(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isPod = kubeObjectMatchesToKindAndApiVersion("Pod", ["v1"]);
|
||||||
|
|
||||||
|
export default podDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { PodDisruptionBudgetDetails } from "../../../+config-pod-disruption-budgets";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const podDisruptionBudgetDetailItemInjectable = getInjectable({
|
||||||
|
id: "pod-disruption-budget-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: PodDisruptionBudgetDetails,
|
||||||
|
enabled: computed(() => isPodDisruptionBudget(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isPodDisruptionBudget = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"PodDisruptionBudget",
|
||||||
|
["policy/v1beta1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default podDisruptionBudgetDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { PodSecurityPolicyDetails } from "../../../+pod-security-policies";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const podSecurityPolicyDetailItemInjectable = getInjectable({
|
||||||
|
id: "pod-security-policy-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: PodSecurityPolicyDetails,
|
||||||
|
enabled: computed(() => isPodSecurityPolicy(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isPodSecurityPolicy = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"PodSecurityPolicy",
|
||||||
|
["policy/v1beta1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default podSecurityPolicyDetailItemInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ReplicaSetDetails } from "../../../+workloads-replicasets";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const replicaSetDetailItemInjectable = getInjectable({
|
||||||
|
id: "replica-set-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ReplicaSetDetails,
|
||||||
|
enabled: computed(() => isReplicaSet(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isReplicaSet = kubeObjectMatchesToKindAndApiVersion("ReplicaSet", [
|
||||||
|
"apps/v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default replicaSetDetailItemInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ResourceQuotaDetails } from "../../../+config-resource-quotas";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const resourceQuotaDetailItemInjectable = getInjectable({
|
||||||
|
id: "resource-quota-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ResourceQuotaDetails,
|
||||||
|
enabled: computed(() => isResourceQuota(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isResourceQuota = kubeObjectMatchesToKindAndApiVersion("ResourceQuota", [
|
||||||
|
"v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default resourceQuotaDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { RoleBindingDetails } from "../../../+user-management/+role-bindings";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const roleBindingDetailItemInjectable = getInjectable({
|
||||||
|
id: "role-binding-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: RoleBindingDetails,
|
||||||
|
enabled: computed(() => isRoleBinding(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isRoleBinding = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"RoleBinding",
|
||||||
|
["rbac.authorization.k8s.io/v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default roleBindingDetailItemInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { RoleDetails } from "../../../+user-management/+roles";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const roleDetailItemInjectable = getInjectable({
|
||||||
|
id: "role-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: RoleDetails,
|
||||||
|
enabled: computed(() => isRole(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isRole = kubeObjectMatchesToKindAndApiVersion("Role", [
|
||||||
|
"rbac.authorization.k8s.io/v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default roleDetailItemInjectable;
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { SecretDetails } from "../../../+config-secrets";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const secretsDetailItemInjectable = getInjectable({
|
||||||
|
id: "secrets-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: SecretDetails,
|
||||||
|
enabled: computed(() => isSecret(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isSecret = kubeObjectMatchesToKindAndApiVersion("Secret", ["v1"]);
|
||||||
|
|
||||||
|
export default secretsDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ServiceAccountsDetails } from "../../../+user-management/+service-accounts";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const serviceAccountDetailItemInjectable = getInjectable({
|
||||||
|
id: "service-account-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ServiceAccountsDetails,
|
||||||
|
enabled: computed(() => isServiceAccount(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isServiceAccount = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"ServiceAccount",
|
||||||
|
["v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default serviceAccountDetailItemInjectable;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ServiceDetails } from "../../../+network-services";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const serviceDetailItemInjectable = getInjectable({
|
||||||
|
id: "service-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ServiceDetails,
|
||||||
|
enabled: computed(() => isService(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isService = kubeObjectMatchesToKindAndApiVersion("Service", [
|
||||||
|
"v1",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default serviceDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { StatefulSetDetails } from "../../../+workloads-statefulsets";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const statefulSetDetailItemInjectable = getInjectable({
|
||||||
|
id: "stateful-set-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: StatefulSetDetails,
|
||||||
|
enabled: computed(() => isStatefulSet(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isStatefulSet = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"StatefulSet",
|
||||||
|
["apps/v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default statefulSetDetailItemInjectable;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { StorageClassDetails } from "../../../+storage-classes";
|
||||||
|
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
|
const storageClassDetailItemInjectable = getInjectable({
|
||||||
|
id: "storage-class-detail-item",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: StorageClassDetails,
|
||||||
|
enabled: computed(() => isStorageClass(kubeObject.get())),
|
||||||
|
orderNumber: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isStorageClass = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
"StorageClass",
|
||||||
|
["storage.k8s.io/v1"],
|
||||||
|
);
|
||||||
|
|
||||||
|
export default storageClassDetailItemInjectable;
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
export interface KubeObjectDetailItem {
|
||||||
|
Component: React.ElementType<KubeObjectDetailsProps<any>>;
|
||||||
|
enabled: IComputedValue<boolean>;
|
||||||
|
orderNumber: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const kubeObjectDetailItemInjectionToken = getInjectionToken<KubeObjectDetailItem>({
|
||||||
|
id: "kube-object-detail-item-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import getRandomIdInjectable from "../../../../common/utils/get-random-id.injectable";
|
||||||
|
import type { LensRendererExtension } from "../../../../extensions/lens-renderer-extension";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-item-injection-token";
|
||||||
|
import { extensionRegistratorInjectionToken } from "../../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "../current-kube-object-in-details.injectable";
|
||||||
|
import {
|
||||||
|
kubeObjectMatchesToKindAndApiVersion,
|
||||||
|
} from "./kube-object-matches-to-kind-and-api-version";
|
||||||
|
|
||||||
|
const kubeObjectDetailItemRegistratorInjectable = getInjectable({
|
||||||
|
id: "kube-object-detail-item-registrator",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const getRandomId = di.inject(getRandomIdInjectable);
|
||||||
|
|
||||||
|
const getExtensionShouldBeEnabledForClusterFrame = (
|
||||||
|
extension: LensRendererExtension,
|
||||||
|
) =>
|
||||||
|
di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
|
||||||
|
|
||||||
|
return (ext) => {
|
||||||
|
const extension = ext as LensRendererExtension;
|
||||||
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrame =
|
||||||
|
getExtensionShouldBeEnabledForClusterFrame(extension);
|
||||||
|
|
||||||
|
return extension.kubeObjectDetailItems.map((registration) => {
|
||||||
|
const id = `kube-object-detail-item-registration-from-${
|
||||||
|
extension.sanitizedExtensionId
|
||||||
|
}-${getRandomId()}`;
|
||||||
|
|
||||||
|
const isRelevantKubeObject = kubeObjectMatchesToKindAndApiVersion(
|
||||||
|
registration.kind,
|
||||||
|
registration.apiVersions,
|
||||||
|
);
|
||||||
|
|
||||||
|
return getInjectable({
|
||||||
|
id,
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const kubeObject = di.inject(
|
||||||
|
currentKubeObjectInDetailsInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
kind: registration.kind,
|
||||||
|
apiVersions: registration.apiVersions,
|
||||||
|
Component: registration.components.Details,
|
||||||
|
|
||||||
|
enabled: computed(
|
||||||
|
() =>
|
||||||
|
extensionShouldBeEnabledForClusterFrame.value.get() &&
|
||||||
|
isRelevantKubeObject(kubeObject.get()),
|
||||||
|
),
|
||||||
|
|
||||||
|
orderNumber: 300 - (registration.priority || 50),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectDetailItemRegistratorInjectable;
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { filter, map, sortBy } from "lodash/fp";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-item-injection-token";
|
||||||
|
|
||||||
|
const kubeObjectDetailItemsInjectable = getInjectable({
|
||||||
|
id: "kube-object-detail-items",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const items = computedInjectMany(kubeObjectDetailItemInjectionToken);
|
||||||
|
|
||||||
|
return computed(() => {
|
||||||
|
return pipeline(
|
||||||
|
items.get(),
|
||||||
|
filter((item) => item.enabled.get()),
|
||||||
|
sortBy((item) => item.orderNumber),
|
||||||
|
map((item) => item.Component),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectDetailItemsInjectable;
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
export const kubeObjectMatchesToKindAndApiVersion =
|
||||||
|
(kind: string, apiVersions: string[]) =>
|
||||||
|
<TKubeObject extends KubeObject>(item: TKubeObject | undefined) =>
|
||||||
|
!!item && item.kind === kind && apiVersions.includes(item.apiVersion);
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* 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 { KubeObjectDetailsProps } from "./kube-object-details";
|
||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
export interface KubeObjectDetailComponents<T extends KubeObject = KubeObject> {
|
||||||
|
Details: React.ComponentType<KubeObjectDetailsProps<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KubeObjectDetailRegistration<T extends KubeObject = KubeObject> {
|
||||||
|
kind: string;
|
||||||
|
apiVersions: string[];
|
||||||
|
components: KubeObjectDetailComponents<T>;
|
||||||
|
priority?: number;
|
||||||
|
}
|
||||||
@ -7,13 +7,13 @@ import "./kube-object-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
import { computed, observable, reaction, makeObservable } from "mobx";
|
import { computed, observable, reaction, makeObservable } from "mobx";
|
||||||
import { Drawer } from "../drawer";
|
import { Drawer } from "../drawer";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import { KubeObjectMenu } from "../kube-object-menu";
|
import { KubeObjectMenu } from "../kube-object-menu";
|
||||||
import { KubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
|
||||||
import { CustomResourceDetails } from "../+custom-resources";
|
import { CustomResourceDetails } from "../+custom-resources";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
import type { PageParam } from "../../navigation";
|
import type { PageParam } from "../../navigation";
|
||||||
@ -24,7 +24,8 @@ import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.in
|
|||||||
import customResourceDefinitionStoreInjectable from "../+custom-resources/definition.store.injectable";
|
import customResourceDefinitionStoreInjectable from "../+custom-resources/definition.store.injectable";
|
||||||
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
||||||
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
||||||
|
import kubeObjectDetailItemsInjectable from "./kube-object-detail-items/kube-object-detail-items.injectable";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -32,6 +33,8 @@ export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
|
detailComponents: IComputedValue<React.ElementType[]>;
|
||||||
|
kubeObject: IComputedValue<KubeObject | undefined>;
|
||||||
kubeDetailsUrlParam: PageParam<string>;
|
kubeDetailsUrlParam: PageParam<string>;
|
||||||
apiManager: ApiManager;
|
apiManager: ApiManager;
|
||||||
hideDetails: HideDetails;
|
hideDetails: HideDetails;
|
||||||
@ -53,15 +56,7 @@ class NonInjectedKubeObjectDetails extends React.Component<Dependencies> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@computed get object() {
|
@computed get object() {
|
||||||
try {
|
return this.props.kubeObject.get();
|
||||||
return this.props.apiManager
|
|
||||||
.getStore(this.path)
|
|
||||||
?.getByPath(this.path);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[KUBE-OBJECT-DETAILS]: failed to get store or object: ${error}`, { path: this.path });
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
@ -108,39 +103,40 @@ class NonInjectedKubeObjectDetails extends React.Component<Dependencies> {
|
|||||||
|
|
||||||
renderContents(object: KubeObject) {
|
renderContents(object: KubeObject) {
|
||||||
const { isLoading, loadingError } = this;
|
const { isLoading, loadingError } = this;
|
||||||
const details = KubeObjectDetailRegistry
|
const details = this.props.detailComponents.get();
|
||||||
.getInstance()
|
|
||||||
.getItemsForKind(object.kind, object.apiVersion)
|
|
||||||
.map((item, index) => (
|
|
||||||
<item.components.Details object={object} key={`object-details-${index}`} />
|
|
||||||
));
|
|
||||||
|
|
||||||
if (details.length === 0) {
|
const getContents = () => {
|
||||||
const crd = this.props.customResourceDefinitionStore.getByObject(object);
|
if (details.length === 0) {
|
||||||
|
const crd = this.props.customResourceDefinitionStore.getByObject(object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a fallback so that if a custom resource object doesn't have
|
* This is a fallback so that if a custom resource object doesn't have
|
||||||
* any defined details we should try and display at least some details
|
* any defined details we should try and display at least some details
|
||||||
*/
|
*/
|
||||||
if (crd) {
|
if (crd) {
|
||||||
details.push(<CustomResourceDetails
|
return (
|
||||||
key={object.getId()}
|
<CustomResourceDetails
|
||||||
object={object}
|
key={object.getId()}
|
||||||
crd={crd}
|
object={object}
|
||||||
/>);
|
crd={crd}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// if we still don't have any details to show, just show the standard object metadata
|
||||||
|
return <KubeObjectMeta key={object.getId()} object={object} />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (details.length === 0) {
|
return details.map((DetailComponent, index) => (
|
||||||
// if we still don't have any details to show, just show the standard object metadata
|
<DetailComponent key={index} object={object} />
|
||||||
details.push(<KubeObjectMeta key={object.getId()} object={object} />);
|
));
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isLoading && <Spinner center/>}
|
{isLoading && <Spinner center/>}
|
||||||
{loadingError && <div className="box center">{loadingError}</div>}
|
{loadingError && <div className="box center">{loadingError}</div>}
|
||||||
{details}
|
{getContents()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -169,5 +165,7 @@ export const KubeObjectDetails = withInjectables<Dependencies>(NonInjectedKubeOb
|
|||||||
customResourceDefinitionStore: di.inject(customResourceDefinitionStoreInjectable),
|
customResourceDefinitionStore: di.inject(customResourceDefinitionStoreInjectable),
|
||||||
hideDetails: di.inject(hideDetailsInjectable),
|
hideDetails: di.inject(hideDetailsInjectable),
|
||||||
kubeDetailsUrlParam: di.inject(kubeDetailsUrlParamInjectable),
|
kubeDetailsUrlParam: di.inject(kubeDetailsUrlParamInjectable),
|
||||||
|
detailComponents: di.inject(kubeObjectDetailItemsInjectable),
|
||||||
|
kubeObject: di.inject(currentKubeObjectInDetailsInjectable),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { conforms, includes, eq } from "lodash/fp";
|
|
||||||
import type { KubeObject } from "../../../../../common/k8s-api/kube-object";
|
|
||||||
import type { LensRendererExtension } from "../../../../../extensions/lens-renderer-extension";
|
|
||||||
import { staticKubeObjectMenuItems as staticMenuItems } from "../static-kube-object-menu-items";
|
|
||||||
|
|
||||||
interface Dependencies {
|
|
||||||
extensions: LensRendererExtension[];
|
|
||||||
kubeObject: KubeObject | null | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getKubeObjectMenuItems = ({
|
|
||||||
extensions,
|
|
||||||
kubeObject,
|
|
||||||
}: Dependencies) => {
|
|
||||||
return [
|
|
||||||
...staticMenuItems,
|
|
||||||
...extensions.flatMap((extension) => extension.kubeObjectMenuItems),
|
|
||||||
]
|
|
||||||
.filter(
|
|
||||||
conforms({
|
|
||||||
kind: eq(kubeObject?.kind),
|
|
||||||
apiVersions: includes(kubeObject?.apiVersion),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.map((item) => item.components.MenuItem);
|
|
||||||
};
|
|
||||||
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 { getKubeObjectMenuItems } from "./get-kube-object-menu-items";
|
|
||||||
import type { KubeObject } from "../../../../../common/k8s-api/kube-object";
|
|
||||||
import rendererExtensionsInjectable from "../../../../../extensions/renderer-extensions.injectable";
|
|
||||||
|
|
||||||
const kubeObjectMenuItemsInjectable = getInjectable({
|
|
||||||
id: "kube-object-menu-items",
|
|
||||||
instantiate: (di, { kubeObject }: { kubeObject: KubeObject }) =>
|
|
||||||
getKubeObjectMenuItems({
|
|
||||||
extensions: di.inject(rendererExtensionsInjectable).get(),
|
|
||||||
kubeObject,
|
|
||||||
}),
|
|
||||||
|
|
||||||
lifecycle: lifecycleEnum.transient,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default kubeObjectMenuItemsInjectable;
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { ServiceAccountMenu } from "../../+user-management/+service-accounts/service-account-menu";
|
|
||||||
import { CronJobMenu } from "../../+workloads-cronjobs/cron-job-menu";
|
|
||||||
import { DeploymentMenu } from "../../+workloads-deployments/deployment-menu";
|
|
||||||
import { ReplicaSetMenu } from "../../+workloads-replicasets/replica-set-menu";
|
|
||||||
|
|
||||||
export const staticKubeObjectMenuItems = [
|
|
||||||
{
|
|
||||||
kind: "ServiceAccount",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
MenuItem: ServiceAccountMenu,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "CronJob",
|
|
||||||
apiVersions: ["batch/v1beta1"],
|
|
||||||
components: {
|
|
||||||
MenuItem: CronJobMenu,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "Deployment",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
MenuItem: DeploymentMenu,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "ReplicaSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
MenuItem: ReplicaSetMenu,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import type { KubeObjectMenuProps } from "./kube-object-menu";
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
export type KubeObjectMenuItemComponent = React.ElementType<
|
||||||
|
KubeObjectMenuProps<KubeObject>
|
||||||
|
>;
|
||||||
|
|
||||||
|
export interface KubeObjectMenuItem {
|
||||||
|
kind: string;
|
||||||
|
apiVersions: string[];
|
||||||
|
enabled: IComputedValue<boolean>;
|
||||||
|
Component: KubeObjectMenuItemComponent;
|
||||||
|
orderNumber: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const kubeObjectMenuItemInjectionToken = getInjectionToken<KubeObjectMenuItem>({
|
||||||
|
id: "kube-object-menu-item-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||||
|
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||||
|
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "./kube-object-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const kubeObjectMenuItemRegistratorInjectable = getInjectable({
|
||||||
|
id: "kube-object-menu-item-registrator",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const getRandomId = di.inject(getRandomIdInjectable);
|
||||||
|
|
||||||
|
const getExtensionShouldBeEnabledForClusterFrame = (
|
||||||
|
extension: LensRendererExtension,
|
||||||
|
) =>
|
||||||
|
di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
|
||||||
|
|
||||||
|
return (ext) => {
|
||||||
|
const extension = ext as LensRendererExtension;
|
||||||
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrame =
|
||||||
|
getExtensionShouldBeEnabledForClusterFrame(extension);
|
||||||
|
|
||||||
|
return extension.kubeObjectMenuItems.map((registration) => {
|
||||||
|
const id = `kube-object-menu-item-registration-from-${
|
||||||
|
extension.sanitizedExtensionId
|
||||||
|
}-${getRandomId()}`;
|
||||||
|
|
||||||
|
return getInjectable({
|
||||||
|
id,
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
kind: registration.kind,
|
||||||
|
apiVersions: registration.apiVersions,
|
||||||
|
Component: registration.components.MenuItem,
|
||||||
|
|
||||||
|
enabled: computed(() =>
|
||||||
|
extensionShouldBeEnabledForClusterFrame.value.get(),
|
||||||
|
),
|
||||||
|
|
||||||
|
orderNumber: 100,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectMenuItemRegistratorInjectable;
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* 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 type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "./kube-object-menu-item-injection-token";
|
||||||
|
import { filter, map, sortBy } from "lodash/fp";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
|
||||||
|
const kubeObjectMenuItemsInjectable = getInjectable({
|
||||||
|
id: "kube-object-menu-items",
|
||||||
|
|
||||||
|
instantiate: (di, kubeObject: KubeObject) => {
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const menuItems = computedInjectMany(kubeObjectMenuItemInjectionToken);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
pipeline(
|
||||||
|
menuItems.get(),
|
||||||
|
|
||||||
|
filter(
|
||||||
|
(item) =>
|
||||||
|
item.kind === kubeObject?.kind &&
|
||||||
|
item.apiVersions.includes(kubeObject?.apiVersion) &&
|
||||||
|
item.enabled.get(),
|
||||||
|
),
|
||||||
|
|
||||||
|
sortBy((item) => item.orderNumber),
|
||||||
|
map((item) => item.Component),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, kubeObject: KubeObject) => kubeObject?.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectMenuItemsInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeObjectMenuItemComponent } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { CronJobMenu } from "../../+workloads-cronjobs/cron-job-menu";
|
||||||
|
|
||||||
|
const cronJobMenuInjectable = getInjectable({
|
||||||
|
id: "cron-job-menu-kube-object-menu",
|
||||||
|
|
||||||
|
instantiate: () => ( {
|
||||||
|
kind: "CronJob",
|
||||||
|
apiVersions: ["batch/v1beta1"],
|
||||||
|
Component: CronJobMenu as KubeObjectMenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 20,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default cronJobMenuInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeObjectMenuItemComponent } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { DeploymentMenu } from "../../+workloads-deployments/deployment-menu";
|
||||||
|
|
||||||
|
const deploymentMenuInjectable = getInjectable({
|
||||||
|
id: "deployment-menu-kube-object-menu",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
kind: "Deployment",
|
||||||
|
apiVersions: ["apps/v1"],
|
||||||
|
Component: DeploymentMenu as KubeObjectMenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 30,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default deploymentMenuInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeObjectMenuItemComponent } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { ReplicaSetMenu } from "../../+workloads-replicasets/replica-set-menu";
|
||||||
|
|
||||||
|
const replicaSetMenuInjectable = getInjectable({
|
||||||
|
id: "replica-set-menu-kube-object-menu",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
kind: "ReplicaSet",
|
||||||
|
apiVersions: ["apps/v1"],
|
||||||
|
Component: ReplicaSetMenu as KubeObjectMenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 40,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default replicaSetMenuInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeObjectMenuItemComponent } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "../kube-object-menu-item-injection-token";
|
||||||
|
import { ServiceAccountMenu } from "../../+user-management/+service-accounts/service-account-menu";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const serviceAccountMenuInjectable = getInjectable({
|
||||||
|
id: "service-account-menu-kube-object-menu",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
kind: "ServiceAccount",
|
||||||
|
apiVersions: ["v1"],
|
||||||
|
Component: ServiceAccountMenu as KubeObjectMenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 10,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default serviceAccountMenuInjectable;
|
||||||
@ -8,12 +8,13 @@ import { screen, waitFor } from "@testing-library/react";
|
|||||||
import "@testing-library/jest-dom/extend-expect";
|
import "@testing-library/jest-dom/extend-expect";
|
||||||
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
import { ConfirmDialog } from "../confirm-dialog";
|
import { ConfirmDialog } from "../confirm-dialog";
|
||||||
import type { AsyncFnMock } from "@async-fn/jest";
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
import asyncFn from "@async-fn/jest";
|
import asyncFn from "@async-fn/jest";
|
||||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||||
|
import { computed } from "mobx";
|
||||||
import clusterInjectable from "./dependencies/cluster.injectable";
|
import clusterInjectable from "./dependencies/cluster.injectable";
|
||||||
import type { DiRender } from "../test-utils/renderFor";
|
import type { DiRender } from "../test-utils/renderFor";
|
||||||
import { renderFor } from "../test-utils/renderFor";
|
import { renderFor } from "../test-utils/renderFor";
|
||||||
@ -21,12 +22,9 @@ import type { Cluster } from "../../../common/cluster/cluster";
|
|||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import { KubeObjectMenu } from "./index";
|
import { KubeObjectMenu } from "./index";
|
||||||
import type { KubeObjectMenuRegistration } from "./kube-object-menu-registration";
|
|
||||||
import { computed } from "mobx";
|
|
||||||
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
|
||||||
import createEditResourceTabInjectable from "../dock/edit-resource/edit-resource-tab.injectable";
|
import createEditResourceTabInjectable from "../dock/edit-resource/edit-resource-tab.injectable";
|
||||||
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
||||||
|
import { kubeObjectMenuItemInjectionToken } from "./kube-object-menu-item-injection-token";
|
||||||
|
|
||||||
// TODO: Make tooltips free of side effects by making it deterministic
|
// TODO: Make tooltips free of side effects by making it deterministic
|
||||||
jest.mock("../tooltip/tooltip");
|
jest.mock("../tooltip/tooltip");
|
||||||
@ -35,59 +33,21 @@ jest.mock("../tooltip/withTooltip", () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO: make `animated={false}` not required to make tests deterministic
|
// TODO: make `animated={false}` not required to make tests deterministic
|
||||||
|
|
||||||
class SomeTestExtension extends LensRendererExtension {
|
|
||||||
constructor(
|
|
||||||
kubeObjectMenuItems: KubeObjectMenuRegistration[],
|
|
||||||
) {
|
|
||||||
super({
|
|
||||||
id: "some-id",
|
|
||||||
absolutePath: "irrelevant",
|
|
||||||
isBundled: false,
|
|
||||||
isCompatible: false,
|
|
||||||
isEnabled: false,
|
|
||||||
manifest: { name: "some-id", version: "some-version", engines: { lens: "^5.5.0" }},
|
|
||||||
manifestPath: "irrelevant",
|
|
||||||
});
|
|
||||||
|
|
||||||
this.kubeObjectMenuItems = kubeObjectMenuItems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("kube-object-menu", () => {
|
describe("kube-object-menu", () => {
|
||||||
let di: DiContainer;
|
let di: DiContainer;
|
||||||
let render: DiRender;
|
let render: DiRender;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const MenuItemComponent = () => <li>Some menu item</li>;
|
|
||||||
const someTestExtension = new SomeTestExtension([
|
|
||||||
{
|
|
||||||
apiVersions: ["some-api-version"],
|
|
||||||
kind: "some-kind",
|
|
||||||
components: { MenuItem: MenuItemComponent },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
apiVersions: ["some-unrelated-api-version"],
|
|
||||||
kind: "some-kind",
|
|
||||||
components: { MenuItem: MenuItemComponent },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
apiVersions: ["some-api-version"],
|
|
||||||
kind: "some-unrelated-kind",
|
|
||||||
components: { MenuItem: MenuItemComponent },
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
di = getDiForUnitTesting({ doGeneralOverrides: true });
|
di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
render = renderFor(di);
|
di.register(
|
||||||
|
someMenuItemInjectable,
|
||||||
di.override(rendererExtensionsInjectable, () =>
|
someOtherMenuItemInjectable,
|
||||||
computed(() => [someTestExtension]),
|
someAnotherMenuItemInjectable,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
render = renderFor(di);
|
||||||
|
|
||||||
di.override(
|
di.override(
|
||||||
clusterInjectable,
|
clusterInjectable,
|
||||||
() =>
|
() =>
|
||||||
@ -318,3 +278,47 @@ describe("kube-object-menu", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const MenuItemComponent = () => <li>Some menu item</li>;
|
||||||
|
|
||||||
|
const someMenuItemInjectable = getInjectable({
|
||||||
|
id: "some-menu-item",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
kind: "some-kind",
|
||||||
|
Component: MenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 1,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const someOtherMenuItemInjectable = getInjectable({
|
||||||
|
id: "some-other-menu-item",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
apiVersions: ["some-unrelated-api-version"],
|
||||||
|
kind: "some-kind",
|
||||||
|
Component: MenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 1,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const someAnotherMenuItemInjectable = getInjectable({
|
||||||
|
id: "some-another-menu-item",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
apiVersions: ["some-api-version"],
|
||||||
|
kind: "some-unrelated-kind",
|
||||||
|
Component: MenuItemComponent,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: 1,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectMenuItemInjectionToken,
|
||||||
|
});
|
||||||
|
|||||||
@ -13,13 +13,14 @@ import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
|||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import clusterNameInjectable from "./dependencies/cluster-name.injectable";
|
import clusterNameInjectable from "./dependencies/cluster-name.injectable";
|
||||||
import createEditResourceTabInjectable from "../dock/edit-resource/edit-resource-tab.injectable";
|
import createEditResourceTabInjectable from "../dock/edit-resource/edit-resource-tab.injectable";
|
||||||
import kubeObjectMenuItemsInjectable from "./dependencies/kube-object-menu-items/kube-object-menu-items.injectable";
|
import kubeObjectMenuItemsInjectable from "./kube-object-menu-items.injectable";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import type { HideDetails } from "../kube-detail-params/hide-details.injectable";
|
import type { HideDetails } from "../kube-detail-params/hide-details.injectable";
|
||||||
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
||||||
import type { OnKubeObjectContextMenuOpen } from "./on-context-menu-open.injectable";
|
import type { OnKubeObjectContextMenuOpen } from "./on-context-menu-open.injectable";
|
||||||
import onKubeObjectContextMenuOpenInjectable from "./on-context-menu-open.injectable";
|
import onKubeObjectContextMenuOpenInjectable from "./on-context-menu-open.injectable";
|
||||||
import type { KubeObjectContextMenuItem } from "../../kube-object/handler";
|
import type { KubeObjectContextMenuItem } from "../../kube-object/handler";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
import { observable, runInAction } from "mobx";
|
import { observable, runInAction } from "mobx";
|
||||||
import type { WithConfirmation } from "../confirm-dialog/with-confirm.injectable";
|
import type { WithConfirmation } from "../confirm-dialog/with-confirm.injectable";
|
||||||
import type { Navigate } from "../../navigation/navigate.injectable";
|
import type { Navigate } from "../../navigation/navigate.injectable";
|
||||||
@ -36,7 +37,7 @@ export interface KubeObjectMenuProps<TKubeObject extends KubeObject> extends Men
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
apiManager: ApiManager;
|
apiManager: ApiManager;
|
||||||
kubeObjectMenuItems: React.ElementType[];
|
kubeObjectMenuItems: IComputedValue<React.ElementType[]>;
|
||||||
clusterName: string | undefined;
|
clusterName: string | undefined;
|
||||||
hideDetails: HideDetails;
|
hideDetails: HideDetails;
|
||||||
createEditResourceTab: (kubeObject: KubeObject) => void;
|
createEditResourceTab: (kubeObject: KubeObject) => void;
|
||||||
@ -73,7 +74,7 @@ class NonInjectedKubeObjectMenu<Kube extends KubeObject> extends React.Component
|
|||||||
private renderMenuItems() {
|
private renderMenuItems() {
|
||||||
const { object, toolbar } = this.props;
|
const { object, toolbar } = this.props;
|
||||||
|
|
||||||
return this.props.kubeObjectMenuItems.map((MenuItem, index) => (
|
return this.props.kubeObjectMenuItems.get().map((MenuItem, index) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
object={object}
|
object={object}
|
||||||
toolbar={toolbar}
|
toolbar={toolbar}
|
||||||
@ -206,9 +207,7 @@ export const KubeObjectMenu = withInjectables<Dependencies, KubeObjectMenuProps<
|
|||||||
apiManager: di.inject(apiManagerInjectable),
|
apiManager: di.inject(apiManagerInjectable),
|
||||||
createEditResourceTab: di.inject(createEditResourceTabInjectable),
|
createEditResourceTab: di.inject(createEditResourceTabInjectable),
|
||||||
hideDetails: di.inject(hideDetailsInjectable),
|
hideDetails: di.inject(hideDetailsInjectable),
|
||||||
kubeObjectMenuItems: di.inject(kubeObjectMenuItemsInjectable, {
|
kubeObjectMenuItems: di.inject(kubeObjectMenuItemsInjectable, props.object),
|
||||||
kubeObject: props.object,
|
|
||||||
}),
|
|
||||||
onContextMenuOpen: di.inject(onKubeObjectContextMenuOpenInjectable),
|
onContextMenuOpen: di.inject(onKubeObjectContextMenuOpenInjectable),
|
||||||
navigate: di.inject(navigateInjectable),
|
navigate: di.inject(navigateInjectable),
|
||||||
withConfirmation: di.inject(withConfirmationInjectable),
|
withConfirmation: di.inject(withConfirmationInjectable),
|
||||||
|
|||||||
@ -3,38 +3,29 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
|
||||||
import type { DiRender } from "../test-utils/renderFor";
|
import type { DiRender } from "../test-utils/renderFor";
|
||||||
import { renderFor } from "../test-utils/renderFor";
|
import { renderFor } from "../test-utils/renderFor";
|
||||||
import { computed } from "mobx";
|
import type { KubeObjectStatus } from "../../../common/k8s-api/kube-object-status";
|
||||||
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
|
||||||
import { KubeObjectStatusLevel } from "../../../common/k8s-api/kube-object-status";
|
import { KubeObjectStatusLevel } from "../../../common/k8s-api/kube-object-status";
|
||||||
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
import { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import { KubeObjectStatusIcon } from "./kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "./kube-object-status-icon";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type { KubeObjectStatusRegistration } from "./kube-object-status-registration";
|
import { useFakeTime } from "../../../common/test-utils/use-fake-time";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import { kubeObjectStatusTextInjectionToken } from "./kube-object-status-text-injection-token";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
describe("kube-object-status-icon", () => {
|
describe("kube-object-status-icon", () => {
|
||||||
let render: DiRender;
|
let render: DiRender;
|
||||||
let kubeObjectStatusRegistrations: KubeObjectStatusRegistration[];
|
let di: DiContainer;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// TODO: Make mocking of date in unit tests global
|
useFakeTime("2015-10-21T07:28:00Z");
|
||||||
global.Date.now = () => new Date("2015-10-21T07:28:00Z").getTime();
|
|
||||||
|
|
||||||
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
render = renderFor(di);
|
render = renderFor(di);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations = [];
|
|
||||||
|
|
||||||
const someTestExtension = new SomeTestExtension(
|
|
||||||
kubeObjectStatusRegistrations,
|
|
||||||
);
|
|
||||||
|
|
||||||
di.override(rendererExtensionsInjectable, () =>
|
|
||||||
computed(() => [someTestExtension]),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given no statuses, when rendered, renders as empty", () => {
|
it("given no statuses, when rendered, renders as empty", () => {
|
||||||
@ -48,14 +39,14 @@ describe("kube-object-status-icon", () => {
|
|||||||
it('given level "critical" status, when rendered, renders with status', () => {
|
it('given level "critical" status, when rendered, renders with status', () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = getStatusRegistration(
|
const statusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.CRITICAL,
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
"critical",
|
"critical",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -67,14 +58,14 @@ describe("kube-object-status-icon", () => {
|
|||||||
it('given level "info" status, when rendered, renders with status', () => {
|
it('given level "info" status, when rendered, renders with status', () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = getStatusRegistration(
|
const statusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.INFO,
|
KubeObjectStatusLevel.INFO,
|
||||||
"info",
|
"info",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -86,14 +77,14 @@ describe("kube-object-status-icon", () => {
|
|||||||
it('given level "warning" status, when rendered, renders with status', () => {
|
it('given level "warning" status, when rendered, renders with status', () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = getStatusRegistration(
|
const statusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.WARNING,
|
KubeObjectStatusLevel.WARNING,
|
||||||
"warning",
|
"warning",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -105,30 +96,32 @@ describe("kube-object-status-icon", () => {
|
|||||||
it("given status for all levels is present, when rendered, renders with statuses", () => {
|
it("given status for all levels is present, when rendered, renders with statuses", () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const critical = getStatusRegistration(
|
const criticalStatusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.CRITICAL,
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
"critical",
|
"critical",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
const warning = getStatusRegistration(
|
const warningStatusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.WARNING,
|
KubeObjectStatusLevel.WARNING,
|
||||||
"warning",
|
"warning",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
const info = getStatusRegistration(
|
const infoStatusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.INFO,
|
KubeObjectStatusLevel.INFO,
|
||||||
"info",
|
"info",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(critical);
|
di.register(
|
||||||
kubeObjectStatusRegistrations.push(warning);
|
criticalStatusTextInjectable,
|
||||||
kubeObjectStatusRegistrations.push(info);
|
warningStatusTextInjectable,
|
||||||
|
infoStatusTextInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -140,22 +133,21 @@ describe("kube-object-status-icon", () => {
|
|||||||
it("given info and warning statuses are present, when rendered, renders with statuses", () => {
|
it("given info and warning statuses are present, when rendered, renders with statuses", () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const warning = getStatusRegistration(
|
const warningStatusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.WARNING,
|
KubeObjectStatusLevel.WARNING,
|
||||||
"warning",
|
"warning",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
const info = getStatusRegistration(
|
const infoStatusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.INFO,
|
KubeObjectStatusLevel.INFO,
|
||||||
"info",
|
"info",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(warning);
|
di.register(warningStatusTextInjectable, infoStatusTextInjectable);
|
||||||
kubeObjectStatusRegistrations.push(info);
|
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -168,14 +160,14 @@ describe("kube-object-status-icon", () => {
|
|||||||
it("given registration for wrong api version, when rendered, renders as empty", () => {
|
it("given registration for wrong api version, when rendered, renders as empty", () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = getStatusRegistration(
|
const statusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.CRITICAL,
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
"irrelevant",
|
"irrelevant",
|
||||||
"some-kind",
|
"some-kind",
|
||||||
["some-other-api-version"],
|
["some-other-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -187,14 +179,14 @@ describe("kube-object-status-icon", () => {
|
|||||||
it("given registration for wrong kind, when rendered, renders as empty", () => {
|
it("given registration for wrong kind, when rendered, renders as empty", () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = getStatusRegistration(
|
const statusTextInjectable = getStatusTextInjectable(
|
||||||
KubeObjectStatusLevel.CRITICAL,
|
KubeObjectStatusLevel.CRITICAL,
|
||||||
"irrelevant",
|
"irrelevant",
|
||||||
"some-other-kind",
|
"some-other-kind",
|
||||||
["some-api-version"],
|
["some-api-version"],
|
||||||
);
|
);
|
||||||
|
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
@ -206,21 +198,25 @@ describe("kube-object-status-icon", () => {
|
|||||||
it("given registration without status for exact kube object, when rendered, renders as empty", () => {
|
it("given registration without status for exact kube object, when rendered, renders as empty", () => {
|
||||||
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
const kubeObject = getKubeObjectStub("some-kind", "some-api-version");
|
||||||
|
|
||||||
const statusRegistration = {
|
const statusTextInjectable = getInjectable({
|
||||||
apiVersions: ["some-api-version"],
|
id: "some-id",
|
||||||
kind: "some-kind",
|
instantiate: () => ({
|
||||||
resolve: (): void => {},
|
apiVersions: ["some-api-version"],
|
||||||
};
|
kind: "some-kind",
|
||||||
|
resolve: () => { return undefined as unknown as KubeObjectStatus; },
|
||||||
|
enabled: computed(() => true),
|
||||||
|
}),
|
||||||
|
|
||||||
// @ts-ignore
|
injectionToken: kubeObjectStatusTextInjectionToken,
|
||||||
kubeObjectStatusRegistrations.push(statusRegistration);
|
});
|
||||||
|
|
||||||
|
di.register(statusTextInjectable);
|
||||||
|
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(
|
||||||
<KubeObjectStatusIcon object={kubeObject} />,
|
<KubeObjectStatusIcon object={kubeObject} />,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(baseElement).toMatchSnapshot();
|
expect(baseElement).toMatchSnapshot();
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -236,28 +232,20 @@ const getKubeObjectStub = (kind: string, apiVersion: string) => KubeObject.creat
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const getStatusRegistration = (level: KubeObjectStatusLevel, title: string, kind: string, apiVersions: string[]) => ({
|
const getStatusTextInjectable = (level: KubeObjectStatusLevel, title: string, kind: string, apiVersions: string[]) => getInjectable({
|
||||||
apiVersions,
|
id: title,
|
||||||
kind,
|
instantiate: () => ({
|
||||||
resolve: (kubeObject: KubeObject) => ({
|
apiVersions,
|
||||||
level,
|
kind,
|
||||||
text: `Some ${title} status for ${kubeObject.getName()}`,
|
|
||||||
timestamp: "2015-10-19T07:28:00Z",
|
resolve: (kubeObject: KubeObject) => ({
|
||||||
|
level,
|
||||||
|
text: `Some ${title} status for ${kubeObject.getName()}`,
|
||||||
|
timestamp: "2015-10-19T07:28:00Z",
|
||||||
|
}),
|
||||||
|
|
||||||
|
enabled: computed(() => true),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectStatusTextInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
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", engines: { lens: "^5.5.0" }},
|
|
||||||
manifestPath: "irrelevant",
|
|
||||||
});
|
|
||||||
|
|
||||||
this.kubeObjectStatusTexts = kubeObjectStatusTexts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -9,10 +9,12 @@ import React from "react";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { cssNames, formatDuration, getOrInsert } from "../../utils";
|
import { cssNames, formatDuration, getOrInsert } from "../../utils";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import statusesForKubeObjectInjectable from "./statuses-for-kube-object.injectable";
|
import kubeObjectStatusTextsForObjectInjectable from "./kube-object-status-texts-for-object.injectable";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import type { KubeObjectStatus } from "../../../common/k8s-api/kube-object-status";
|
import type { KubeObjectStatus } from "../../../common/k8s-api/kube-object-status";
|
||||||
import { KubeObjectStatusLevel } from "../../../common/k8s-api/kube-object-status";
|
import { KubeObjectStatusLevel } from "../../../common/k8s-api/kube-object-status";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
function statusClassName(level: KubeObjectStatusLevel): string {
|
function statusClassName(level: KubeObjectStatusLevel): string {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -76,9 +78,10 @@ export interface KubeObjectStatusIconProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
statuses: KubeObjectStatus[];
|
statuses: IComputedValue<KubeObjectStatus[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
class NonInjectedKubeObjectStatusIcon extends React.Component<KubeObjectStatusIconProps & Dependencies> {
|
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);
|
||||||
@ -104,7 +107,7 @@ class NonInjectedKubeObjectStatusIcon extends React.Component<KubeObjectStatusIc
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const statuses = this.props.statuses;
|
const statuses = this.props.statuses.get();
|
||||||
|
|
||||||
if (statuses.length === 0) {
|
if (statuses.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -135,7 +138,7 @@ export const KubeObjectStatusIcon = withInjectables<Dependencies, KubeObjectStat
|
|||||||
|
|
||||||
{
|
{
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
statuses: di.inject(statusesForKubeObjectInjectable, props.object),
|
statuses: di.inject(kubeObjectStatusTextsForObjectInjectable, props.object),
|
||||||
...props,
|
...props,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
import type { KubeObjectStatus } from "../../../common/k8s-api/kube-object-status";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
|
||||||
|
export interface KubeObjectStatusText {
|
||||||
|
kind: string;
|
||||||
|
apiVersions: string[];
|
||||||
|
resolve: (object: KubeObject) => KubeObjectStatus;
|
||||||
|
enabled: IComputedValue<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const kubeObjectStatusTextInjectionToken =
|
||||||
|
getInjectionToken<KubeObjectStatusText>({
|
||||||
|
id: "kube-object-status-text-injection-token",
|
||||||
|
});
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||||
|
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||||
|
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
|
||||||
|
import { kubeObjectStatusTextInjectionToken } from "./kube-object-status-text-injection-token";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const kubeObjectStatusTextRegistratorInjectable = getInjectable({
|
||||||
|
id: "kube-object-status-text-registrator",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const getRandomId = di.inject(getRandomIdInjectable);
|
||||||
|
|
||||||
|
const getExtensionShouldBeEnabledForClusterFrame = (
|
||||||
|
extension: LensRendererExtension,
|
||||||
|
) =>
|
||||||
|
di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
|
||||||
|
|
||||||
|
return (ext) => {
|
||||||
|
const extension = ext as LensRendererExtension;
|
||||||
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrame =
|
||||||
|
getExtensionShouldBeEnabledForClusterFrame(extension);
|
||||||
|
|
||||||
|
return extension.kubeObjectStatusTexts.map((registration) => {
|
||||||
|
const id = `kube-object-status-text-registration-from-${
|
||||||
|
extension.sanitizedExtensionId
|
||||||
|
}-${getRandomId()}`;
|
||||||
|
|
||||||
|
return getInjectable({
|
||||||
|
id,
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
...registration,
|
||||||
|
|
||||||
|
enabled: computed(() =>
|
||||||
|
extensionShouldBeEnabledForClusterFrame.value.get(),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: kubeObjectStatusTextInjectionToken,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectStatusTextRegistratorInjectable;
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* 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 kubeObjectStatusTextsInjectable from "./kube-object-status-texts.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";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
const kubeObjectStatusTextsForObjectInjectable = getInjectable({
|
||||||
|
id: "kube-object-status-texts-for-object",
|
||||||
|
|
||||||
|
instantiate: (di, kubeObject: KubeObject) => {
|
||||||
|
const allStatusTexts = di.inject(kubeObjectStatusTextsInjectable);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
allStatusTexts
|
||||||
|
.get()
|
||||||
|
.filter(toKubeObjectRelated(kubeObject))
|
||||||
|
.map(toStatus(kubeObject))
|
||||||
|
.filter(Boolean),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, kubeObject: KubeObject) => kubeObject.getId(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const toKubeObjectRelated = (kubeObject: KubeObject) =>
|
||||||
|
conforms({
|
||||||
|
kind: eq(kubeObject.kind),
|
||||||
|
apiVersions: includes(kubeObject.apiVersion),
|
||||||
|
});
|
||||||
|
|
||||||
|
const toStatus =
|
||||||
|
(kubeObject: KubeObject) => (item: KubeObjectStatusRegistration) =>
|
||||||
|
item.resolve(kubeObject);
|
||||||
|
|
||||||
|
export default kubeObjectStatusTextsForObjectInjectable;
|
||||||
@ -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 } from "@ogre-tools/injectable";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { kubeObjectStatusTextInjectionToken } from "./kube-object-status-text-injection-token";
|
||||||
|
|
||||||
|
const kubeObjectStatusTextsInjectable = getInjectable({
|
||||||
|
id: "kube-object-status-texts",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const statusTexts = computedInjectMany(kubeObjectStatusTextInjectionToken);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
statusTexts.get().filter((statusText) => statusText.enabled.get()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubeObjectStatusTextsInjectable;
|
||||||
@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { getInjectable } 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),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default statusRegistrationsInjectable;
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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;
|
|
||||||
@ -14,6 +14,7 @@ import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
|
|||||||
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
import { getExtensionRoutePath } from "../../routes/for-extension";
|
import { getExtensionRoutePath } from "../../routes/for-extension";
|
||||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
|
||||||
const extensionSidebarItemRegistratorInjectable = getInjectable({
|
const extensionSidebarItemRegistratorInjectable = getInjectable({
|
||||||
id: "extension-sidebar-item-registrator",
|
id: "extension-sidebar-item-registrator",
|
||||||
@ -22,6 +23,7 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
|
|||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
||||||
const routes = di.inject(routesInjectable);
|
const routes = di.inject(routesInjectable);
|
||||||
|
const extensionShouldBeEnabledForClusterFrame = di.inject(extensionShouldBeEnabledForClusterFrameInjectable, extension);
|
||||||
|
|
||||||
const sidebarItemsForExtensionInjectable = getInjectable({
|
const sidebarItemsForExtensionInjectable = getInjectable({
|
||||||
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}`,
|
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}`,
|
||||||
@ -41,6 +43,18 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
|
|||||||
matches({ path: targetRoutePath }),
|
matches({ path: targetRoutePath }),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isVisible = computed(() => {
|
||||||
|
if (!extensionShouldBeEnabledForClusterFrame.value.get()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registration.visible) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registration.visible.get();
|
||||||
|
});
|
||||||
|
|
||||||
const res: SidebarItemRegistration = {
|
const res: SidebarItemRegistration = {
|
||||||
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
||||||
orderNumber: 9999,
|
orderNumber: 9999,
|
||||||
@ -49,7 +63,7 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
|
|||||||
? `${extension.sanitizedExtensionId}-${registration.parentId}`
|
? `${extension.sanitizedExtensionId}-${registration.parentId}`
|
||||||
: null,
|
: null,
|
||||||
|
|
||||||
...(registration.visible ? { isVisible: registration.visible } : {}),
|
isVisible,
|
||||||
|
|
||||||
title: registration.title,
|
title: registration.title,
|
||||||
getIcon: registration.components.Icon
|
getIcon: registration.components.Icon
|
||||||
|
|||||||
@ -58,6 +58,8 @@ import { renderFor } from "./renderFor";
|
|||||||
import { RootFrame } from "../../frames/root-frame/root-frame";
|
import { RootFrame } from "../../frames/root-frame/root-frame";
|
||||||
import { ClusterFrame } from "../../frames/cluster-frame/cluster-frame";
|
import { ClusterFrame } from "../../frames/cluster-frame/cluster-frame";
|
||||||
import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable";
|
import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable";
|
||||||
|
import activeKubernetesClusterInjectable from "../../cluster-frame-context/active-kubernetes-cluster.injectable";
|
||||||
|
import { catalogEntityFromCluster } from "../../../main/cluster-manager";
|
||||||
|
|
||||||
type Callback = (dis: DiContainers) => void | Promise<void>;
|
type Callback = (dis: DiContainers) => void | Promise<void>;
|
||||||
|
|
||||||
@ -382,6 +384,10 @@ export const getApplicationBuilder = () => {
|
|||||||
accessibleNamespaces: [],
|
accessibleNamespaces: [],
|
||||||
} as unknown as Cluster;
|
} as unknown as Cluster;
|
||||||
|
|
||||||
|
rendererDi.override(activeKubernetesClusterInjectable, () =>
|
||||||
|
computed(() => catalogEntityFromCluster(clusterStub)),
|
||||||
|
);
|
||||||
|
|
||||||
const namespaceStoreStub = {
|
const namespaceStoreStub = {
|
||||||
contextNamespaces: [],
|
contextNamespaces: [],
|
||||||
items: [],
|
items: [],
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* 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 { asyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import type { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
||||||
|
import type { KubernetesCluster } from "../../common/catalog-entities";
|
||||||
|
import extensionIsEnabledForClusterInjectable from "../../extensions/extension-loader/extension-is-enabled-for-cluster.injectable";
|
||||||
|
import activeKubernetesClusterInjectable from "../cluster-frame-context/active-kubernetes-cluster.injectable";
|
||||||
|
import { untracked } from "mobx";
|
||||||
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrameInjectable = getInjectable({
|
||||||
|
id: "extension-should-be-enabled-for-cluster-frame",
|
||||||
|
|
||||||
|
instantiate: (di, extension: LensRendererExtension) => {
|
||||||
|
const activeKubernetesCluster = di.inject(activeKubernetesClusterInjectable);
|
||||||
|
|
||||||
|
const getExtensionIsEnabledForCluster = (
|
||||||
|
extension: LensRendererExtension,
|
||||||
|
cluster: KubernetesCluster,
|
||||||
|
) =>
|
||||||
|
untracked(() => di.inject(extensionIsEnabledForClusterInjectable, { extension, cluster }));
|
||||||
|
|
||||||
|
return asyncComputed(
|
||||||
|
async () => {
|
||||||
|
const cluster = activeKubernetesCluster.get();
|
||||||
|
|
||||||
|
if (!cluster) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getExtensionIsEnabledForCluster(
|
||||||
|
extension,
|
||||||
|
cluster,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, extension: LensRendererExtension) =>
|
||||||
|
extension.sanitizedExtensionId,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default extensionShouldBeEnabledForClusterFrameInjectable;
|
||||||
@ -69,6 +69,8 @@ import kubeObjectDetailsClusterFrameChildComponentInjectable from "./components/
|
|||||||
import kubeconfigDialogClusterFrameChildComponentInjectable from "./components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable";
|
import kubeconfigDialogClusterFrameChildComponentInjectable from "./components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable";
|
||||||
import portForwardDialogClusterFrameChildComponentInjectable from "./port-forward/port-forward-dialog-cluster-frame-child-component.injectable";
|
import portForwardDialogClusterFrameChildComponentInjectable from "./port-forward/port-forward-dialog-cluster-frame-child-component.injectable";
|
||||||
import setupSystemCaInjectable from "./frames/root-frame/setup-system-ca.injectable";
|
import setupSystemCaInjectable from "./frames/root-frame/setup-system-ca.injectable";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "./extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||||
import forceUpdateModalRootFrameComponentInjectable from "./application-update/force-update-modal/force-update-modal-root-frame-component.injectable";
|
import forceUpdateModalRootFrameComponentInjectable from "./application-update/force-update-modal/force-update-modal-root-frame-component.injectable";
|
||||||
|
|
||||||
export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => {
|
export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => {
|
||||||
@ -126,6 +128,11 @@ export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
shouldRender: computed(() => false),
|
shouldRender: computed(() => false),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// TODO: Remove after "LensRendererExtension.isEnabledForCluster" is removed
|
||||||
|
di.override(extensionShouldBeEnabledForClusterFrameInjectable, () =>
|
||||||
|
asyncComputed(async () => true, true),
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: Remove side-effects and shared global state
|
// TODO: Remove side-effects and shared global state
|
||||||
const clusterFrameChildComponentInjectables: Injectable<any, any, any>[] = [
|
const clusterFrameChildComponentInjectables: Injectable<any, any, any>[] = [
|
||||||
commandContainerClusterFrameChildComponentInjectable,
|
commandContainerClusterFrameChildComponentInjectable,
|
||||||
|
|||||||
@ -7,6 +7,5 @@ export * from "./catalog-entity-detail-registry";
|
|||||||
export * from "./catalog";
|
export * from "./catalog";
|
||||||
export * from "./entity-settings-registry";
|
export * from "./entity-settings-registry";
|
||||||
export * from "./ipc";
|
export * from "./ipc";
|
||||||
export * from "./kube-object-detail-registry";
|
|
||||||
export * from "./registries";
|
export * from "./registries";
|
||||||
export * from "./catalog-category-registry";
|
export * from "./catalog-category-registry";
|
||||||
|
|||||||
@ -1,441 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { KubeObjectDetailRegistry } from "../api/kube-object-detail-registry";
|
|
||||||
import type { HpaDetailsProps } from "../components/+config-autoscalers";
|
|
||||||
import { HpaDetails } from "../components/+config-autoscalers";
|
|
||||||
import { LimitRangeDetails } from "../components/+config-limit-ranges";
|
|
||||||
import { ConfigMapDetails } from "../components/+config-maps";
|
|
||||||
import { PodDisruptionBudgetDetails } from "../components/+config-pod-disruption-budgets";
|
|
||||||
import { ResourceQuotaDetails } from "../components/+config-resource-quotas";
|
|
||||||
import { SecretDetails } from "../components/+config-secrets";
|
|
||||||
import { CRDDetails } from "../components/+custom-resources";
|
|
||||||
import { EventDetails } from "../components/+events";
|
|
||||||
import { KubeEventDetails } from "../components/+events/kube-event-details";
|
|
||||||
import { NamespaceDetails } from "../components/+namespaces";
|
|
||||||
import { EndpointsDetails } from "../components/+network-endpoints";
|
|
||||||
import { IngressDetails } from "../components/+network-ingresses";
|
|
||||||
import { NetworkPolicyDetails } from "../components/+network-policies";
|
|
||||||
import { ServiceDetails } from "../components/+network-services";
|
|
||||||
import { NodeDetails } from "../components/+nodes/details";
|
|
||||||
import { PodSecurityPolicyDetails } from "../components/+pod-security-policies";
|
|
||||||
import { StorageClassDetails } from "../components/+storage-classes";
|
|
||||||
import { PersistentVolumeClaimDetails } from "../components/+storage-volume-claims";
|
|
||||||
import { PersistentVolumeDetails } from "../components/+storage-volumes";
|
|
||||||
import { ClusterRoleDetails } from "../components/+user-management/+cluster-roles";
|
|
||||||
import { ClusterRoleBindingDetails } from "../components/+user-management/+cluster-role-bindings";
|
|
||||||
import { RoleDetails } from "../components/+user-management/+roles";
|
|
||||||
import { RoleBindingDetails } from "../components/+user-management/+role-bindings";
|
|
||||||
import { ServiceAccountsDetails } from "../components/+user-management/+service-accounts";
|
|
||||||
import { CronJobDetails } from "../components/+workloads-cronjobs";
|
|
||||||
import { DaemonSetDetails } from "../components/+workloads-daemonsets";
|
|
||||||
import { DeploymentDetails } from "../components/+workloads-deployments";
|
|
||||||
import { JobDetails } from "../components/+workloads-jobs";
|
|
||||||
import { PodDetails } from "../components/+workloads-pods";
|
|
||||||
import { ReplicaSetDetails } from "../components/+workloads-replicasets";
|
|
||||||
import { StatefulSetDetails } from "../components/+workloads-statefulsets";
|
|
||||||
import type { KubeObjectDetailsProps } from "../components/kube-object-details";
|
|
||||||
|
|
||||||
export function initKubeObjectDetailRegistry() {
|
|
||||||
const registry = KubeObjectDetailRegistry.getInstance();
|
|
||||||
|
|
||||||
registry.add({
|
|
||||||
kind: "HorizontalPodAutoscaler",
|
|
||||||
apiVersions: ["autoscaling/v2beta1"],
|
|
||||||
components: {
|
|
||||||
// Note: this line is left in the long form as a validation that this usecase is valid
|
|
||||||
Details: (props: HpaDetailsProps) => <HpaDetails {...props}/>,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "HorizontalPodAutoscaler",
|
|
||||||
apiVersions: ["autoscaling/v2beta1"],
|
|
||||||
components: {
|
|
||||||
// Note: this line is left in the long form as a validation that this usecase is valid
|
|
||||||
Details: (props: HpaDetailsProps) => <HpaDetails {...props}/>,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "HorizontalPodAutoscaler",
|
|
||||||
apiVersions: ["autoscaling/v2beta1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
// Note: this line is left in the long form as a validation that this usecase is valid
|
|
||||||
Details: (props: KubeObjectDetailsProps) => <KubeEventDetails {...props}/>,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "LimitRange",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: LimitRangeDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ConfigMap",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: ConfigMapDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ConfigMap",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PodDisruptionBudget",
|
|
||||||
apiVersions: ["policy/v1beta1"],
|
|
||||||
components: {
|
|
||||||
Details: PodDisruptionBudgetDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ResourceQuota",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: ResourceQuotaDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Secret",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: SecretDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "CustomResourceDefinition",
|
|
||||||
apiVersions: ["apiextensions.k8s.io/v1", "apiextensions.k8s.io/v1beta1"],
|
|
||||||
components: {
|
|
||||||
Details: CRDDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Event",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: EventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Namespace",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: NamespaceDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Endpoints",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: EndpointsDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Endpoints",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Ingress",
|
|
||||||
apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"],
|
|
||||||
components: {
|
|
||||||
Details: IngressDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Ingress",
|
|
||||||
apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "NetworkPolicy",
|
|
||||||
apiVersions: ["networking.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: NetworkPolicyDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "NetworkPolicy",
|
|
||||||
apiVersions: ["networking.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Service",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: ServiceDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Service",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Node",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: NodeDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Node",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PodSecurityPolicy",
|
|
||||||
apiVersions: ["policy/v1beta1"],
|
|
||||||
components: {
|
|
||||||
Details: PodSecurityPolicyDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "StorageClass",
|
|
||||||
apiVersions: ["storage.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: StorageClassDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "StorageClass",
|
|
||||||
apiVersions: ["storage.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PersistentVolumeClaim",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: PersistentVolumeClaimDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PersistentVolumeClaim",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PersistentVolume",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: PersistentVolumeDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "PersistentVolume",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Role",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: RoleDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Role",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ClusterRole",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: ClusterRoleDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ClusterRole",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "RoleBinding",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: RoleBindingDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "RoleBinding",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ClusterRoleBinding",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
components: {
|
|
||||||
Details: ClusterRoleBindingDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ClusterRoleBinding",
|
|
||||||
apiVersions: ["rbac.authorization.k8s.io/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ServiceAccount",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: ServiceAccountsDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ServiceAccount",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "CronJob",
|
|
||||||
apiVersions: ["batch/v1beta1"],
|
|
||||||
components: {
|
|
||||||
Details: CronJobDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "CronJob",
|
|
||||||
apiVersions: ["batch/v1beta1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "DaemonSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
Details: DaemonSetDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "DaemonSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Deployment",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
Details: DeploymentDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Deployment",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Job",
|
|
||||||
apiVersions: ["batch/v1"],
|
|
||||||
components: {
|
|
||||||
Details: JobDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Job",
|
|
||||||
apiVersions: ["batch/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Pod",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
components: {
|
|
||||||
Details: PodDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "Pod",
|
|
||||||
apiVersions: ["v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ReplicaSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
Details: ReplicaSetDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "ReplicaSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "StatefulSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
components: {
|
|
||||||
Details: StatefulSetDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
registry.add({
|
|
||||||
kind: "StatefulSet",
|
|
||||||
apiVersions: ["apps/v1"],
|
|
||||||
priority: 5,
|
|
||||||
components: {
|
|
||||||
Details: KubeEventDetails,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -7,6 +7,5 @@ import * as registries from "../../extensions/registries";
|
|||||||
|
|
||||||
export function initRegistries() {
|
export function initRegistries() {
|
||||||
registries.CatalogEntityDetailRegistry.createInstance();
|
registries.CatalogEntityDetailRegistry.createInstance();
|
||||||
registries.KubeObjectDetailRegistry.createInstance();
|
|
||||||
registries.EntitySettingRegistry.createInstance();
|
registries.EntitySettingRegistry.createInstance();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,11 @@ import { extensionRegistratorInjectionToken } from "../../extensions/extension-l
|
|||||||
import { SiblingsInTabLayout } from "../components/layout/siblings-in-tab-layout";
|
import { SiblingsInTabLayout } from "../components/layout/siblings-in-tab-layout";
|
||||||
import extensionPageParametersInjectable from "./extension-page-parameters.injectable";
|
import extensionPageParametersInjectable from "./extension-page-parameters.injectable";
|
||||||
import { routeSpecificComponentInjectionToken } from "./route-specific-component-injection-token";
|
import { routeSpecificComponentInjectionToken } from "./route-specific-component-injection-token";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
|
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
|
||||||
import { getExtensionRoutePath } from "./for-extension";
|
import { getExtensionRoutePath } from "./for-extension";
|
||||||
|
import extensionShouldBeEnabledForClusterFrameInjectable from "../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
|
|
||||||
const extensionRouteRegistratorInjectable = getInjectable({
|
const extensionRouteRegistratorInjectable = getInjectable({
|
||||||
id: "extension-route-registrator",
|
id: "extension-route-registrator",
|
||||||
@ -24,14 +26,27 @@ const extensionRouteRegistratorInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
return (ext) => {
|
return (ext) => {
|
||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
const toRouteInjectable = toRouteInjectableFor(
|
const toRouteInjectable = toRouteInjectableFor(di, extension);
|
||||||
di,
|
|
||||||
|
const extensionShouldBeEnabledForClusterFrame = di.inject(
|
||||||
|
extensionShouldBeEnabledForClusterFrameInjectable,
|
||||||
extension,
|
extension,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...extension.globalPages.map(toRouteInjectable(false)),
|
...extension.globalPages.map(
|
||||||
...extension.clusterPages.map(toRouteInjectable(true)),
|
toRouteInjectable(
|
||||||
|
false,
|
||||||
|
computed(() => true),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
...extension.clusterPages.map(
|
||||||
|
toRouteInjectable(
|
||||||
|
true,
|
||||||
|
computed(() => extensionShouldBeEnabledForClusterFrame.value.get()),
|
||||||
|
),
|
||||||
|
),
|
||||||
].flat();
|
].flat();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -46,7 +61,7 @@ const toRouteInjectableFor =
|
|||||||
di: DiContainerForInjection,
|
di: DiContainerForInjection,
|
||||||
extension: LensRendererExtension,
|
extension: LensRendererExtension,
|
||||||
) =>
|
) =>
|
||||||
(clusterFrame: boolean) =>
|
(clusterFrame: boolean, isEnabled: IComputedValue<boolean>) =>
|
||||||
(registration: PageRegistration) => {
|
(registration: PageRegistration) => {
|
||||||
const routeInjectable = getInjectable({
|
const routeInjectable = getInjectable({
|
||||||
id: `route-${registration.id}-for-extension-${extension.sanitizedExtensionId}`,
|
id: `route-${registration.id}-for-extension-${extension.sanitizedExtensionId}`,
|
||||||
@ -54,7 +69,7 @@ const toRouteInjectableFor =
|
|||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
path: getExtensionRoutePath(extension, registration.id),
|
path: getExtensionRoutePath(extension, registration.id),
|
||||||
clusterFrame,
|
clusterFrame,
|
||||||
isEnabled: computed(() => true),
|
isEnabled,
|
||||||
extension,
|
extension,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user