mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Simplify logic for injecting many instances which can reactively change e.g. based on extension being enabled or disabled (#5662)
* Reorganize stuff to prevent circular dependencies Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Install injectable extension to allow injecting reactively many implementations Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using computedInjectMany over filtering injectMany based on enabled extensions for simplicity Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove await for not being needed Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Sort dependencies alphabetically Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
d0ed4e46b1
commit
f87f5f245c
@ -208,10 +208,11 @@
|
|||||||
"@hapi/subtext": "^7.0.3",
|
"@hapi/subtext": "^7.0.3",
|
||||||
"@kubernetes/client-node": "^0.16.3",
|
"@kubernetes/client-node": "^0.16.3",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"@ogre-tools/fp": "7.1.0",
|
"@ogre-tools/fp": "8.0.0",
|
||||||
"@ogre-tools/injectable": "7.1.0",
|
"@ogre-tools/injectable": "8.0.0",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "7.1.0",
|
"@ogre-tools/injectable-extension-for-auto-registration": "8.0.0",
|
||||||
"@ogre-tools/injectable-react": "7.1.0",
|
"@ogre-tools/injectable-extension-for-mobx": "8.0.0",
|
||||||
|
"@ogre-tools/injectable-react": "8.0.0",
|
||||||
"@sentry/electron": "^3.0.7",
|
"@sentry/electron": "^3.0.7",
|
||||||
"@sentry/integrations": "^6.19.3",
|
"@sentry/integrations": "^6.19.3",
|
||||||
"@side/jest-runtime": "^1.0.0",
|
"@side/jest-runtime": "^1.0.0",
|
||||||
|
|||||||
@ -42,11 +42,11 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("given extension with cluster pages and cluster page menus", () => {
|
describe("given extension with cluster pages and cluster page menus", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(() => {
|
||||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||||
const testExtension = getRendererExtensionFake(extensionStubWithSidebarItems);
|
const testExtension = getRendererExtensionFake(extensionStubWithSidebarItems);
|
||||||
|
|
||||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("given no state for expanded sidebar items exists, and navigated to child sidebar item, when rendered", () => {
|
describe("given no state for expanded sidebar items exists, and navigated to child sidebar item, when rendered", () => {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ describe("extension special characters in page registrations", () => {
|
|||||||
extensionWithPagesHavingSpecialCharacters,
|
extensionWithPagesHavingSpecialCharacters,
|
||||||
);
|
);
|
||||||
|
|
||||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||||
|
|
||||||
rendered = await applicationBuilder.render();
|
rendered = await applicationBuilder.render();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -27,7 +27,7 @@ describe("navigate to extension page", () => {
|
|||||||
extensionWithPagesHavingParameters,
|
extensionWithPagesHavingParameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||||
|
|
||||||
rendered = await applicationBuilder.render();
|
rendered = await applicationBuilder.render();
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,8 @@ import { getApplicationBuilder } from "../renderer/components/test-utils/get-app
|
|||||||
import currentRouteInjectable from "../renderer/routes/current-route.injectable";
|
import currentRouteInjectable from "../renderer/routes/current-route.injectable";
|
||||||
import currentPathInjectable from "../renderer/routes/current-path.injectable";
|
import currentPathInjectable from "../renderer/routes/current-path.injectable";
|
||||||
import queryParametersInjectable from "../renderer/routes/query-parameters.injectable";
|
import queryParametersInjectable from "../renderer/routes/query-parameters.injectable";
|
||||||
import currentPathParametersInjectable from "../renderer/routes/current-path-parameters.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 routePathParametersInjectable from "../renderer/routes/route-path-parameters.injectable";
|
||||||
|
|
||||||
describe("navigating between routes", () => {
|
describe("navigating between routes", () => {
|
||||||
let rendererDi: DiContainer;
|
let rendererDi: DiContainer;
|
||||||
@ -73,7 +73,7 @@ describe("navigating between routes", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not have path parameters", () => {
|
it("does not have path parameters", () => {
|
||||||
const pathParameters = rendererDi.inject(currentPathParametersInjectable);
|
const pathParameters = rendererDi.inject(routePathParametersInjectable, route);
|
||||||
|
|
||||||
expect(pathParameters.get()).toEqual({});
|
expect(pathParameters.get()).toEqual({});
|
||||||
});
|
});
|
||||||
@ -101,7 +101,6 @@ describe("navigating between routes", () => {
|
|||||||
|
|
||||||
describe("given route with optional path parameters", () => {
|
describe("given route with optional path parameters", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
|
||||||
applicationBuilder.beforeApplicationStart(({ rendererDi }) => {
|
applicationBuilder.beforeApplicationStart(({ rendererDi }) => {
|
||||||
rendererDi.register(routeWithOptionalPathParametersInjectable);
|
rendererDi.register(routeWithOptionalPathParametersInjectable);
|
||||||
rendererDi.register(routeWithOptionalPathParametersComponentInjectable);
|
rendererDi.register(routeWithOptionalPathParametersComponentInjectable);
|
||||||
@ -146,7 +145,7 @@ describe("navigating between routes", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("knows path parameters", () => {
|
it("knows path parameters", () => {
|
||||||
const pathParameters = rendererDi.inject(currentPathParametersInjectable);
|
const pathParameters = rendererDi.inject(routePathParametersInjectable, route);
|
||||||
|
|
||||||
expect(pathParameters.get()).toEqual({
|
expect(pathParameters.get()).toEqual({
|
||||||
someParameter: "some-value",
|
someParameter: "some-value",
|
||||||
@ -179,7 +178,7 @@ describe("navigating between routes", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("knows path parameters", () => {
|
it("knows path parameters", () => {
|
||||||
const pathParameters = rendererDi.inject(currentPathParametersInjectable);
|
const pathParameters = rendererDi.inject(routePathParametersInjectable, route);
|
||||||
|
|
||||||
expect(pathParameters.get()).toEqual({
|
expect(pathParameters.get()).toEqual({
|
||||||
someParameter: undefined,
|
someParameter: undefined,
|
||||||
@ -227,10 +226,11 @@ const routeWithOptionalPathParametersComponentInjectable = getInjectable({
|
|||||||
id: "some-route-component",
|
id: "some-route-component",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const pathParameters = di.inject(currentPathParametersInjectable);
|
const route = di.inject(routeWithOptionalPathParametersInjectable);
|
||||||
|
const pathParameters = di.inject(routePathParametersInjectable, route);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
route: di.inject(routeWithOptionalPathParametersInjectable),
|
route,
|
||||||
|
|
||||||
Component: observer(() => (
|
Component: observer(() => (
|
||||||
<pre>{JSON.stringify(pathParameters.get(), null, 2)}</pre>
|
<pre>{JSON.stringify(pathParameters.get(), null, 2)}</pre>
|
||||||
|
|||||||
@ -44,11 +44,11 @@ describe("preferences - navigation to extension specific preferences", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("when extension with specific preferences is enabled", () => {
|
describe("when extension with specific preferences is enabled", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(() => {
|
||||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||||
const testExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
|
const testExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
|
||||||
|
|
||||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders", () => {
|
it("renders", () => {
|
||||||
|
|||||||
@ -29,7 +29,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
let someExtension: SomeTestExtension;
|
let someExtension: SomeTestExtension;
|
||||||
let clickMock: jest.Mock;
|
let clickMock: jest.Mock;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(() => {
|
||||||
clickMock = jest.fn();
|
clickMock = jest.fn();
|
||||||
|
|
||||||
someExtension = new SomeTestExtension({
|
someExtension = new SomeTestExtension({
|
||||||
@ -37,12 +37,12 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
trayMenus: [{ label: "some-label", click: clickMock }],
|
trayMenus: [{ label: "some-label", click: clickMock }],
|
||||||
});
|
});
|
||||||
|
|
||||||
await applicationBuilder.extensions.main.enable(someExtension);
|
applicationBuilder.extensions.main.enable(someExtension);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when item is clicked, triggers the click handler", () => {
|
it("when item is clicked, triggers the click handler", () => {
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
"some-label-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(clickMock).toHaveBeenCalled();
|
expect(clickMock).toHaveBeenCalled();
|
||||||
@ -55,7 +55,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
"some-label-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
clickMock.mockImplementation(() => Promise.reject("some-rejection"));
|
clickMock.mockImplementation(() => Promise.reject("some-rejection"));
|
||||||
|
|
||||||
applicationBuilder.tray.click(
|
applicationBuilder.tray.click(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
"some-label-tray-menu-item-for-extension-some-extension-id",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -90,11 +90,9 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not have the tray menu item from extension", () => {
|
it("does not have the tray menu item from extension", () => {
|
||||||
applicationBuilder.extensions.main.disable(someExtension);
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
applicationBuilder.tray.get(
|
applicationBuilder.tray.get(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
"some-label-tray-menu-item-for-extension-some-extension-id",
|
||||||
),
|
),
|
||||||
).toBeNull();
|
).toBeNull();
|
||||||
});
|
});
|
||||||
@ -105,7 +103,7 @@ describe("clicking tray menu item originating from extension", () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
applicationBuilder.tray.get(
|
applicationBuilder.tray.get(
|
||||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-2",
|
"some-label-tray-menu-item-for-extension-some-extension-id",
|
||||||
),
|
),
|
||||||
).not.toBeNull();
|
).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -28,9 +28,9 @@ describe("multiple separators originating from extension", () => {
|
|||||||
trayMenus: [{ type: "separator" }, { type: "separator" } ],
|
trayMenus: [{ type: "separator" }, { type: "separator" } ],
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(
|
expect(() => {
|
||||||
applicationBuilder.extensions.main.enable(someExtension),
|
applicationBuilder.extensions.main.enable(someExtension);
|
||||||
).resolves.toBeUndefined();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,11 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { ExtensionLoader } from "./extension-loader";
|
import { ExtensionLoader } from "./extension-loader";
|
||||||
import updateExtensionsStateInjectable from "./update-extensions-state/update-extensions-state.injectable";
|
import updateExtensionsStateInjectable from "./update-extensions-state/update-extensions-state.injectable";
|
||||||
import { extensionRegistratorInjectionToken } from "./extension-registrator-injection-token";
|
|
||||||
import extensionInstallationCounterInjectable from "./extension-installation-counter.injectable";
|
import extensionInstallationCounterInjectable from "./extension-installation-counter.injectable";
|
||||||
import { createExtensionInstanceInjectionToken } from "./create-extension-instance.token";
|
import { createExtensionInstanceInjectionToken } from "./create-extension-instance.token";
|
||||||
import extensionInstancesInjectable from "./extension-instances.injectable";
|
import extensionInstancesInjectable from "./extension-instances.injectable";
|
||||||
|
import type { LensExtension } from "../lens-extension";
|
||||||
|
import extensionInjectable from "./extension/extension.injectable";
|
||||||
|
|
||||||
const extensionLoaderInjectable = getInjectable({
|
const extensionLoaderInjectable = getInjectable({
|
||||||
id: "extension-loader",
|
id: "extension-loader",
|
||||||
@ -16,9 +17,9 @@ const extensionLoaderInjectable = getInjectable({
|
|||||||
instantiate: (di) => new ExtensionLoader({
|
instantiate: (di) => new ExtensionLoader({
|
||||||
updateExtensionsState: di.inject(updateExtensionsStateInjectable),
|
updateExtensionsState: di.inject(updateExtensionsStateInjectable),
|
||||||
createExtensionInstance: di.inject(createExtensionInstanceInjectionToken),
|
createExtensionInstance: di.inject(createExtensionInstanceInjectionToken),
|
||||||
extensionRegistrators: di.injectMany(extensionRegistratorInjectionToken),
|
|
||||||
extensionInstallationCounter: di.inject(extensionInstallationCounterInjectable),
|
extensionInstallationCounter: di.inject(extensionInstallationCounterInjectable),
|
||||||
extensionInstances: di.inject(extensionInstancesInjectable),
|
extensionInstances: di.inject(extensionInstancesInjectable),
|
||||||
|
getExtension: (instance: LensExtension) => di.inject(extensionInjectable, instance),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -23,15 +23,16 @@ import { requestExtensionLoaderInitialState } from "../../renderer/ipc";
|
|||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { EventEmitter } from "../../common/event-emitter";
|
import { EventEmitter } from "../../common/event-emitter";
|
||||||
import type { CreateExtensionInstance } from "./create-extension-instance.token";
|
import type { CreateExtensionInstance } from "./create-extension-instance.token";
|
||||||
|
import type { Extension } from "./extension/extension.injectable";
|
||||||
|
|
||||||
const logModule = "[EXTENSIONS-LOADER]";
|
const logModule = "[EXTENSIONS-LOADER]";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
updateExtensionsState: (extensionsState: Record<LensExtensionId, LensExtensionState>) => void;
|
updateExtensionsState: (extensionsState: Record<LensExtensionId, LensExtensionState>) => void;
|
||||||
createExtensionInstance: CreateExtensionInstance;
|
createExtensionInstance: CreateExtensionInstance;
|
||||||
readonly extensionRegistrators: ((extension: LensExtension, extensionInstallationCount: number) => void)[];
|
|
||||||
readonly extensionInstallationCounter: Map<string, number>;
|
readonly extensionInstallationCounter: Map<string, number>;
|
||||||
readonly extensionInstances: ObservableMap<LensExtensionId, LensExtension>;
|
readonly extensionInstances: ObservableMap<LensExtensionId, LensExtension>;
|
||||||
|
getExtension: (instance: LensExtension) => Extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExtensionLoading {
|
export interface ExtensionLoading {
|
||||||
@ -169,6 +170,11 @@ export class ExtensionLoader {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
instance.disable();
|
instance.disable();
|
||||||
|
|
||||||
|
const registeredExtension = this.dependencies.getExtension(instance);
|
||||||
|
|
||||||
|
registeredExtension.deregister();
|
||||||
|
|
||||||
this.onRemoveExtensionId.emit(instance.id);
|
this.onRemoveExtensionId.emit(instance.id);
|
||||||
this.dependencies.extensionInstances.delete(lensExtensionId);
|
this.dependencies.extensionInstances.delete(lensExtensionId);
|
||||||
this.nonInstancesByName.delete(instance.name);
|
this.nonInstancesByName.delete(instance.name);
|
||||||
@ -354,13 +360,9 @@ export class ExtensionLoader {
|
|||||||
);
|
);
|
||||||
|
|
||||||
extensions.forEach(({ instance }) => {
|
extensions.forEach(({ instance }) => {
|
||||||
const installationCount = (this.dependencies.extensionInstallationCounter.get(instance.sanitizedExtensionId) ?? 0) + 1;
|
const getExtension = this.dependencies.getExtension(instance);
|
||||||
|
|
||||||
this.dependencies.extensionInstallationCounter.set(instance.sanitizedExtensionId, installationCount);
|
getExtension.register();
|
||||||
|
|
||||||
this.dependencies.extensionRegistrators.forEach((register) =>
|
|
||||||
register(instance, installationCount),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Return ExtensionLoading[]
|
// Return ExtensionLoading[]
|
||||||
|
|||||||
@ -2,11 +2,12 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* 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 type { Injectable } from "@ogre-tools/injectable";
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { LensExtension } from "../lens-extension";
|
import type { LensExtension } from "../lens-extension";
|
||||||
|
|
||||||
export const extensionRegistratorInjectionToken = getInjectionToken<
|
export const extensionRegistratorInjectionToken = getInjectionToken<
|
||||||
(extension: LensExtension, extensionInstallationCount: number) => void
|
(extension: LensExtension) => Injectable<any, any, any>[]
|
||||||
>({
|
>({
|
||||||
id: "extension-registrator-token",
|
id: "extension-registrator-token",
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* 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 { LensExtension } from "../../lens-extension";
|
||||||
|
import { extensionRegistratorInjectionToken } from "../extension-registrator-injection-token";
|
||||||
|
|
||||||
|
export interface Extension {
|
||||||
|
register: () => void;
|
||||||
|
deregister: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extensionInjectable = getInjectable({
|
||||||
|
id: "extension",
|
||||||
|
|
||||||
|
instantiate: (parentDi, instance: LensExtension): Extension => {
|
||||||
|
const extensionInjectable = getInjectable({
|
||||||
|
id: `extension-${instance.sanitizedExtensionId}`,
|
||||||
|
|
||||||
|
instantiate: (childDi) => {
|
||||||
|
const extensionRegistrators = childDi.injectMany(extensionRegistratorInjectionToken);
|
||||||
|
|
||||||
|
return {
|
||||||
|
register: () => {
|
||||||
|
const injectables = extensionRegistrators.flatMap((getInjectablesOfExtension) =>
|
||||||
|
getInjectablesOfExtension(instance),
|
||||||
|
);
|
||||||
|
|
||||||
|
childDi.register(...injectables);
|
||||||
|
},
|
||||||
|
|
||||||
|
deregister: () => {
|
||||||
|
parentDi.deregister(extensionInjectable);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
parentDi.register(extensionInjectable);
|
||||||
|
|
||||||
|
return parentDi.inject(extensionInjectable);
|
||||||
|
},
|
||||||
|
|
||||||
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
getInstanceKey: (di, extension: LensExtension) => extension,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default extensionInjectable;
|
||||||
@ -2,14 +2,16 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* 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 { createContainer } from "@ogre-tools/injectable";
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
||||||
|
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
|
|
||||||
export const getDi = () => {
|
export const getDi = () => {
|
||||||
const di = createContainer();
|
const di = createContainer();
|
||||||
|
|
||||||
|
registerMobX(di);
|
||||||
|
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
requireContexts: [
|
||||||
|
|||||||
@ -98,6 +98,7 @@ import listHelmReleasesInjectable from "./helm/helm-service/list-helm-releases.i
|
|||||||
import rollbackHelmReleaseInjectable from "./helm/helm-service/rollback-helm-release.injectable";
|
import rollbackHelmReleaseInjectable from "./helm/helm-service/rollback-helm-release.injectable";
|
||||||
import updateHelmReleaseInjectable from "./helm/helm-service/update-helm-release.injectable";
|
import updateHelmReleaseInjectable from "./helm/helm-service/update-helm-release.injectable";
|
||||||
import waitUntilBundledExtensionsAreLoadedInjectable from "./start-main-application/lens-window/application-window/wait-until-bundled-extensions-are-loaded.injectable";
|
import waitUntilBundledExtensionsAreLoadedInjectable from "./start-main-application/lens-window/application-window/wait-until-bundled-extensions-are-loaded.injectable";
|
||||||
|
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
|
||||||
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
|
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
|
||||||
const {
|
const {
|
||||||
@ -106,6 +107,8 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
|
|
||||||
const di = createContainer();
|
const di = createContainer();
|
||||||
|
|
||||||
|
registerMobX(di);
|
||||||
|
|
||||||
setLegacyGlobalDiForExtensionApi(di, Environments.main);
|
setLegacyGlobalDiForExtensionApi(di, Environments.main);
|
||||||
|
|
||||||
for (const filePath of getInjectableFilePaths()) {
|
for (const filePath of getInjectableFilePaths()) {
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
|
||||||
|
|
||||||
export interface TrayMenuItem {
|
export interface TrayMenuItem {
|
||||||
id: string;
|
id: string;
|
||||||
@ -17,7 +16,6 @@ export interface TrayMenuItem {
|
|||||||
click?: () => Promise<void> | void;
|
click?: () => Promise<void> | void;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
separator?: boolean;
|
separator?: boolean;
|
||||||
extension?: LensMainExtension;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const trayMenuItemInjectionToken = getInjectionToken<TrayMenuItem>({
|
export const trayMenuItemInjectionToken = getInjectionToken<TrayMenuItem>({
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* 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 { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
import { flatMap, kebabCase } from "lodash/fp";
|
import { kebabCase } from "lodash/fp";
|
||||||
import type { Injectable } from "@ogre-tools/injectable";
|
import type { Injectable } from "@ogre-tools/injectable";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
@ -20,17 +20,13 @@ import getRandomIdInjectable from "../../../common/utils/get-random-id.injectabl
|
|||||||
const trayMenuItemRegistratorInjectable = getInjectable({
|
const trayMenuItemRegistratorInjectable = getInjectable({
|
||||||
id: "tray-menu-item-registrator",
|
id: "tray-menu-item-registrator",
|
||||||
|
|
||||||
instantiate: (di) => (extension, installationCounter) => {
|
instantiate: (di) => (extension) => {
|
||||||
const mainExtension = extension as LensMainExtension;
|
const mainExtension = extension as LensMainExtension;
|
||||||
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
|
||||||
const getRandomId = di.inject(getRandomIdInjectable);
|
const getRandomId = di.inject(getRandomIdInjectable);
|
||||||
|
|
||||||
pipeline(
|
return mainExtension.trayMenus.flatMap(
|
||||||
mainExtension.trayMenus,
|
toItemInjectablesFor(mainExtension, withErrorLoggingFor, getRandomId),
|
||||||
|
|
||||||
flatMap(toItemInjectablesFor(mainExtension, installationCounter, withErrorLoggingFor, getRandomId)),
|
|
||||||
|
|
||||||
(injectables) => di.register(...injectables),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -39,10 +35,10 @@ const trayMenuItemRegistratorInjectable = getInjectable({
|
|||||||
|
|
||||||
export default trayMenuItemRegistratorInjectable;
|
export default trayMenuItemRegistratorInjectable;
|
||||||
|
|
||||||
const toItemInjectablesFor = (extension: LensMainExtension, installationCounter: number, withErrorLoggingFor: WithErrorLoggingFor, getRandomId: () => string) => {
|
const toItemInjectablesFor = (extension: LensMainExtension, withErrorLoggingFor: WithErrorLoggingFor, getRandomId: () => string) => {
|
||||||
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
const _toItemInjectables = (parentId: string | null) => (registration: TrayMenuRegistration): Injectable<TrayMenuItem, TrayMenuItem, void>[] => {
|
||||||
const trayItemId = registration.id || kebabCase(registration.label || getRandomId());
|
const trayItemId = registration.id || kebabCase(registration.label || getRandomId());
|
||||||
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}-instance-${installationCounter}`;
|
const id = `${trayItemId}-tray-menu-item-for-extension-${extension.sanitizedExtensionId}`;
|
||||||
|
|
||||||
const parentInjectable = getInjectable({
|
const parentInjectable = getInjectable({
|
||||||
id,
|
id,
|
||||||
@ -76,8 +72,6 @@ const toItemInjectablesFor = (extension: LensMainExtension, installationCounter:
|
|||||||
|
|
||||||
enabled: computed(() => registration.enabled ?? true),
|
enabled: computed(() => registration.enabled ?? true),
|
||||||
visible: computed(() => true),
|
visible: computed(() => true),
|
||||||
|
|
||||||
extension,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: trayMenuItemInjectionToken,
|
injectionToken: trayMenuItemInjectionToken,
|
||||||
|
|||||||
@ -3,47 +3,30 @@
|
|||||||
* 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 { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
|
|
||||||
|
|
||||||
import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
|
|
||||||
import type { TrayMenuItem } from "./tray-menu-item-injection-token";
|
|
||||||
import { trayMenuItemInjectionToken } from "./tray-menu-item-injection-token";
|
import { trayMenuItemInjectionToken } from "./tray-menu-item-injection-token";
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
import { filter, overSome, sortBy } from "lodash/fp";
|
import { filter, sortBy } from "lodash/fp";
|
||||||
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
|
||||||
|
|
||||||
const trayMenuItemsInjectable = getInjectable({
|
const trayMenuItemsInjectable = getInjectable({
|
||||||
id: "tray-menu-items",
|
id: "tray-menu-items",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const extensions = di.inject(mainExtensionsInjectable);
|
const computedInjectMany = di.inject(
|
||||||
|
computedInjectManyInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
return computed(() => {
|
const reactiveMenuItems = computedInjectMany(trayMenuItemInjectionToken);
|
||||||
const enabledExtensions = extensions.get();
|
|
||||||
|
|
||||||
return pipeline(
|
return computed(() =>
|
||||||
di.injectMany(trayMenuItemInjectionToken),
|
pipeline(
|
||||||
|
reactiveMenuItems.get(),
|
||||||
filter((item) =>
|
filter((item) => item.visible.get()),
|
||||||
overSome([
|
(items) => sortBy("orderNumber", items),
|
||||||
isNonExtensionItem,
|
),
|
||||||
isEnabledExtensionItemFor(enabledExtensions),
|
);
|
||||||
])(item),
|
|
||||||
),
|
|
||||||
|
|
||||||
filter(item => item.visible.get()),
|
|
||||||
items => sortBy("orderNumber", items),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isNonExtensionItem = (item: TrayMenuItem) => !item.extension;
|
|
||||||
|
|
||||||
const isEnabledExtensionItemFor =
|
|
||||||
(enabledExtensions: LensMainExtension[]) => (item: TrayMenuItem) =>
|
|
||||||
!!enabledExtensions.find((extension) => extension === item.extension);
|
|
||||||
|
|
||||||
|
|
||||||
export default trayMenuItemsInjectable;
|
export default trayMenuItemsInjectable;
|
||||||
|
|||||||
@ -8,10 +8,10 @@ import crdListRouteInjectable from "../../../common/front-end-routing/routes/clu
|
|||||||
import customResourceDefinitionsInjectable from "./custom-resources.injectable";
|
import customResourceDefinitionsInjectable from "./custom-resources.injectable";
|
||||||
import { groupBy, matches, noop, some, toPairs } from "lodash/fp";
|
import { groupBy, matches, noop, some, toPairs } from "lodash/fp";
|
||||||
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable";
|
import customResourcesRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/custom-resources-route.injectable";
|
||||||
import currentPathParametersInjectable from "../../routes/current-path-parameters.injectable";
|
|
||||||
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
|
import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable";
|
||||||
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
|
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
|
||||||
import navigateToCustomResourcesInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/navigate-to-custom-resources.injectable";
|
import navigateToCustomResourcesInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/navigate-to-custom-resources.injectable";
|
||||||
|
import routePathParametersInjectable from "../../routes/route-path-parameters.injectable";
|
||||||
|
|
||||||
const sidebarItemsForDefinitionGroupsInjectable = getInjectable({
|
const sidebarItemsForDefinitionGroupsInjectable = getInjectable({
|
||||||
id: "sidebar-items-for-definition-groups",
|
id: "sidebar-items-for-definition-groups",
|
||||||
@ -24,7 +24,7 @@ const sidebarItemsForDefinitionGroupsInjectable = getInjectable({
|
|||||||
const crdRoute = di.inject(customResourcesRouteInjectable);
|
const crdRoute = di.inject(customResourcesRouteInjectable);
|
||||||
const crdRouteIsActive = di.inject(routeIsActiveInjectable, crdRoute);
|
const crdRouteIsActive = di.inject(routeIsActiveInjectable, crdRoute);
|
||||||
const crdListRoute = di.inject(crdListRouteInjectable);
|
const crdListRoute = di.inject(crdListRouteInjectable);
|
||||||
const pathParameters = di.inject(currentPathParametersInjectable);
|
const pathParameters = di.inject(routePathParametersInjectable, crdRoute);
|
||||||
const navigateToCustomResources = di.inject(navigateToCustomResourcesInjectable);
|
const navigateToCustomResources = di.inject(navigateToCustomResourcesInjectable);
|
||||||
|
|
||||||
return computed((): SidebarItemRegistration[] => {
|
return computed((): SidebarItemRegistration[] => {
|
||||||
|
|||||||
@ -13,10 +13,11 @@ const extensionPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
id: "extension-preference-item-registrator",
|
id: "extension-preference-item-registrator",
|
||||||
|
|
||||||
instantiate:
|
instantiate:
|
||||||
(di) =>
|
() =>
|
||||||
(ext, extensionInstallationCount) => {
|
(ext) => {
|
||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
const injectables = pipeline(
|
|
||||||
|
return pipeline(
|
||||||
extension.appPreferences,
|
extension.appPreferences,
|
||||||
|
|
||||||
filter(
|
filter(
|
||||||
@ -27,13 +28,12 @@ const extensionPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
const id = `extension-preferences-item-${registration.id}-for-extension-${extension.sanitizedExtensionId}`;
|
const id = `extension-preferences-item-${registration.id}-for-extension-${extension.sanitizedExtensionId}`;
|
||||||
|
|
||||||
return getInjectable({
|
return getInjectable({
|
||||||
id: `${id}-for-instance-${extensionInstallationCount}`,
|
id,
|
||||||
injectionToken: extensionPreferenceItemInjectionToken,
|
injectionToken: extensionPreferenceItemInjectionToken,
|
||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: registration.id || id,
|
id: registration.id || id,
|
||||||
title: registration.title,
|
title: registration.title,
|
||||||
extension,
|
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Hint: registration.components.Hint,
|
Hint: registration.components.Hint,
|
||||||
@ -43,10 +43,6 @@ const extensionPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
di.register(...injectables);
|
|
||||||
|
|
||||||
return;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: extensionRegistratorInjectionToken,
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
|||||||
@ -2,19 +2,11 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* 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 { pipeline } from "@ogre-tools/fp";
|
|
||||||
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import { filter, overSome } from "lodash/fp";
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { computed } from "mobx";
|
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
|
||||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
|
||||||
import type { RegisteredAppPreference } from "./app-preferences/app-preference-registration";
|
import type { RegisteredAppPreference } from "./app-preferences/app-preference-registration";
|
||||||
|
|
||||||
interface ExtensionPreferenceItem extends RegisteredAppPreference {
|
export const extensionPreferenceItemInjectionToken = getInjectionToken<RegisteredAppPreference>({
|
||||||
extension: LensRendererExtension;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const extensionPreferenceItemInjectionToken = getInjectionToken<ExtensionPreferenceItem>({
|
|
||||||
id: "extension-preference-item-injection-token",
|
id: "extension-preference-item-injection-token",
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -22,29 +14,10 @@ const extensionsPreferenceItemsInjectable = getInjectable({
|
|||||||
id: "extension-preference-items",
|
id: "extension-preference-items",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const extensions = di.inject(rendererExtensionsInjectable);
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
|
||||||
return computed(() => {
|
return computedInjectMany(extensionPreferenceItemInjectionToken);
|
||||||
const enabledExtensions = extensions.get();
|
|
||||||
|
|
||||||
return pipeline(
|
|
||||||
di.injectMany(extensionPreferenceItemInjectionToken),
|
|
||||||
|
|
||||||
filter((item) =>
|
|
||||||
overSome([
|
|
||||||
isNonExtensionItem,
|
|
||||||
isEnabledExtensionItemFor(enabledExtensions),
|
|
||||||
])(item),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isNonExtensionItem = (item: ExtensionPreferenceItem) => !item.extension;
|
|
||||||
|
|
||||||
const isEnabledExtensionItemFor =
|
|
||||||
(enabledExtensions: LensRendererExtension[]) => (item: ExtensionPreferenceItem) =>
|
|
||||||
!!enabledExtensions.find((extension) => extension === item.extension);
|
|
||||||
|
|
||||||
export default extensionsPreferenceItemsInjectable;
|
export default extensionsPreferenceItemsInjectable;
|
||||||
|
|||||||
@ -13,10 +13,11 @@ const extensionTelemetryPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
id: "extension-telemetry-preference-item-registrator",
|
id: "extension-telemetry-preference-item-registrator",
|
||||||
|
|
||||||
instantiate:
|
instantiate:
|
||||||
(di) =>
|
() =>
|
||||||
(ext, extensionInstallationCount) => {
|
(ext) => {
|
||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
const injectables = pipeline(
|
|
||||||
|
return pipeline(
|
||||||
extension.appPreferences,
|
extension.appPreferences,
|
||||||
|
|
||||||
filter(
|
filter(
|
||||||
@ -27,13 +28,12 @@ const extensionTelemetryPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
const id = `telemetry-preferences-item-${registration.id}-for-extension-${extension.sanitizedExtensionId}`;
|
const id = `telemetry-preferences-item-${registration.id}-for-extension-${extension.sanitizedExtensionId}`;
|
||||||
|
|
||||||
return getInjectable({
|
return getInjectable({
|
||||||
id: `${id}-for-instance-${extensionInstallationCount}`,
|
id,
|
||||||
injectionToken: telemetryPreferenceItemInjectionToken,
|
injectionToken: telemetryPreferenceItemInjectionToken,
|
||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: registration.id || id,
|
id: registration.id || id,
|
||||||
title: registration.title,
|
title: registration.title,
|
||||||
extension,
|
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Hint: registration.components.Hint,
|
Hint: registration.components.Hint,
|
||||||
@ -43,10 +43,6 @@ const extensionTelemetryPreferenceItemRegistratorInjectable = getInjectable({
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
di.register(...injectables);
|
|
||||||
|
|
||||||
return;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: extensionRegistratorInjectionToken,
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
|||||||
@ -3,48 +3,22 @@
|
|||||||
* 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 { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
|
||||||
import { filter, overSome } from "lodash/fp";
|
|
||||||
import { computed } from "mobx";
|
|
||||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
|
||||||
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
|
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
|
||||||
|
|
||||||
export interface ExtensionTelemetryPreferenceRegistration extends AppPreferenceRegistration {
|
export const telemetryPreferenceItemInjectionToken = getInjectionToken<AppPreferenceRegistration>({
|
||||||
extension?: LensRendererExtension;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const telemetryPreferenceItemInjectionToken = getInjectionToken<ExtensionTelemetryPreferenceRegistration>({
|
|
||||||
id: "telemetry-preference-item-injection-token",
|
id: "telemetry-preference-item-injection-token",
|
||||||
});
|
});
|
||||||
|
|
||||||
const telemetryPreferenceItemsInjectable = getInjectable({
|
const telemetryPreferenceItemsInjectable = getInjectable({
|
||||||
id: "telemetry-preference-items",
|
id: "telemetry-preference-items",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const extensions = di.inject(rendererExtensionsInjectable);
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
|
||||||
return computed(() => {
|
return computedInjectMany(telemetryPreferenceItemInjectionToken);
|
||||||
const enabledExtensions = extensions.get();
|
|
||||||
|
|
||||||
return pipeline(
|
|
||||||
di.injectMany(telemetryPreferenceItemInjectionToken),
|
|
||||||
filter((item) =>
|
|
||||||
overSome([
|
|
||||||
isNonExtensionItem,
|
|
||||||
isEnabledExtensionItemFor(enabledExtensions),
|
|
||||||
])(item),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const isNonExtensionItem = (item: ExtensionTelemetryPreferenceRegistration) => !item.extension;
|
|
||||||
|
|
||||||
const isEnabledExtensionItemFor =
|
|
||||||
(enabledExtensions: LensRendererExtension[]) => (item: ExtensionTelemetryPreferenceRegistration) =>
|
|
||||||
!!enabledExtensions.find((extension) => extension === item.extension);
|
|
||||||
|
|
||||||
|
|
||||||
export default telemetryPreferenceItemsInjectable;
|
export default telemetryPreferenceItemsInjectable;
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,13 @@ import { ExtensionSettings } from "./extension-settings";
|
|||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import { Preferences } from "./preferences";
|
import { Preferences } from "./preferences";
|
||||||
import type { ExtensionTelemetryPreferenceRegistration } from "./telemetry-preference-items.injectable";
|
|
||||||
import telemetryPreferenceItemsInjectable from "./telemetry-preference-items.injectable";
|
import telemetryPreferenceItemsInjectable from "./telemetry-preference-items.injectable";
|
||||||
import sentryDnsUrlInjectable from "./sentry-dns-url.injectable";
|
import sentryDnsUrlInjectable from "./sentry-dns-url.injectable";
|
||||||
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
||||||
|
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
telemetryPreferenceItems: IComputedValue<ExtensionTelemetryPreferenceRegistration[]>;
|
telemetryPreferenceItems: IComputedValue<AppPreferenceRegistration[]>;
|
||||||
sentryDnsUrl: string;
|
sentryDnsUrl: string;
|
||||||
userStore: UserStore;
|
userStore: UserStore;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,17 +18,16 @@ import type { LensRendererExtension } from "../../../extensions/lens-renderer-ex
|
|||||||
const extensionSidebarItemRegistratorInjectable = getInjectable({
|
const extensionSidebarItemRegistratorInjectable = getInjectable({
|
||||||
id: "extension-sidebar-item-registrator",
|
id: "extension-sidebar-item-registrator",
|
||||||
|
|
||||||
instantiate: (di) => (ext, extensionInstallationCount) => {
|
instantiate: (di) => (ext) => {
|
||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
|
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
||||||
|
const routes = di.inject(routesInjectable);
|
||||||
|
|
||||||
const sidebarItemsForExtensionInjectable = getInjectable({
|
const sidebarItemsForExtensionInjectable = getInjectable({
|
||||||
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}-instance-${extensionInstallationCount}`,
|
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}`,
|
||||||
injectionToken: sidebarItemsInjectionToken,
|
injectionToken: sidebarItemsInjectionToken,
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
|
||||||
const routes = di.inject(routesInjectable);
|
|
||||||
|
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
const extensionRoutes = routes.get().filter(matches({ extension }));
|
const extensionRoutes = routes.get().filter(matches({ extension }));
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
|
|||||||
|
|
||||||
const res: SidebarItemRegistration = {
|
const res: SidebarItemRegistration = {
|
||||||
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
||||||
extension,
|
|
||||||
orderNumber: 9999,
|
orderNumber: 9999,
|
||||||
|
|
||||||
parentId: registration.parentId
|
parentId: registration.parentId
|
||||||
@ -73,7 +71,9 @@ const extensionSidebarItemRegistratorInjectable = getInjectable({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
di.register(sidebarItemsForExtensionInjectable);
|
return [
|
||||||
|
sidebarItemsForExtensionInjectable,
|
||||||
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: extensionRegistratorInjectionToken,
|
injectionToken: extensionRegistratorInjectionToken,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
|||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import {
|
import {
|
||||||
filter,
|
filter,
|
||||||
flatMap,
|
flatMap,
|
||||||
@ -15,11 +15,8 @@ import {
|
|||||||
isEmpty,
|
isEmpty,
|
||||||
map,
|
map,
|
||||||
orderBy,
|
orderBy,
|
||||||
overSome,
|
|
||||||
some,
|
some,
|
||||||
} from "lodash/fp";
|
} from "lodash/fp";
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
|
||||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
|
||||||
|
|
||||||
export interface SidebarItemRegistration {
|
export interface SidebarItemRegistration {
|
||||||
id: string;
|
id: string;
|
||||||
@ -30,7 +27,6 @@ export interface SidebarItemRegistration {
|
|||||||
isActive?: IComputedValue<boolean>;
|
isActive?: IComputedValue<boolean>;
|
||||||
isVisible?: IComputedValue<boolean>;
|
isVisible?: IComputedValue<boolean>;
|
||||||
orderNumber: number;
|
orderNumber: number;
|
||||||
extension?: LensRendererExtension;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sidebarItemsInjectionToken = getInjectionToken<
|
export const sidebarItemsInjectionToken = getInjectionToken<
|
||||||
@ -47,25 +43,14 @@ const sidebarItemsInjectable = getInjectable({
|
|||||||
id: "sidebar-items",
|
id: "sidebar-items",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const extensions = di.inject(rendererExtensionsInjectable);
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
|
||||||
|
const sidebarItemRegistrations = computedInjectMany(sidebarItemsInjectionToken);
|
||||||
|
|
||||||
return computed((): HierarchicalSidebarItem[] => {
|
return computed((): HierarchicalSidebarItem[] => {
|
||||||
const enabledExtensions = extensions.get();
|
|
||||||
|
|
||||||
const sidebarItemRegistrations = di.injectMany(
|
|
||||||
sidebarItemsInjectionToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
const registrations = pipeline(
|
const registrations = pipeline(
|
||||||
sidebarItemRegistrations,
|
sidebarItemRegistrations.get(),
|
||||||
flatMap(dereference),
|
flatMap(dereference),
|
||||||
|
|
||||||
filter(
|
|
||||||
overSome([
|
|
||||||
isNonExtensionSidebarItem,
|
|
||||||
isEnabledExtensionSidebarItemFor(enabledExtensions),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSidebarItemsHierarchy = (registrations: SidebarItemRegistration[]) => {
|
const getSidebarItemsHierarchy = (registrations: SidebarItemRegistration[]) => {
|
||||||
@ -114,14 +99,6 @@ const sidebarItemsInjectable = getInjectable({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isNonExtensionSidebarItem = (sidebarItem: SidebarItemRegistration) =>
|
|
||||||
!sidebarItem.extension;
|
|
||||||
|
|
||||||
const isEnabledExtensionSidebarItemFor =
|
|
||||||
(enabledExtensions: LensRendererExtension[]) =>
|
|
||||||
(sidebarItem: SidebarItemRegistration) =>
|
|
||||||
!!enabledExtensions.find((x) => x === sidebarItem.extension);
|
|
||||||
|
|
||||||
const dereference = (items: IComputedValue<SidebarItemRegistration[]>) =>
|
const dereference = (items: IComputedValue<SidebarItemRegistration[]>) =>
|
||||||
items.get();
|
items.get();
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||||
import currentlyInClusterFrameInjectable from "../../routes/currently-in-cluster-frame.injectable";
|
import currentlyInClusterFrameInjectable from "../../routes/currently-in-cluster-frame.injectable";
|
||||||
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
|
||||||
import type { IObservableArray, ObservableSet } from "mobx";
|
import type { IObservableArray, ObservableSet } from "mobx";
|
||||||
import { computed, observable, runInAction } from "mobx";
|
import { computed, observable, runInAction } from "mobx";
|
||||||
import { renderFor } from "./renderFor";
|
import { renderFor } from "./renderFor";
|
||||||
@ -60,9 +59,11 @@ import type { LensMainExtension } from "../../../extensions/lens-main-extension"
|
|||||||
import trayMenuItemsInjectable from "../../../main/tray/tray-menu-item/tray-menu-items.injectable";
|
import trayMenuItemsInjectable from "../../../main/tray/tray-menu-item/tray-menu-items.injectable";
|
||||||
import type { LensExtension } from "../../../extensions/lens-extension";
|
import type { LensExtension } from "../../../extensions/lens-extension";
|
||||||
|
|
||||||
|
import extensionInjectable from "../../../extensions/extension-loader/extension/extension.injectable";
|
||||||
|
|
||||||
type Callback = (dis: DiContainers) => void | Promise<void>;
|
type Callback = (dis: DiContainers) => void | Promise<void>;
|
||||||
|
|
||||||
type EnableExtensions<T> = (...extensions: T[]) => Promise<void>;
|
type EnableExtensions<T> = (...extensions: T[]) => void;
|
||||||
type DisableExtensions<T> = (...extensions: T[]) => void;
|
type DisableExtensions<T> = (...extensions: T[]) => void;
|
||||||
|
|
||||||
export interface ApplicationBuilder {
|
export interface ApplicationBuilder {
|
||||||
@ -222,33 +223,26 @@ export const getApplicationBuilder = () => {
|
|||||||
extensionState: T,
|
extensionState: T,
|
||||||
di: DiContainer,
|
di: DiContainer,
|
||||||
) => {
|
) => {
|
||||||
let index = 0;
|
const getExtension = (extension: LensExtension) =>
|
||||||
|
di.inject(extensionInjectable, extension);
|
||||||
|
|
||||||
return async (...extensions: LensExtension[]) => {
|
return (...extensionInstances: LensExtension[]) => {
|
||||||
const extensionRegistrators = di.injectMany(
|
const addAndEnableExtensions = () => {
|
||||||
extensionRegistratorInjectionToken,
|
extensionInstances.forEach(instance => {
|
||||||
);
|
const extension = getExtension(instance);
|
||||||
|
|
||||||
const addAndEnableExtensions = async () => {
|
extension.register();
|
||||||
index++;
|
});
|
||||||
|
|
||||||
const registratorPromises = extensions.flatMap((extension) =>
|
|
||||||
extensionRegistrators.map((registrator) =>
|
|
||||||
registrator(extension, index),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await Promise.all(registratorPromises);
|
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
extensions.forEach((extension) => {
|
extensionInstances.forEach((extension) => {
|
||||||
extensionState.add(extension);
|
extensionState.add(extension);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (rendered) {
|
if (rendered) {
|
||||||
await addAndEnableExtensions();
|
addAndEnableExtensions();
|
||||||
} else {
|
} else {
|
||||||
builder.beforeRender(addAndEnableExtensions);
|
builder.beforeRender(addAndEnableExtensions);
|
||||||
}
|
}
|
||||||
@ -407,12 +401,12 @@ export const getApplicationBuilder = () => {
|
|||||||
extensions: {
|
extensions: {
|
||||||
renderer: {
|
renderer: {
|
||||||
enable: enableExtensionsFor(rendererExtensionsState, rendererDi),
|
enable: enableExtensionsFor(rendererExtensionsState, rendererDi),
|
||||||
disable: disableExtensionsFor(rendererExtensionsState),
|
disable: disableExtensionsFor(rendererExtensionsState, rendererDi),
|
||||||
},
|
},
|
||||||
|
|
||||||
main: {
|
main: {
|
||||||
enable: enableExtensionsFor(mainExtensionsState, mainDi),
|
enable: enableExtensionsFor(mainExtensionsState, mainDi),
|
||||||
disable: disableExtensionsFor(mainExtensionsState),
|
disable: disableExtensionsFor(mainExtensionsState, mainDi),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -538,13 +532,22 @@ function toFlatChildren(parentId: string | null | undefined): ToFlatChildren {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const disableExtensionsFor =
|
const disableExtensionsFor = <T extends ObservableSet>(
|
||||||
<T extends ObservableSet>(extensionState: T) =>
|
extensionState: T,
|
||||||
|
di: DiContainer,
|
||||||
|
) => {
|
||||||
|
const getExtension = (instance: LensExtension) =>
|
||||||
|
di.inject(extensionInjectable, instance);
|
||||||
|
|
||||||
(...extensions: LensExtension[]) => {
|
return (...extensionInstances: LensExtension[]) => {
|
||||||
extensions.forEach((extension) => {
|
extensionInstances.forEach((instance) => {
|
||||||
runInAction(() => {
|
const extension = getExtension(instance);
|
||||||
extensionState.delete(extension);
|
|
||||||
});
|
extension.deregister();
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
extensionState.delete(extension);
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
import { createContainer } from "@ogre-tools/injectable";
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
||||||
|
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
|
|
||||||
export const getDi = () => {
|
export const getDi = () => {
|
||||||
const di = createContainer();
|
const di = createContainer();
|
||||||
|
|
||||||
|
registerMobX(di);
|
||||||
|
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
requireContexts: [
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import getFilePathsInjectable from "./components/+preferences/kubernetes/helm-ch
|
|||||||
import callForPublicHelmRepositoriesInjectable from "./components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
|
import callForPublicHelmRepositoriesInjectable from "./components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
|
||||||
import platformInjectable from "../common/vars/platform.injectable";
|
import platformInjectable from "../common/vars/platform.injectable";
|
||||||
import startTopbarStateSyncInjectable from "./components/layout/top-bar/start-state-sync.injectable";
|
import startTopbarStateSyncInjectable from "./components/layout/top-bar/start-state-sync.injectable";
|
||||||
|
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
|
||||||
export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => {
|
export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => {
|
||||||
const {
|
const {
|
||||||
@ -59,6 +60,8 @@ export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
|
|
||||||
const di = createContainer();
|
const di = createContainer();
|
||||||
|
|
||||||
|
registerMobX(di);
|
||||||
|
|
||||||
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
|
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
|
||||||
|
|
||||||
for (const filePath of getInjectableFilePaths()) {
|
for (const filePath of getInjectableFilePaths()) {
|
||||||
|
|||||||
@ -1,40 +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 { overSome } from "lodash/fp";
|
|
||||||
import { computed } from "mobx";
|
|
||||||
import rendererExtensionsInjectable from "../../extensions/renderer-extensions.injectable";
|
|
||||||
import type { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
|
||||||
import type { Route } from "../../common/front-end-routing/front-end-route-injection-token";
|
|
||||||
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
|
|
||||||
|
|
||||||
const allRoutesInjectable = getInjectable({
|
|
||||||
id: "all-routes",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const extensions = di.inject(rendererExtensionsInjectable);
|
|
||||||
|
|
||||||
return computed(() => {
|
|
||||||
const enabledExtensions = extensions.get();
|
|
||||||
|
|
||||||
return di
|
|
||||||
.injectMany(frontEndRouteInjectionToken)
|
|
||||||
.filter((route) =>
|
|
||||||
overSome([
|
|
||||||
isNonExtensionRoute,
|
|
||||||
isEnabledExtensionRouteFor(enabledExtensions),
|
|
||||||
])(route),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isNonExtensionRoute = (route: Route<unknown>) => !route.extension;
|
|
||||||
|
|
||||||
const isEnabledExtensionRouteFor =
|
|
||||||
(enabledExtensions: LensRendererExtension[]) => (route: Route<unknown>) =>
|
|
||||||
!!enabledExtensions.find((x) => x === route.extension);
|
|
||||||
|
|
||||||
export default allRoutesInjectable;
|
|
||||||
@ -1,23 +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 matchingRouteInjectable from "./matching-route.injectable";
|
|
||||||
|
|
||||||
const currentPathParametersInjectable = getInjectable({
|
|
||||||
id: "current-path-parameters",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const matchingRoute = di.inject(matchingRouteInjectable);
|
|
||||||
|
|
||||||
return computed((): Record<string, string> => {
|
|
||||||
const match = matchingRoute.get();
|
|
||||||
|
|
||||||
return match ? match.pathParameters: {};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default currentPathParametersInjectable;
|
|
||||||
@ -3,6 +3,7 @@
|
|||||||
* 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 { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
import { matches } from "lodash/fp";
|
import { matches } from "lodash/fp";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import currentRouteInjectable from "./current-route.injectable";
|
import currentRouteInjectable from "./current-route.injectable";
|
||||||
@ -13,6 +14,8 @@ const currentRouteComponentInjectable = getInjectable({
|
|||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const route = di.inject(currentRouteInjectable);
|
const route = di.inject(currentRouteInjectable);
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const routeComponents = computedInjectMany(routeSpecificComponentInjectionToken);
|
||||||
|
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
const currentRoute = route.get();
|
const currentRoute = route.get();
|
||||||
@ -21,8 +24,8 @@ const currentRouteComponentInjectable = getInjectable({
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const routeSpecificComponent = di
|
const routeSpecificComponent = routeComponents
|
||||||
.injectMany(routeSpecificComponentInjectionToken)
|
.get()
|
||||||
.find(matches({ route: currentRoute }));
|
.find(matches({ route: currentRoute }));
|
||||||
|
|
||||||
return routeSpecificComponent?.Component;
|
return routeSpecificComponent?.Component;
|
||||||
|
|||||||
@ -22,20 +22,17 @@ const extensionRouteRegistratorInjectable = getInjectable({
|
|||||||
id: "extension-route-registrator",
|
id: "extension-route-registrator",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
return (ext, extensionInstallationCount) => {
|
return (ext) => {
|
||||||
const extension = ext as LensRendererExtension;
|
const extension = ext as LensRendererExtension;
|
||||||
const toRouteInjectable = toRouteInjectableFor(
|
const toRouteInjectable = toRouteInjectableFor(
|
||||||
di,
|
di,
|
||||||
extension,
|
extension,
|
||||||
extensionInstallationCount,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const routeInjectables = [
|
return [
|
||||||
...extension.globalPages.map(toRouteInjectable(false)),
|
...extension.globalPages.map(toRouteInjectable(false)),
|
||||||
...extension.clusterPages.map(toRouteInjectable(true)),
|
...extension.clusterPages.map(toRouteInjectable(true)),
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
di.register(...routeInjectables);
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -48,12 +45,11 @@ const toRouteInjectableFor =
|
|||||||
(
|
(
|
||||||
di: DiContainerForInjection,
|
di: DiContainerForInjection,
|
||||||
extension: LensRendererExtension,
|
extension: LensRendererExtension,
|
||||||
extensionInstallationCount: number,
|
|
||||||
) =>
|
) =>
|
||||||
(clusterFrame: boolean) =>
|
(clusterFrame: boolean) =>
|
||||||
(registration: PageRegistration) => {
|
(registration: PageRegistration) => {
|
||||||
const routeInjectable = getInjectable({
|
const routeInjectable = getInjectable({
|
||||||
id: `route-${registration.id}-for-extension-${extension.sanitizedExtensionId}-installation-${extensionInstallationCount}`,
|
id: `route-${registration.id}-for-extension-${extension.sanitizedExtensionId}`,
|
||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
path: getExtensionRoutePath(extension, registration.id),
|
path: getExtensionRoutePath(extension, registration.id),
|
||||||
@ -95,7 +91,7 @@ const toRouteInjectableFor =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const routeSpecificComponentInjectable = getInjectable({
|
const routeSpecificComponentInjectable = getInjectable({
|
||||||
id: `route-${registration.id}-component-for-extension-${extension.sanitizedExtensionId}-installation-${extensionInstallationCount}`,
|
id: `route-${registration.id}-component-for-extension-${extension.sanitizedExtensionId}`,
|
||||||
|
|
||||||
instantiate: (di) => ({
|
instantiate: (di) => ({
|
||||||
route: di.inject(routeInjectable),
|
route: di.inject(routeInjectable),
|
||||||
|
|||||||
@ -4,16 +4,23 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import currentRouteInjectable from "./current-route.injectable";
|
|
||||||
import type { Route } from "../../common/front-end-routing/front-end-route-injection-token";
|
import type { Route } from "../../common/front-end-routing/front-end-route-injection-token";
|
||||||
|
import currentPathInjectable from "./current-path.injectable";
|
||||||
|
import { matchPath } from "react-router-dom";
|
||||||
|
|
||||||
const routeIsActiveInjectable = getInjectable({
|
const routeIsActiveInjectable = getInjectable({
|
||||||
id: "route-is-active",
|
id: "route-is-active",
|
||||||
|
|
||||||
instantiate: (di, route: Route<unknown>) => {
|
instantiate: (di, route: Route<unknown>) => {
|
||||||
const currentRoute = di.inject(currentRouteInjectable);
|
const currentPath = di.inject(currentPathInjectable);
|
||||||
|
|
||||||
return computed(() => currentRoute.get() === route);
|
return computed(
|
||||||
|
() =>
|
||||||
|
!!matchPath(currentPath.get(), {
|
||||||
|
path: route.path,
|
||||||
|
exact: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
lifecycle: lifecycleEnum.keyedSingleton({
|
lifecycle: lifecycleEnum.keyedSingleton({
|
||||||
|
|||||||
@ -5,18 +5,20 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import currentlyInClusterFrameInjectable from "./currently-in-cluster-frame.injectable";
|
import currentlyInClusterFrameInjectable from "./currently-in-cluster-frame.injectable";
|
||||||
import allRoutesInjectable from "./all-routes.injectable";
|
|
||||||
import { matches } from "lodash/fp";
|
import { matches } from "lodash/fp";
|
||||||
|
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
|
||||||
|
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
|
||||||
const routesInjectable = getInjectable({
|
const routesInjectable = getInjectable({
|
||||||
id: "routes",
|
id: "routes",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const allRoutes = di.inject(allRoutesInjectable);
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
const currentlyInClusterFrame = di.inject(currentlyInClusterFrameInjectable);
|
const currentlyInClusterFrame = di.inject(currentlyInClusterFrameInjectable);
|
||||||
|
const routes = computedInjectMany(frontEndRouteInjectionToken);
|
||||||
|
|
||||||
return computed(() =>
|
return computed(() =>
|
||||||
allRoutes
|
routes
|
||||||
.get()
|
.get()
|
||||||
.filter(matches({ clusterFrame: currentlyInClusterFrame }))
|
.filter(matches({ clusterFrame: currentlyInClusterFrame }))
|
||||||
.filter((route) => route.isEnabled.get()),
|
.filter((route) => route.isEnabled.get()),
|
||||||
|
|||||||
51
yarn.lock
51
yarn.lock
@ -1189,37 +1189,46 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.5"
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
fastq "^1.6.0"
|
fastq "^1.6.0"
|
||||||
|
|
||||||
"@ogre-tools/fp@7.1.0", "@ogre-tools/fp@^7.1.0":
|
"@ogre-tools/fp@8.0.0", "@ogre-tools/fp@^8.0.0":
|
||||||
version "7.1.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@ogre-tools/fp/-/fp-7.1.0.tgz#63bdd23e82d4d0f3cfffbf575017e4dac893f590"
|
resolved "https://registry.yarnpkg.com/@ogre-tools/fp/-/fp-8.0.0.tgz#dd2319a96ce3d2edd3ee2bc2acca07a94a77bf3b"
|
||||||
integrity sha512-lhXreCXr1mlyvNf+YXvqBcIvL2ZKswYJXK1hx2ieeQLmgyvDs6xGio6h+6bHf1kJhvM55PfBATAJ3DyyiUfwiA==
|
integrity sha512-8OpGUbG3avGtx6ASz3XNnK/KCyPW25RPp8oYzzU0zihKU5D4QKHy9qNkQ3npurzeg4d1k4BsgkeX+805nqtZOA==
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration@7.1.0":
|
"@ogre-tools/injectable-extension-for-auto-registration@8.0.0":
|
||||||
version "7.1.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-7.1.0.tgz#eb4aabee04fff1c4e353e4b5e805639e5e8923d5"
|
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-8.0.0.tgz#3a443f1f1c9b564baa78cca6a3c81ac4102660b0"
|
||||||
integrity sha512-xEnXF2iAxYOCj46HymDIjO85zsunONmMD8CThks46pyUD7kTOaf7c9tClEUFdXQTmCAfU3UFxcAxDjyJynoSTg==
|
integrity sha512-DX1bxn8mDwek+W/SaI5WmDHmkY3B3njs3X4pOvqRtiMis3GaWHzeCZeK3q3Iv5cd14FTW8AsfKtujPmLklNf/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ogre-tools/fp" "^7.1.0"
|
"@ogre-tools/fp" "^8.0.0"
|
||||||
"@ogre-tools/injectable" "^7.1.0"
|
"@ogre-tools/injectable" "^8.0.0"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@ogre-tools/injectable-react@7.1.0":
|
"@ogre-tools/injectable-extension-for-mobx@8.0.0":
|
||||||
version "7.1.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable-react/-/injectable-react-7.1.0.tgz#afb60951e7e22b59921eb5ce5d04e3be93fe119e"
|
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable-extension-for-mobx/-/injectable-extension-for-mobx-8.0.0.tgz#80ff506011e078050dd8dcb72660d17181db6d34"
|
||||||
integrity sha512-JDTZR+1IhFUAPjlzP7IwMRysFBVjpQke4Y/7Ddy7MhOF+WtfFx8pOnuWFWKQRlU2FS4PsMpCG09Jgy09j+Qa8Q==
|
integrity sha512-m8gU3cEFHl9IMZLcvvoS7hVxS6p6nG3jdf6fY6MUZE0u9hx4bZuUdWYoylGQizy0FyRFQ2/m5xhTH2VdtXqx8w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ogre-tools/fp" "^7.1.0"
|
"@ogre-tools/fp" "^8.0.0"
|
||||||
"@ogre-tools/injectable" "^7.1.0"
|
"@ogre-tools/injectable" "^8.0.0"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@ogre-tools/injectable@7.1.0", "@ogre-tools/injectable@^7.1.0":
|
"@ogre-tools/injectable-react@8.0.0":
|
||||||
version "7.1.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable/-/injectable-7.1.0.tgz#4137d630720245e9bc8635a0f62888878f711da5"
|
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable-react/-/injectable-react-8.0.0.tgz#b2d8db4bb697ba2822d71ec73e6cabee30f70f34"
|
||||||
integrity sha512-EN82trTh80TuSE0Gr1Gk4oC/Mj3Od//kWH2r+0Z3Np554e4zOgW6lyEOQlxaGIm77taGSvHq9B9cO7lI9hJonQ==
|
integrity sha512-rZa38fm3UzGa/09qC765Za8xJiSPOYHJGsob8UOt2JQIt/BecTNXPMHexfxy9W+DIdAer+YruUgedChdk9nvdQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ogre-tools/fp" "^7.1.0"
|
"@ogre-tools/fp" "^8.0.0"
|
||||||
|
"@ogre-tools/injectable" "^8.0.0"
|
||||||
|
lodash "^4.17.21"
|
||||||
|
|
||||||
|
"@ogre-tools/injectable@8.0.0", "@ogre-tools/injectable@^8.0.0":
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ogre-tools/injectable/-/injectable-8.0.0.tgz#ea4f98bd2466149add94d4f6a9beb7be03729da7"
|
||||||
|
integrity sha512-59p+8uGqwVQ5IpGpgfn3RA+wXzn1tjnPdFWO3GLEgjyp5dWBaMKufCpCFRvvb9sP6B68qo19aLfy/uSm4AXduw==
|
||||||
|
dependencies:
|
||||||
|
"@ogre-tools/fp" "^8.0.0"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@panva/asn1.js@^1.0.0":
|
"@panva/asn1.js@^1.0.0":
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user