mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
try and fix behavioural tests
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
6a93ef0358
commit
27ec0573a3
@ -21,6 +21,9 @@ import writeJsonFileInjectable from "../../common/fs/write-json-file.injectable"
|
||||
import pathExistsInjectable from "../../common/fs/path-exists.injectable";
|
||||
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
|
||||
import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import { getSidebarItem } from "../utils";
|
||||
import createStoresAndApisInjectable from "../../renderer/create-stores-apis.injectable";
|
||||
import sidebarStorageInjectable from "../../renderer/components/layout/sidebar-storage/sidebar-storage.injectable";
|
||||
|
||||
describe("cluster - sidebar and tab navigation for core", () => {
|
||||
let applicationBuilder: ApplicationBuilder;
|
||||
@ -33,8 +36,8 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
applicationBuilder = getApplicationBuilder();
|
||||
rendererDi = applicationBuilder.dis.rendererDi;
|
||||
|
||||
rendererDi.override(createStoresAndApisInjectable, () => true);
|
||||
applicationBuilder.setEnvironmentToClusterFrame();
|
||||
|
||||
applicationBuilder.beforeSetups(({ rendererDi }) => {
|
||||
rendererDi.override(
|
||||
directoryForLensLocalStorageInjectable,
|
||||
@ -72,13 +75,13 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent is highlighted", () => {
|
||||
const parent = getSidebarItem(rendered, "some-parent-id");
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("true");
|
||||
expect(parent?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
|
||||
it("child page is shown", () => {
|
||||
@ -101,6 +104,12 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
applicationBuilder.beforeRender(async ({ rendererDi }) => {
|
||||
const sidebarStorage = rendererDi.inject(sidebarStorageInjectable);
|
||||
|
||||
await sidebarStorage.whenReady;
|
||||
console.log({ ...sidebarStorage.get() });
|
||||
});
|
||||
|
||||
rendered = await applicationBuilder.render();
|
||||
});
|
||||
@ -112,13 +121,13 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent sidebar item is not highlighted", () => {
|
||||
const parent = getSidebarItem(rendered, "some-parent-id");
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).not.toBe(null);
|
||||
expect(child).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -148,7 +157,7 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -175,7 +184,7 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -191,13 +200,13 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent sidebar item is not highlighted", () => {
|
||||
const parent = getSidebarItem(rendered, "some-parent-id");
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
|
||||
describe("when a parent sidebar item is expanded", () => {
|
||||
@ -216,13 +225,13 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent sidebar item is not highlighted", () => {
|
||||
const parent = getSidebarItem(rendered, "some-parent-id");
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is expanded", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child).not.toBe(null);
|
||||
expect(child).not.toBeUndefined();
|
||||
});
|
||||
|
||||
describe("when a child of the parent is selected", () => {
|
||||
@ -241,13 +250,13 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
it("parent is highlighted", () => {
|
||||
const parent = getSidebarItem(rendered, "some-parent-id");
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("true");
|
||||
expect(parent?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("child is highlighted", () => {
|
||||
const child = getSidebarItem(rendered, "some-child-id");
|
||||
|
||||
expect(child.dataset.isActiveTest).toBe("true");
|
||||
expect(child?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("child page is shown", () => {
|
||||
@ -288,11 +297,6 @@ describe("cluster - sidebar and tab navigation for core", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const getSidebarItem = (rendered: RenderResult, itemId: string) =>
|
||||
rendered
|
||||
.queryAllByTestId("sidebar-item")
|
||||
.find((x) => x.dataset.idTest === itemId) || null;
|
||||
|
||||
const testSidebarItemsInjectable = getInjectable({
|
||||
id: "some-sidebar-items-injectable",
|
||||
|
||||
@ -325,7 +329,7 @@ const testSidebarItemsInjectable = getInjectable({
|
||||
injectionToken: sidebarItemsInjectionToken,
|
||||
});
|
||||
|
||||
const testRouteInjectable = getInjectable({
|
||||
const testRouteInjectable = getInjectable({
|
||||
id: "some-route-injectable-id",
|
||||
|
||||
instantiate: () => ({
|
||||
|
||||
@ -6,7 +6,7 @@ import React from "react";
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import { fireEvent } from "@testing-library/react";
|
||||
import { getRendererExtensionFake } from "../../renderer/components/test-utils/get-renderer-extension-fake";
|
||||
import type { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
||||
import { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
||||
import directoryForLensLocalStorageInjectable from "../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
||||
import routesInjectable from "../../renderer/routes/routes.injectable";
|
||||
import { matches } from "lodash/fp";
|
||||
@ -17,6 +17,8 @@ import pathExistsInjectable from "../../common/fs/path-exists.injectable";
|
||||
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import assert from "assert";
|
||||
import { getSidebarItem } from "../utils";
|
||||
|
||||
describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
let applicationBuilder: ApplicationBuilder;
|
||||
@ -41,9 +43,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
|
||||
describe("given extension with cluster pages and cluster page menus", () => {
|
||||
beforeEach(async () => {
|
||||
const testExtension = getRendererExtensionFake(
|
||||
extensionStubWithSidebarItems,
|
||||
);
|
||||
const testExtension = getRendererExtensionFake(extensionStubWithSidebarItems);
|
||||
|
||||
await applicationBuilder.addExtensions(testExtension);
|
||||
});
|
||||
@ -51,9 +51,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
describe("given no state for expanded sidebar items exists, and navigated to child sidebar item, when rendered", () => {
|
||||
beforeEach(async () => {
|
||||
applicationBuilder.beforeRender(({ rendererDi }) => {
|
||||
const navigateToRoute = rendererDi.inject(
|
||||
navigateToRouteInjectionToken,
|
||||
);
|
||||
const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken);
|
||||
|
||||
const route = rendererDi
|
||||
.inject(routesInjectable)
|
||||
@ -64,6 +62,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
assert(route);
|
||||
navigateToRoute(route);
|
||||
});
|
||||
|
||||
@ -80,7 +79,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-parent-id",
|
||||
);
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("true");
|
||||
expect(parent?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
@ -89,7 +88,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
|
||||
it("child page is shown", () => {
|
||||
@ -126,7 +125,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-parent-id",
|
||||
);
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is expanded", () => {
|
||||
@ -135,7 +134,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).not.toBe(null);
|
||||
expect(child).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -168,7 +167,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -198,7 +197,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@ -217,7 +216,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-parent-id",
|
||||
);
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is not expanded", () => {
|
||||
@ -226,7 +225,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).toBe(null);
|
||||
expect(child).toBeUndefined();
|
||||
});
|
||||
|
||||
describe("when a parent sidebar item is expanded", () => {
|
||||
@ -248,7 +247,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-parent-id",
|
||||
);
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("false");
|
||||
expect(parent?.dataset.isActiveTest).toBe("false");
|
||||
});
|
||||
|
||||
it("parent sidebar item is expanded", () => {
|
||||
@ -257,7 +256,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child).not.toBe(null);
|
||||
expect(child).not.toBeUndefined();
|
||||
});
|
||||
|
||||
describe("when a child of the parent is selected", () => {
|
||||
@ -279,7 +278,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-parent-id",
|
||||
);
|
||||
|
||||
expect(parent.dataset.isActiveTest).toBe("true");
|
||||
expect(parent?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("child is highlighted", () => {
|
||||
@ -288,7 +287,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
"some-extension-id-some-child-id",
|
||||
);
|
||||
|
||||
expect(child.dataset.isActiveTest).toBe("true");
|
||||
expect(child?.dataset.isActiveTest).toBe("true");
|
||||
});
|
||||
|
||||
it("child page is shown", () => {
|
||||
@ -385,10 +384,8 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
id: "some-extension-id",
|
||||
|
||||
clusterPages: [
|
||||
const extensionStubWithSidebarItems = new (class extends LensRendererExtension {
|
||||
clusterPages = [
|
||||
{
|
||||
components: {
|
||||
Page: () => {
|
||||
@ -396,7 +393,6 @@ const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id: "some-child-page-id",
|
||||
|
||||
@ -404,7 +400,6 @@ const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
Page: () => <div data-testid="some-child-page">Some child page</div>,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id: "some-other-child-page-id",
|
||||
|
||||
@ -414,9 +409,9 @@ const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
clusterPageMenus: [
|
||||
clusterPageMenus = [
|
||||
{
|
||||
id: "some-parent-id",
|
||||
title: "Parent",
|
||||
@ -433,7 +428,7 @@ const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
title: "Child 1",
|
||||
|
||||
components: {
|
||||
Icon: null,
|
||||
Icon: null as never,
|
||||
},
|
||||
},
|
||||
|
||||
@ -444,13 +439,16 @@ const extensionStubWithSidebarItems: Partial<LensRendererExtension> = {
|
||||
title: "Child 2",
|
||||
|
||||
components: {
|
||||
Icon: null,
|
||||
Icon: null as never,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const getSidebarItem = (rendered: RenderResult, itemId: string) =>
|
||||
rendered
|
||||
.queryAllByTestId("sidebar-item")
|
||||
.find((x) => x.dataset.idTest === itemId) || null;
|
||||
];
|
||||
})({
|
||||
absolutePath: "/some/absolute/path",
|
||||
id: "some-extension-id",
|
||||
isBundled: true,
|
||||
isCompatible: true,
|
||||
isEnabled: true,
|
||||
manifest: null as never,
|
||||
manifestPath: "/some/manifest/path",
|
||||
});
|
||||
|
||||
@ -14,6 +14,7 @@ import { routeInjectionToken } from "../../common/front-end-routing/route-inject
|
||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import { getSidebarItem } from "../utils";
|
||||
|
||||
describe("cluster - visibility of sidebar items", () => {
|
||||
let applicationBuilder: ApplicationBuilder;
|
||||
@ -43,7 +44,7 @@ describe("cluster - visibility of sidebar items", () => {
|
||||
it("related sidebar item does not exist", () => {
|
||||
const item = getSidebarItem(rendered, "some-item-id");
|
||||
|
||||
expect(item).toBeNull();
|
||||
expect(item).toBeUndefined();
|
||||
});
|
||||
|
||||
describe("when kube resource becomes allowed", () => {
|
||||
@ -58,17 +59,12 @@ describe("cluster - visibility of sidebar items", () => {
|
||||
it("related sidebar item exists", () => {
|
||||
const item = getSidebarItem(rendered, "some-item-id");
|
||||
|
||||
expect(item).not.toBeNull();
|
||||
expect(item).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const getSidebarItem = (rendered: RenderResult, itemId: string) =>
|
||||
rendered
|
||||
.queryAllByTestId("sidebar-item")
|
||||
.find((x) => x.dataset.idTest === itemId) || null;
|
||||
|
||||
const testRouteInjectable = getInjectable({
|
||||
id: "some-route-injectable-id",
|
||||
|
||||
|
||||
12
src/behaviours/utils.ts
Normal file
12
src/behaviours/utils.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
|
||||
export function getSidebarItem(rendered: RenderResult, itemId: string) {
|
||||
return rendered
|
||||
.queryAllByTestId("sidebar-item")
|
||||
.find((x) => x.dataset.idTest === itemId);
|
||||
}
|
||||
@ -26,9 +26,7 @@ import { Agent } from "https";
|
||||
import type { Patch } from "rfc6902";
|
||||
import assert from "assert";
|
||||
import type { PartialDeep } from "type-fest";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import loggerInjectable from "../logger.injectable";
|
||||
import type { Logger } from "../logger";
|
||||
import logger from "../logger";
|
||||
|
||||
/**
|
||||
* The options used for creating a `KubeApi`
|
||||
@ -330,7 +328,6 @@ export class KubeApi<
|
||||
protected readonly doCheckPreferredVersion: boolean;
|
||||
protected readonly fullApiPathname: string;
|
||||
protected readonly fallbackApiBases: string[] | undefined;
|
||||
protected readonly logger: Logger;
|
||||
|
||||
constructor({
|
||||
objectConstructor,
|
||||
@ -345,12 +342,10 @@ export class KubeApi<
|
||||
assert(request, "request MUST be provided if not in a cluster page frame context");
|
||||
|
||||
const { apiBase, apiPrefix, apiGroup, apiVersion, resource } = parseKubeApi(fullApiPathname);
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
assert(kind, "kind MUST be provied either via KubeApiOptions.kind or KubeApiOptions.objectConstructor.kind");
|
||||
assert(apiPrefix, "apiBase MUST be parsable as a kubeApi selfLink style string");
|
||||
|
||||
this.logger = di.inject(loggerInjectable);
|
||||
this.doCheckPreferredVersion = doCheckPreferredVersion;
|
||||
this.fallbackApiBases = fallbackApiBases;
|
||||
this.fullApiPathname = fullApiPathname;
|
||||
@ -414,7 +409,7 @@ export class KubeApi<
|
||||
return await this.getLatestApiPrefixGroup();
|
||||
} catch (error) {
|
||||
// If valid API wasn't found, log the error and return defaults below
|
||||
this.logger.error(`[KUBE-API]: ${error}`);
|
||||
logger.error(`[KUBE-API]: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,7 +674,7 @@ export class KubeApi<
|
||||
const abortController = new WrappedAbortController(opts.abortController);
|
||||
|
||||
abortController.signal.addEventListener("abort", () => {
|
||||
this.logger.info(`[KUBE-API] watch (${watchId}) aborted ${watchUrl}`);
|
||||
logger.info(`[KUBE-API] watch (${watchId}) aborted ${watchUrl}`);
|
||||
clearTimeout(timedRetry);
|
||||
});
|
||||
|
||||
@ -690,7 +685,7 @@ export class KubeApi<
|
||||
timeout: 600_000,
|
||||
});
|
||||
|
||||
this.logger.info(`[KUBE-API] watch (${watchId}) ${retry === true ? "retried" : "started"} ${watchUrl}`);
|
||||
logger.info(`[KUBE-API] watch (${watchId}) ${retry === true ? "retried" : "started"} ${watchUrl}`);
|
||||
|
||||
responsePromise
|
||||
.then(response => {
|
||||
@ -698,7 +693,7 @@ export class KubeApi<
|
||||
let requestRetried = false;
|
||||
|
||||
if (!response.ok) {
|
||||
this.logger.warn(`[KUBE-API] watch (${watchId}) error response ${watchUrl}`, { status: response.status });
|
||||
logger.warn(`[KUBE-API] watch (${watchId}) error response ${watchUrl}`, { status: response.status });
|
||||
|
||||
return callback(null, response);
|
||||
}
|
||||
@ -715,7 +710,7 @@ export class KubeApi<
|
||||
// Close current request
|
||||
abortController.abort();
|
||||
|
||||
this.logger.info(`[KUBE-API] Watch timeout set, but not retried, retrying now`);
|
||||
logger.info(`[KUBE-API] Watch timeout set, but not retried, retrying now`);
|
||||
|
||||
requestRetried = true;
|
||||
|
||||
@ -734,7 +729,7 @@ export class KubeApi<
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.info(`[KUBE-API] watch (${watchId}) ${eventName} ${watchUrl}`);
|
||||
logger.info(`[KUBE-API] watch (${watchId}) ${eventName} ${watchUrl}`);
|
||||
|
||||
requestRetried = true;
|
||||
|
||||
@ -763,7 +758,7 @@ export class KubeApi<
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
this.logger.error(`[KUBE-API] watch (${watchId}) throwed ${watchUrl}`, error);
|
||||
logger.error(`[KUBE-API] watch (${watchId}) throwed ${watchUrl}`, error);
|
||||
|
||||
callback(null, error);
|
||||
});
|
||||
|
||||
@ -8,7 +8,10 @@
|
||||
// and to `Renderer`
|
||||
|
||||
export { ResourceStack } from "../../common/k8s/resource-stack";
|
||||
export { apiManager } from "../../common/k8s-api/api-manager";
|
||||
import apiManagerInjectable from "../../common/k8s-api/api-manager/manager.injectable";
|
||||
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||
|
||||
export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable);
|
||||
|
||||
export {
|
||||
KubeApi,
|
||||
|
||||
@ -5,15 +5,10 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { noop } from "lodash/fp";
|
||||
import { computed } from "mobx";
|
||||
|
||||
import type {
|
||||
SidebarItemRegistration } from "../layout/sidebar-items.injectable";
|
||||
import {
|
||||
sidebarItemsInjectionToken,
|
||||
} from "../layout/sidebar-items.injectable";
|
||||
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
|
||||
import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable";
|
||||
import { Icon } from "../icon";
|
||||
import React from "react";
|
||||
|
||||
import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable";
|
||||
import sidebarItemsForDefinitionGroupsInjectable from "./sidebar-items-for-definition-groups.injectable";
|
||||
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
|
||||
@ -26,10 +21,7 @@ const customResourceSidebarItemsInjectable = getInjectable({
|
||||
const navigateToCrdList = di.inject(navigateToCrdListInjectable);
|
||||
const crdListRoute = di.inject(crdListRouteInjectable);
|
||||
const crdListRouteIsActive = di.inject(routeIsActiveInjectable, crdListRoute);
|
||||
|
||||
const definitionGroupSidebarItems = di.inject(
|
||||
sidebarItemsForDefinitionGroupsInjectable,
|
||||
);
|
||||
const definitionGroupSidebarItems = di.inject(sidebarItemsForDefinitionGroupsInjectable);
|
||||
|
||||
return computed((): SidebarItemRegistration[] => {
|
||||
const definitionsItem = {
|
||||
@ -42,12 +34,10 @@ const customResourceSidebarItemsInjectable = getInjectable({
|
||||
orderNumber: 10,
|
||||
};
|
||||
|
||||
const definitionGroupItems = definitionGroupSidebarItems.get();
|
||||
|
||||
const childrenAndGrandChildren = [
|
||||
const childrenAndGrandChildren = computed(() => [
|
||||
definitionsItem,
|
||||
...definitionGroupItems,
|
||||
];
|
||||
...definitionGroupSidebarItems.get(),
|
||||
]);
|
||||
|
||||
const parentItem: SidebarItemRegistration = {
|
||||
id: "custom-resources",
|
||||
@ -55,11 +45,11 @@ const customResourceSidebarItemsInjectable = getInjectable({
|
||||
title: "Custom Resources",
|
||||
getIcon: () => <Icon material="extension" />,
|
||||
onClick: noop,
|
||||
isVisible: computed(() => childrenAndGrandChildren.some(item => item.isVisible?.get())),
|
||||
isVisible: computed(() => childrenAndGrandChildren.get().some(item => item.isVisible?.get())),
|
||||
orderNumber: 110,
|
||||
};
|
||||
|
||||
return [parentItem, definitionsItem, ...definitionGroupItems];
|
||||
return [parentItem, definitionsItem, ...definitionGroupSidebarItems.get()];
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -69,15 +69,10 @@ class NonInjectedMainLayout extends React.Component<MainLayoutProps & Dependenci
|
||||
}
|
||||
}
|
||||
|
||||
export const MainLayout = withInjectables<Dependencies, MainLayoutProps>(
|
||||
NonInjectedMainLayout,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const MainLayout = withInjectables<Dependencies, MainLayoutProps>(NonInjectedMainLayout, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -123,13 +123,9 @@ class NonInjectedSidebarItem extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(
|
||||
NonInjectedSidebarItem,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonInjectedSidebarItem, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@ -25,7 +25,6 @@ import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable";
|
||||
import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
|
||||
import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
|
||||
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||
import currentRouteComponentInjectable from "../../routes/current-route-component.injectable";
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { flatMap, compact, join, get, filter } from "lodash/fp";
|
||||
@ -91,7 +90,7 @@ export const getApplicationBuilder = () => {
|
||||
|
||||
rendererDi.override(subscribeStoresInjectable, () => () => () => {});
|
||||
|
||||
const environments: Record<string, Environment> = {
|
||||
const environments = {
|
||||
application: {
|
||||
renderSidebar: () => null,
|
||||
|
||||
@ -100,12 +99,12 @@ export const getApplicationBuilder = () => {
|
||||
"Tried to allow kube resource when environment is not cluster frame.",
|
||||
);
|
||||
},
|
||||
},
|
||||
} as Environment,
|
||||
|
||||
clusterFrame: {
|
||||
renderSidebar: () => <Sidebar />,
|
||||
onAllowKubeResource: () => {},
|
||||
},
|
||||
} as Environment,
|
||||
};
|
||||
|
||||
let environment = environments.application;
|
||||
@ -120,7 +119,7 @@ export const getApplicationBuilder = () => {
|
||||
);
|
||||
|
||||
mainDi.override(mainExtensionsInjectable, () =>
|
||||
computed((): LensMainExtension[] => []),
|
||||
computed(() => []),
|
||||
);
|
||||
|
||||
let allowedResourcesState: IObservableArray<KubeResource>;
|
||||
@ -182,9 +181,7 @@ export const getApplicationBuilder = () => {
|
||||
.map(get("id"));
|
||||
|
||||
throw new Error(
|
||||
`Tried to click navigation item "${id}" which does not exist in preferences. Available IDs are "${availableIds.join(
|
||||
'", "',
|
||||
)}"`,
|
||||
`Tried to click navigation item "${id}" which does not exist in preferences. Available IDs are "${availableIds.join('", "')}"`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -268,12 +265,8 @@ export const getApplicationBuilder = () => {
|
||||
await runSetups();
|
||||
|
||||
const render = renderFor(rendererDi);
|
||||
|
||||
const history = rendererDi.inject(observableHistoryInjectable);
|
||||
|
||||
const currentRouteComponent = rendererDi.inject(
|
||||
currentRouteComponentInjectable,
|
||||
);
|
||||
const currentRouteComponent = rendererDi.inject(currentRouteComponentInjectable);
|
||||
|
||||
for (const callback of beforeRenderCallbacks) {
|
||||
await callback(dis);
|
||||
|
||||
@ -39,20 +39,21 @@ export const createStorage = ({
|
||||
}: Dependencies): CreateStorage => (key, defaultValue) => {
|
||||
const { logPrefix } = StorageHelper;
|
||||
|
||||
console.log("createStorage", { key, defaultValue });
|
||||
|
||||
if (!storage.initialized) {
|
||||
storage.initialized = true;
|
||||
|
||||
(async () => {
|
||||
const filePath = getAbsolutePath(directoryForLensLocalStorage, `${hostedClusterId || "app"}.json`);
|
||||
|
||||
console.log("reading from", filePath);
|
||||
|
||||
try {
|
||||
storage.data = (await readJsonFile(filePath)) as JsonObject;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-empty
|
||||
catch {}
|
||||
|
||||
finally {
|
||||
} catch {
|
||||
// do nothing
|
||||
} finally {
|
||||
if (!isTestEnv) {
|
||||
logger.info(`${logPrefix} loading finished for ${filePath}`);
|
||||
}
|
||||
|
||||
@ -4,18 +4,24 @@
|
||||
*/
|
||||
|
||||
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.)
|
||||
import { action, comparer, computed, makeObservable, observable, toJS, when } from "mobx";
|
||||
import { action, comparer, computed, makeObservable, observable, observe, toJS, when } from "mobx";
|
||||
import type { Draft } from "immer";
|
||||
import { produce, isDraft } from "immer";
|
||||
import { isEqual, isPlainObject } from "lodash";
|
||||
import logger from "../../main/logger";
|
||||
|
||||
export interface StorageChange<T> {
|
||||
key: string;
|
||||
value: T | undefined;
|
||||
oldValue: T | undefined;
|
||||
}
|
||||
|
||||
export interface StorageAdapter<T> {
|
||||
[metadata: string]: any;
|
||||
[metadata: string]: unknown;
|
||||
getItem(key: string): T | Promise<T>;
|
||||
setItem(key: string, value: T): void;
|
||||
removeItem(key: string): void;
|
||||
onChange?(change: { key: string; value: T; oldValue?: T }): void;
|
||||
onChange?(change: StorageChange<T>): void;
|
||||
}
|
||||
|
||||
export interface StorageHelperOptions<T> {
|
||||
@ -61,9 +67,8 @@ export class StorageHelper<T> implements StorageLayer<T> {
|
||||
|
||||
this.storage = storage;
|
||||
|
||||
// TODO: This code uses undocumented MobX internal to criminally permit exotic mutations without encapsulation.
|
||||
this.data.observe_(({ newValue, oldValue }) => {
|
||||
this.onChange(newValue as T, oldValue as T);
|
||||
observe(this.data, (change) => {
|
||||
this.onChange(change.newValue as T | undefined, change.oldValue as T | undefined);
|
||||
});
|
||||
|
||||
if (autoInit) {
|
||||
@ -109,7 +114,7 @@ export class StorageHelper<T> implements StorageLayer<T> {
|
||||
return isEqual(value, this.defaultValue);
|
||||
}
|
||||
|
||||
protected onChange(value: T, oldValue?: T) {
|
||||
protected onChange(value: T | undefined, oldValue: T | undefined) {
|
||||
if (!this.initialized) return;
|
||||
|
||||
try {
|
||||
|
||||
@ -8,46 +8,23 @@ import writeJsonFileInjectable from "../common/fs/write-json-file.injectable";
|
||||
import readJsonFileInjectable from "../common/fs/read-json-file.injectable";
|
||||
import pathExistsInjectable from "../common/fs/path-exists.injectable";
|
||||
|
||||
type Override = (di: DiContainer) => void;
|
||||
|
||||
export const overrideFsWithFakes = (di: DiContainer) => {
|
||||
const state = new Map();
|
||||
|
||||
const readFile = readFileFor(state);
|
||||
|
||||
const overrides: Override[] = [
|
||||
(di) => {
|
||||
di.override(readFileInjectable, () => readFile);
|
||||
},
|
||||
|
||||
(di) => {
|
||||
di.override(
|
||||
writeJsonFileInjectable,
|
||||
() => (filePath, contents) => {
|
||||
state.set(filePath, JSON.stringify(contents));
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
(di) => {
|
||||
di.override(readJsonFileInjectable, () => async (filePath: string) => {
|
||||
const fileContent = await readFile(filePath);
|
||||
|
||||
return JSON.parse(fileContent.toString());
|
||||
});
|
||||
},
|
||||
|
||||
(di) => {
|
||||
di.override(
|
||||
pathExistsInjectable,
|
||||
() => async (filePath: string) => Promise.resolve(state.has(filePath)),
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
overrides.forEach(callback => callback(di));
|
||||
di.override(readFileInjectable, () => readFile);
|
||||
di.override(writeJsonFileInjectable, () => (
|
||||
async (filePath, contents) => {
|
||||
state.set(filePath, JSON.stringify(contents));
|
||||
}
|
||||
));
|
||||
di.override(readJsonFileInjectable, () => (
|
||||
async (filePath: string) => JSON.parse(await readFile(filePath))
|
||||
));
|
||||
di.override(pathExistsInjectable, () => (
|
||||
(filePath: string) => Promise.resolve(state.has(filePath))
|
||||
));
|
||||
};
|
||||
|
||||
const readFileFor = (state: Map<string, string>) => (filePath: string) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user