diff --git a/extensions/support-page/renderer.tsx b/extensions/support-page/renderer.tsx index 44f5985398..3c453e227b 100644 --- a/extensions/support-page/renderer.tsx +++ b/extensions/support-page/renderer.tsx @@ -1,6 +1,7 @@ -import { LensRendererExtension, Registry } from "@k8slens/extensions"; -import { Support } from "./src/support"; +import React from "react"; +import { Component, LensRendererExtension, Navigation, Registry } from "@k8slens/extensions"; import { supportPageRoute, supportPageURL } from "./src/support.route"; +import { Support } from "./src/support"; export default class SupportPageRendererExtension extends LensRendererExtension { async onActivate() { @@ -19,4 +20,18 @@ export default class SupportPageRendererExtension extends LensRendererExtension }) ) } + + registerStatusBarIcon(registry: Registry.StatusBarRegistry) { + this.disposers.push( + registry.add({ + icon: ( + Navigation.navigate(supportPageURL())} + /> + ) + }) + ) + } } diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index 5dc6a56277..705d88722c 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -34,33 +34,33 @@ export class ExtensionLoader { } } - loadOnClusterRenderer() { - logger.info('[EXTENSIONS-LOADER]: load on cluster renderer') - this.autoloadExtensions((instance: LensRendererExtension) => { - instance.registerPages(pageRegistry) - }) - } - - loadOnMainRenderer() { - logger.info('[EXTENSIONS-LOADER]: load on main renderer') - this.autoloadExtensions((instance: LensRendererExtension) => { - instance.registerPages(pageRegistry) - instance.registerAppPreferences(appPreferenceRegistry) - }) - } - loadOnMain() { logger.info('[EXTENSIONS-LOADER]: load on main') this.autoloadExtensions((instance: LensMainExtension) => { instance.registerAppMenus(menuRegistry); - instance.registerStatusBarIcon(statusBarRegistry); + }) + } + + loadOnClusterManagerRenderer() { + logger.info('[EXTENSIONS-LOADER]: load on main renderer (cluster manager)') + this.autoloadExtensions((instance: LensRendererExtension) => { + instance.registerPages(pageRegistry) + instance.registerAppPreferences(appPreferenceRegistry) + instance.registerStatusBarIcon(statusBarRegistry) + }) + } + + loadOnClusterRenderer() { + logger.info('[EXTENSIONS-LOADER]: load on cluster renderer (dashboard)') + this.autoloadExtensions((instance: LensRendererExtension) => { + instance.registerPages(pageRegistry) }) } protected autoloadExtensions(callback: (instance: LensExtension) => void) { return reaction(() => this.extensions.toJS(), (installedExtensions) => { for (const [id, ext] of installedExtensions) { - let instance = this.instances.get(ext.manifestPath) + let instance = this.instances.get(ext.name) if (!instance) { const extensionModule = this.requireExtension(ext) if (!extensionModule) { @@ -70,7 +70,7 @@ export class ExtensionLoader { instance = new LensExtensionClass({ ...ext.manifest, manifestPath: ext.manifestPath, id: ext.manifestPath }, ext.manifest); instance.enable(); callback(instance) - this.instances.set(ext.id, instance) + this.instances.set(ext.name, instance) } } }, { diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts index 5031c3caa8..34e52623ab 100644 --- a/src/extensions/lens-renderer-extension.ts +++ b/src/extensions/lens-renderer-extension.ts @@ -1,6 +1,7 @@ import { LensExtension } from "./lens-extension" import type { PageRegistry } from "./registries/page-registry" import type { AppPreferenceRegistry } from "./registries/app-preference-registry"; +import type { StatusBarRegistry } from "./registries"; export class LensRendererExtension extends LensExtension { registerPages(registry: PageRegistry) { @@ -10,4 +11,8 @@ export class LensRendererExtension extends LensExtension { registerAppPreferences(registry: AppPreferenceRegistry) { return } + + registerStatusBarIcon(registry: StatusBarRegistry) { + return + } } diff --git a/src/extensions/registries/app-preference-registry.ts b/src/extensions/registries/app-preference-registry.ts index dcfb5bc84e..6c54911f82 100644 --- a/src/extensions/registries/app-preference-registry.ts +++ b/src/extensions/registries/app-preference-registry.ts @@ -1,5 +1,5 @@ -import { observable } from "mobx" -import React from "react" +import type React from "react" +import { BaseRegistry } from "./base-registry"; export interface AppPreferenceComponents { Hint: React.ComponentType; @@ -11,17 +11,7 @@ export interface AppPreferenceRegistration { components: AppPreferenceComponents; } -export class AppPreferenceRegistry { - preferences = observable.array([], { deep: false }); - - add(preference: AppPreferenceRegistration) { - this.preferences.push(preference) - return () => { - this.preferences.replace( - this.preferences.filter(c => c !== preference) - ) - }; - } +export class AppPreferenceRegistry extends BaseRegistry { } export const appPreferenceRegistry = new AppPreferenceRegistry() diff --git a/src/extensions/registries/base-registry.ts b/src/extensions/registries/base-registry.ts new file mode 100644 index 0000000000..01613a59eb --- /dev/null +++ b/src/extensions/registries/base-registry.ts @@ -0,0 +1,17 @@ +// Base class for extensions-api registries +import { observable } from "mobx"; + +export class BaseRegistry { + protected items = observable([], { deep: false }); + + getItems(): T[] { + return this.items.toJS(); + } + + add(item: T) { + this.items.push(item); + return () => { + this.items.remove(item); // works because of {deep: false}; + } + } +} diff --git a/src/extensions/registries/menu-registry.ts b/src/extensions/registries/menu-registry.ts index dba3718017..d31d124f30 100644 --- a/src/extensions/registries/menu-registry.ts +++ b/src/extensions/registries/menu-registry.ts @@ -1,24 +1,14 @@ -// Extensions API -> Global menu customize +// Extensions API -> Global menu customizations -import { observable } from "mobx"; -import { MenuItemConstructorOptions } from "electron"; import type { MenuTopId } from "../../main/menu"; +import type { MenuItemConstructorOptions } from "electron"; +import { BaseRegistry } from "./base-registry"; export interface MenuRegistration extends MenuItemConstructorOptions { parentId?: MenuTopId; } -export class MenuRegistry { - protected items = observable.array([], { deep: false }); - - getItems(): MenuRegistration[] { - return this.items.toJS(); - } - - add(item: MenuRegistration) { - this.items.push(item); - return () => this.items.remove(item) - } +export class MenuRegistry extends BaseRegistry { } export const menuRegistry = new MenuRegistry(); diff --git a/src/extensions/registries/page-registry.ts b/src/extensions/registries/page-registry.ts index 2de9f59ec3..d0b8f57329 100644 --- a/src/extensions/registries/page-registry.ts +++ b/src/extensions/registries/page-registry.ts @@ -5,7 +5,8 @@ import type { RouteProps } from "react-router"; import type { IconProps } from "../../renderer/components/icon"; import type { IClassName } from "../../renderer/utils"; import type { TabRoute } from "../../renderer/components/layout/tab-layout"; -import { computed, observable } from "mobx"; +import { BaseRegistry } from "./base-registry"; +import { computed } from "mobx"; export enum PageRegistryType { GLOBAL = "lens-scope", @@ -26,21 +27,13 @@ export interface PageComponents { MenuIcon?: React.ComponentType; } -export class PageRegistry { - protected pages = observable.array([], { deep: false }); - +export class PageRegistry extends BaseRegistry { @computed get globalPages() { - return this.pages.filter(page => page.type === PageRegistryType.GLOBAL); + return this.items.filter(page => page.type === PageRegistryType.GLOBAL); } @computed get clusterPages() { - return this.pages.filter(page => page.type === PageRegistryType.CLUSTER); - } - - // fixme: validate route paths to avoid collisions - add(pageInit: PageRegistration) { - this.pages.push(pageInit); - return () => this.pages.remove(pageInit); // works because of {deep: false}; + return this.items.filter(page => page.type === PageRegistryType.CLUSTER); } } diff --git a/src/extensions/registries/status-bar-registry.ts b/src/extensions/registries/status-bar-registry.ts index 0182713ab1..df1599cd28 100644 --- a/src/extensions/registries/status-bar-registry.ts +++ b/src/extensions/registries/status-bar-registry.ts @@ -1,15 +1,13 @@ // Extensions API -> Status bar customizations -import { observable } from "mobx"; +import React from "react"; +import { BaseRegistry } from "./base-registry"; export interface StatusBarRegistration { + icon?: React.ReactNode; } -export class StatusBarRegistry { - items = observable([], { deep: false }); - - add(item: StatusBarRegistration) { - } +export class StatusBarRegistry extends BaseRegistry { } export const statusBarRegistry = new StatusBarRegistry(); diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 4b9532229f..613cc25f61 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -103,7 +103,6 @@ export class Preferences extends React.Component { render() { const { preferences } = userStore; - const extensionPreferences = appPreferenceRegistry.preferences; const header =

Preferences

; return ( @@ -170,7 +169,7 @@ export class Preferences extends React.Component {
- {extensionPreferences.map(({ title, components: { Hint, Input } }, index) => { + {appPreferenceRegistry.getItems().map(({ title, components: { Hint, Input } }, index) => { return (

{title}

diff --git a/src/renderer/components/cluster-manager/bottom-bar.tsx b/src/renderer/components/cluster-manager/bottom-bar.tsx index 953334b5fe..1847615c7f 100644 --- a/src/renderer/components/cluster-manager/bottom-bar.tsx +++ b/src/renderer/components/cluster-manager/bottom-bar.tsx @@ -5,7 +5,7 @@ import { observer } from "mobx-react"; import { Icon } from "../icon"; import { WorkspaceMenu } from "../+workspaces/workspace-menu"; import { workspaceStore } from "../../../common/workspace-store"; -import { navigate } from "../../navigation"; +import { statusBarRegistry } from "../../../extensions/registries"; @observer export class BottomBar extends React.Component { @@ -13,18 +13,19 @@ export class BottomBar extends React.Component { const { currentWorkspace } = workspaceStore; return (
-
+
{currentWorkspace.name}
- - navigate("/support")} + +
+ {statusBarRegistry.getItems().map(({ icon }, index) => { + if (!icon) return; + return {icon} + })} +
) } diff --git a/src/renderer/lens-app.tsx b/src/renderer/lens-app.tsx index e23056b9f8..e6c2baa6c2 100644 --- a/src/renderer/lens-app.tsx +++ b/src/renderer/lens-app.tsx @@ -16,7 +16,7 @@ import { extensionLoader } from "../extensions/extension-loader"; @observer export class LensApp extends React.Component { static async init() { - extensionLoader.loadOnMainRenderer(); + extensionLoader.loadOnClusterManagerRenderer(); } render() {