Allow computed tray menu for extensions (#6598)

* Add computed tray menu for extensions.

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>

* Use disposer. Fix style.

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>

* Register/reregister injectables by id.

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
Panu Horsmalahti authored and GitHub committed 2022-11-17 11:03:25 -05:00
1 parent a91e3a7f8e
commit 1861fe2049
6 files changed
+143 -18

No files matched your search

@@ -4,9 +4,11 @@
*/
import type { Injectable } from "@ogre-tools/injectable";
import { getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import type { LensExtension } from "../lens-extension";
export type ExtensionRegistrator = (extension: LensExtension) => Injectable<any, any, any>[];
export type ExtensionRegistrator = (extension: LensExtension) =>
Injectable<any, any, any>[] | IComputedValue<Injectable<any, any, any>[]>;
export const extensionRegistratorInjectionToken = getInjectionToken<ExtensionRegistrator>({
id: "extension-registrator-token",
@@ -2,8 +2,11 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Injectable } from "@ogre-tools/injectable";
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import { difference, find, map } from "lodash";
import { reaction, runInAction } from "mobx";
import { disposer } from "../../../common/utils/disposer";
import type { LensExtension } from "../../lens-extension";
import { extensionRegistratorInjectionToken } from "../extension-registrator-injection-token";
@@ -12,6 +15,16 @@ export interface Extension {
deregister: () => void;
}
const idsToInjectables = (ids: string[], injectables: Injectable<any, any, any>[]) => ids.map(id => {
const injectable = find(injectables, { id });
if (!injectable) {
throw new Error(`Injectable ${id} not found`);
}
return injectable;
});
const extensionInjectable = getInjectable({
id: "extension",
@@ -21,19 +34,42 @@ const extensionInjectable = getInjectable({
instantiate: (childDi) => {
const extensionRegistrators = childDi.injectMany(extensionRegistratorInjectionToken);
const reactionDisposer = disposer();
return {
register: () => {
const injectables = extensionRegistrators.flatMap((getInjectablesOfExtension) =>
getInjectablesOfExtension(instance),
);
extensionRegistrators.forEach((getInjectablesOfExtension) => {
const injectables = getInjectablesOfExtension(instance);
runInAction(() => {
childDi.register(...injectables);
reactionDisposer.push(
// injectables is either an array or a computed array, in which case
// we need to update the registered injectables with a reaction every time they change
reaction(
() => Array.isArray(injectables) ? injectables : injectables.get(),
(currentInjectables, previousInjectables = []) => {
// Register new injectables and deregister removed injectables by id
const currentIds = map(currentInjectables, "id");
const previousIds = map(previousInjectables, "id");
const idsToAdd = difference(currentIds, previousIds);
const idsToRemove = previousIds.filter(previousId => !currentIds.includes(previousId));
if (idsToRemove.length > 0) {
childDi.deregister(...idsToInjectables(idsToRemove, previousInjectables));
}
if (idsToAdd.length > 0) {
childDi.register(...idsToInjectables(idsToAdd, currentInjectables));
}
}, {
fireImmediately: true,
},
));
});
},
deregister: () => {
reactionDisposer();
runInAction(() => {
parentDi.deregister(extensionInjectable);
});
+2 -2
View File
@@ -5,7 +5,7 @@
import { LensExtension, lensExtensionDependencies } from "./lens-extension";
import type { CatalogEntity } from "../common/catalog";
import type { IObservableArray } from "mobx";
import type { IComputedValue, IObservableArray } from "mobx";
import type { MenuRegistration } from "../features/application-menu/main/menu-registration";
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
@@ -13,7 +13,7 @@ import type { LensMainExtensionDependencies } from "./lens-extension-set-depende
export class LensMainExtension extends LensExtension<LensMainExtensionDependencies> {
appMenus: MenuRegistration[] = [];
trayMenus: TrayMenuRegistration[] = [];
trayMenus: TrayMenuRegistration[] | IComputedValue<TrayMenuRegistration[]> = [];
/**
* implement this to modify the shell environment that Lens terminals are opened with. The ShellEnvModifier type has the signature