Expose a way to reactively control visibility of preference tabs and tray menu items through Extension API (#5789)

This commit is contained in:
Janne Savolainen authored and GitHub committed 2022-07-06 08:51:59 -04:00
1 parent 544bbdc952
commit eb6cc70143
30 files changed
+1295 -194

No files matched your search

@@ -78,6 +78,9 @@ export interface ApplicationBuilder {
enable: EnableExtensions<LensMainExtension>;
disable: DisableExtensions<LensMainExtension>;
};
enable: (...extensions: { renderer: LensRendererExtension; main: LensMainExtension }[]) => void;
disable: (...extensions: { renderer: LensRendererExtension; main: LensMainExtension }[]) => void;
};
allowKubeResource: (resourceName: KubeResource) => ApplicationBuilder;
@@ -234,6 +237,11 @@ export const getApplicationBuilder = () => {
};
};
const enableRendererExtension = enableExtensionsFor(rendererExtensionsState, rendererDi);
const enableMainExtension = enableExtensionsFor(mainExtensionsState, mainDi);
const disableRendererExtension = disableExtensionsFor(rendererExtensionsState, rendererDi);
const disableMainExtension = disableExtensionsFor(mainExtensionsState, mainDi);
const builder: ApplicationBuilder = {
dis,
@@ -400,13 +408,29 @@ export const getApplicationBuilder = () => {
extensions: {
renderer: {
enable: enableExtensionsFor(rendererExtensionsState, rendererDi),
disable: disableExtensionsFor(rendererExtensionsState, rendererDi),
enable: enableRendererExtension,
disable: disableRendererExtension,
},
main: {
enable: enableExtensionsFor(mainExtensionsState, mainDi),
disable: disableExtensionsFor(mainExtensionsState, mainDi),
enable: enableMainExtension,
disable: disableMainExtension,
},
enable: (...extensions) => {
const rendererExtensions = extensions.map(extension => extension.renderer);
const mainExtensions = extensions.map(extension => extension.main);
enableRendererExtension(...rendererExtensions);
enableMainExtension(...mainExtensions);
},
disable: (...extensions) => {
const rendererExtensions = extensions.map(extension => extension.renderer);
const mainExtensions = extensions.map(extension => extension.main);
disableRendererExtension(...rendererExtensions);
disableMainExtension(...mainExtensions);
},
},
@@ -0,0 +1,103 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Mutable } from "type-fest";
import fileSystemProvisionerStoreInjectable from "../../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
import { lensExtensionDependencies } from "../../../extensions/lens-extension";
import type { ApplicationBuilder } from "./get-application-builder";
import { LensMainExtension } from "../../../extensions/lens-main-extension";
import navigateForExtensionInjectable from "../../../main/start-main-application/lens-window/navigate-for-extension.injectable";
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable";
import getExtensionPageParametersInjectable from "../../routes/get-extension-page-parameters.injectable";
import navigateToRouteInjectable from "../../routes/navigate-to-route.injectable";
import routesInjectable from "../../routes/routes.injectable";
import catalogEntityRegistryForMainInjectable from "../../../main/catalog/entity-registry.injectable";
import catalogEntityRegistryForRendererInjectable from "../../api/catalog/entity/registry.injectable";
import type { DiContainer } from "@ogre-tools/injectable";
export class TestExtensionMain extends LensMainExtension {}
export class TestExtensionRenderer extends LensRendererExtension {}
export interface FakeExtensionOptions {
id: string;
name: string;
rendererOptions?: Partial<LensRendererExtension>;
mainOptions?: Partial<LensMainExtension>;
}
export type GetExtensionFake = (arg: FakeExtensionOptions) => {
main: TestExtensionMain;
renderer: TestExtensionRenderer;
};
export const getExtensionFakeFor =
(builder: ApplicationBuilder): GetExtensionFake =>
({ id, name, mainOptions = {}, rendererOptions = {}}) => {
const mainInstance = getExtensionFakeForMain(builder.dis.mainDi, id, name, mainOptions);
const rendererInstance = getExtensionFakeForRenderer(builder.dis.rendererDi, id, name, rendererOptions);
return { main: mainInstance, renderer: rendererInstance };
};
const getExtensionFakeForMain = (di: DiContainer, id: string, name: string, options: Partial<LensMainExtension>) => {
const instance = new TestExtensionMain({
id,
absolutePath: "irrelevant",
isBundled: false,
isCompatible: false,
isEnabled: false,
manifest: {
name,
version: "1.0.0",
engines: {
lens: "^5.5.0",
},
},
manifestPath: "irrelevant",
});
Object.assign(instance, options);
(instance as Mutable<LensMainExtension>)[lensExtensionDependencies] = {
fileSystemProvisionerStore: di.inject(
fileSystemProvisionerStoreInjectable,
),
entityRegistry: di.inject(catalogEntityRegistryForMainInjectable),
navigate: di.inject(navigateForExtensionInjectable),
};
return instance;
};
const getExtensionFakeForRenderer = (di: DiContainer, id: string, name: string, options: Partial<LensRendererExtension>) => {
const instance = new TestExtensionRenderer({
id,
absolutePath: "irrelevant",
isBundled: false,
isCompatible: false,
isEnabled: false,
manifest: {
name,
version: "1.0.0",
engines: {
lens: "^5.5.0",
},
},
manifestPath: "irrelevant",
});
Object.assign(instance, options);
(instance as Mutable<LensRendererExtension>)[lensExtensionDependencies] = {
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
entityRegistry: di.inject(catalogEntityRegistryForRendererInjectable),
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
getExtensionPageParameters: di.inject(getExtensionPageParametersInjectable),
navigateToRoute: di.inject(navigateToRouteInjectable),
routes: di.inject(routesInjectable),
};
return instance;
};
@@ -2,16 +2,10 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Mutable, SetRequired } from "type-fest";
import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable";
import fileSystemProvisionerStoreInjectable from "../../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
import { lensExtensionDependencies } from "../../../extensions/lens-extension";
import type { SetRequired } from "type-fest";
import { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
import getExtensionPageParametersInjectable from "../../routes/get-extension-page-parameters.injectable";
import navigateToRouteInjectable from "../../routes/navigate-to-route.injectable";
import routesInjectable from "../../routes/routes.injectable";
import type { ApplicationBuilder } from "./get-application-builder";
import { getExtensionFakeFor } from "./get-extension-fake";
export class TestExtension extends LensRendererExtension {}
@@ -19,36 +13,16 @@ export type FakeExtensionData = SetRequired<Partial<LensRendererExtension>, "id"
export type GetRendererExtensionFake = (fakeExtensionData: FakeExtensionData) => TestExtension;
export const getRendererExtensionFakeFor = (builder: ApplicationBuilder): GetRendererExtensionFake => (
function getRendererExtensionFake({ id, name, ...rest }) {
const instance = new TestExtension({
export const getRendererExtensionFakeFor = (
builder: ApplicationBuilder,
): GetRendererExtensionFake => {
const getExtensionFake = getExtensionFakeFor(builder);
return ({ id, name, ...rest }) =>
getExtensionFake({
id,
absolutePath: "irrelevant",
isBundled: false,
isCompatible: false,
isEnabled: false,
manifest: {
name,
version: "1.0.0",
engines: {
lens: "^5.5.0",
},
},
manifestPath: "irrelevant",
});
Object.assign(instance, rest);
(instance as Mutable<LensRendererExtension>)[lensExtensionDependencies] = {
categoryRegistry: builder.dis.rendererDi.inject(catalogCategoryRegistryInjectable),
entityRegistry: builder.dis.rendererDi.inject(catalogEntityRegistryInjectable),
fileSystemProvisionerStore: builder.dis.rendererDi.inject(fileSystemProvisionerStoreInjectable),
getExtensionPageParameters: builder.dis.rendererDi.inject(getExtensionPageParametersInjectable),
navigateToRoute: builder.dis.rendererDi.inject(navigateToRouteInjectable),
routes: builder.dis.rendererDi.inject(routesInjectable),
};
return instance;
}
);
name,
rendererOptions: rest,
}).renderer;
};