diff --git a/src/renderer/components/status-bar/auto-update-status-bar-item.injectable.ts b/src/renderer/components/status-bar/auto-update-status-bar-item.injectable.ts new file mode 100644 index 0000000000..b04c82b28b --- /dev/null +++ b/src/renderer/components/status-bar/auto-update-status-bar-item.injectable.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import { AutoUpdateComponent } from "./auto-update-status-bar-item"; +import { statusBarItemInjectionToken } from "./status-bar-item-injection-token"; + +const autoUpdateStatusBarItemInjectable = getInjectable({ + id: "quit-app-separator-tray-item", + + instantiate: () => ({ + component: AutoUpdateComponent, + position: "left" as const, + visible: computed(() => true), + }), + + injectionToken: statusBarItemInjectionToken, +}); + +export default autoUpdateStatusBarItemInjectable; diff --git a/src/renderer/components/status-bar/status-bar-item-injection-token.ts b/src/renderer/components/status-bar/status-bar-item-injection-token.ts new file mode 100644 index 0000000000..572496b534 --- /dev/null +++ b/src/renderer/components/status-bar/status-bar-item-injection-token.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { IComputedValue } from "mobx"; +import type React from "react"; +import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension"; + +export interface StatusBarItem { + component: React.ComponentType; + position: "left" | "right"; + visible: IComputedValue; + + extension?: LensRendererExtension; +} + +export const statusBarItemInjectionToken = getInjectionToken({ + id: "status-bar-item", +}); diff --git a/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx b/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx new file mode 100644 index 0000000000..a2b8cf6330 --- /dev/null +++ b/src/renderer/components/status-bar/status-bar-item-registrator.injectable.tsx @@ -0,0 +1,89 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { pipeline } from "@ogre-tools/fp"; +import { flatMap } from "lodash/fp"; +import type { Injectable } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; +import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension"; +import type { StatusBarItem } from "./status-bar-item-injection-token"; +import { statusBarItemInjectionToken } from "./status-bar-item-injection-token"; +import type { StatusBarRegistration } from "./status-bar-registration"; +import * as uuid from "uuid"; +import type React from "react"; + +const statusBarItemRegistratorInjectable = getInjectable({ + id: "status-bar-item-registrator", + + instantiate: (di) => (extension, installationCounter) => { + const rendererExtension = extension as LensRendererExtension; + + pipeline( + rendererExtension.statusBarItems, + + flatMap(toItemInjectablesFor(rendererExtension, installationCounter)), + + (injectables) => di.register(...injectables), + ); + }, + + injectionToken: extensionRegistratorInjectionToken, +}); + +export default statusBarItemRegistratorInjectable; + +const toItemInjectablesFor = (extension: LensRendererExtension, installationCounter: number) => { + const _toItemInjectables = () => (registration: StatusBarRegistration): Injectable[] => { + const id = `${uuid.v4()}-status-bar-item-for-extension-${extension.sanitizedExtensionId}-instance-${installationCounter}`; + let component: React.ComponentType; + let position: "left" | "right"; + + if (registration.item) { + const { item } = registration; + + // default for old API is "right" + component = + () => ( + <> + { + typeof item === "function" + ? item() + : item + } + + ); + } else if (registration.components) { + const { position: pos, Item } = registration.components; + + if (pos !== "left" && pos !== "right") { + throw new TypeError("StatusBarRegistration.components.position must be either 'right' or 'left'"); + } + + position = pos; + + component = Item; + } else { + // throw? + } + + return [getInjectable({ + id, + + instantiate: () => ({ + component, + position, + visible: computed(() => true), + }), + + injectionToken: statusBarItemInjectionToken, + })]; + + }; + + return _toItemInjectables(); +}; + + diff --git a/src/renderer/components/status-bar/status-bar-items.injectable.tsx b/src/renderer/components/status-bar/status-bar-items.injectable.tsx index bc4474a7dc..1ed0a6a76a 100644 --- a/src/renderer/components/status-bar/status-bar-items.injectable.tsx +++ b/src/renderer/components/status-bar/status-bar-items.injectable.tsx @@ -2,16 +2,11 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import React from "react"; import { getInjectable } from "@ogre-tools/injectable"; import type { IComputedValue } from "mobx"; import { computed } from "mobx"; -import type { - StatusBarItemProps, - StatusBarRegistration, -} from "./status-bar-registration"; -import registeredStatusBarItemsInjectable from "./registered-status-bar-items.injectable"; -import { AutoUpdateComponent } from "./auto-update-status-bar-item"; +import type { StatusBarItemProps } from "./status-bar-registration"; +import { StatusBarItem, statusBarItemInjectionToken } from "./status-bar-item-injection-token"; export interface StatusBarItems { right: React.ComponentType[]; @@ -19,7 +14,7 @@ export interface StatusBarItems { } interface Dependencies { - registrations: IComputedValue; + registrations: StatusBarItem[]; } function getStatusBarItems({ registrations }: Dependencies): IComputedValue { @@ -29,39 +24,18 @@ function getStatusBarItems({ registrations }: Dependencies): IComputedValue ( - <> - { - typeof item === "function" - ? item() - : item - } - - ), - ); - } else if (registration.components) { - const { position = "right", Item } = registration.components; - - if (position !== "left" && position !== "right") { - throw new TypeError("StatusBarRegistration.components.position must be either 'right' or 'left'"); - } - - res[position].push(Item); + if (position !== "left" && position !== "right") { + throw new TypeError("StatusBarRegistration.components.position must be either 'right' or 'left'"); } + + res[position].push(component); } // This is done so that the first ones registered are closest to the corner @@ -75,7 +49,7 @@ const statusBarItemsInjectable = getInjectable({ id: "status-bar-items", instantiate: (di) => getStatusBarItems({ - registrations: di.inject(registeredStatusBarItemsInjectable), + registrations: di.injectMany(statusBarItemInjectionToken), }), });