From 4dd6653a665a7505dd84ea8513373f9319deda19 Mon Sep 17 00:00:00 2001 From: Panu Horsmalahti Date: Thu, 24 Mar 2022 11:38:37 +0200 Subject: [PATCH] Add ContextProviders support to the Extension API Signed-off-by: Panu Horsmalahti --- .../extension-loader/extension-loader.ts | 2 + src/extensions/lens-renderer-extension.ts | 1 + .../registries/context-provider-registry.ts | 25 ++++++++++++ src/extensions/registries/index.ts | 1 + src/renderer/frames/root-frame/root-frame.tsx | 39 +++++++++++++------ src/renderer/initializers/registries.ts | 1 + 6 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/extensions/registries/context-provider-registry.ts diff --git a/src/extensions/extension-loader/extension-loader.ts b/src/extensions/extension-loader/extension-loader.ts index 5db134dd4c..086428ff3a 100644 --- a/src/extensions/extension-loader/extension-loader.ts +++ b/src/extensions/extension-loader/extension-loader.ts @@ -250,6 +250,7 @@ export class ExtensionLoader { registries.GlobalPageRegistry.getInstance().add(extension.globalPages, extension), registries.EntitySettingRegistry.getInstance().add(extension.entitySettings), registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems), + ...(extension.getContextProviders ? [registries.ContextProviderRegistry.getInstance().add(await extension.getContextProviders())] : []), ]; this.events.on("remove", (removedExtension: LensRendererExtension) => { @@ -277,6 +278,7 @@ export class ExtensionLoader { registries.ClusterPageRegistry.getInstance().add(extension.clusterPages, extension), registries.ClusterPageMenuRegistry.getInstance().add(extension.clusterPageMenus, extension), registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems), + ...(extension.getContextProviders ? [registries.ContextProviderRegistry.getInstance().add(await extension.getContextProviders())] : []), ]; this.events.on("remove", (removedExtension: LensRendererExtension) => { diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts index 0c16b142a7..a4266a197b 100644 --- a/src/extensions/lens-renderer-extension.ts +++ b/src/extensions/lens-renderer-extension.ts @@ -41,6 +41,7 @@ export class LensRendererExtension extends LensExtension { topBarItems: TopBarRegistration[] = []; additionalCategoryColumns: AdditionalCategoryColumnRegistration[] = []; customCategoryViews: CustomCategoryViewRegistration[] = []; + getContextProviders?: () => Promise; async navigate

(pageId?: string, params?: P) { const { navigate } = await import("../renderer/navigation"); diff --git a/src/extensions/registries/context-provider-registry.ts b/src/extensions/registries/context-provider-registry.ts new file mode 100644 index 0000000000..8cbfb32f31 --- /dev/null +++ b/src/extensions/registries/context-provider-registry.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type React from "react"; +import { BaseRegistry } from "./base-registry"; + +export interface ContextProviderProps { +} + +export interface ContextProviderComponents { + Provider: React.ComponentType; +} + +export interface ContextProviderRegistration { + components: ContextProviderComponents; +} + +export interface RegisteredContextProvider extends ContextProviderRegistration { + id: string; +} + +export class ContextProviderRegistry extends BaseRegistry { +} diff --git a/src/extensions/registries/index.ts b/src/extensions/registries/index.ts index 23f064a26b..7015a3fc06 100644 --- a/src/extensions/registries/index.ts +++ b/src/extensions/registries/index.ts @@ -10,4 +10,5 @@ export * from "./page-menu-registry"; export * from "./kube-object-detail-registry"; export * from "./entity-setting-registry"; export * from "./catalog-entity-detail-registry"; +export * from "./context-provider-registry"; export * from "./protocol-handler"; diff --git a/src/renderer/frames/root-frame/root-frame.tsx b/src/renderer/frames/root-frame/root-frame.tsx index 2dce9a61b0..53ccff367f 100644 --- a/src/renderer/frames/root-frame/root-frame.tsx +++ b/src/renderer/frames/root-frame/root-frame.tsx @@ -18,6 +18,7 @@ import { ClusterFrameHandler } from "../../components/cluster-manager/lens-views import historyInjectable from "../../navigation/history.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; import type { History } from "history"; +import { ContextProviderRegistry, ContextProviderProps } from "../../../extensions/registries/context-provider-registry"; injectSystemCAs(); @@ -39,19 +40,33 @@ class NonInjectedRootFrame extends React.Component { ipcRenderer.send(IpcRendererNavigationEvents.LOADED); } + /** + * Recursively render all the React Context Providers with the children + */ + renderWithProviders(contextProviders: React.ComponentType[], children: React.ReactNode) { + if (contextProviders.length === 0) { + return children; + } else { + const [Provider, ...restProviders] = contextProviders; + + return ({this.renderWithProviders(restProviders, children)}); + } + } + render() { - return ( - - - - - - - - - - - ); + // Extensions may register React Context Provider components + const contextProviders = ContextProviderRegistry.getInstance().getItems().map(contextProvider => contextProvider.components.Provider); + + return this.renderWithProviders(contextProviders, ( + + + + + + + + + )); } } diff --git a/src/renderer/initializers/registries.ts b/src/renderer/initializers/registries.ts index 7362bdfbd7..3f685159ca 100644 --- a/src/renderer/initializers/registries.ts +++ b/src/renderer/initializers/registries.ts @@ -12,4 +12,5 @@ export function initRegistries() { registries.EntitySettingRegistry.createInstance(); registries.GlobalPageRegistry.createInstance(); registries.KubeObjectDetailRegistry.createInstance(); + registries.ContextProviderRegistry.createInstance(); }