diff --git a/extensions/example-extension/index.tsx b/extensions/example-extension/index.tsx index f46a9dd1fc..98688ea077 100644 --- a/extensions/example-extension/index.tsx +++ b/extensions/example-extension/index.tsx @@ -1,4 +1,4 @@ -import { Button, DynamicPageType, Icon, IconProps, LensExtension, React } from "@lens/extensions"; +import { Button, Icon, IconProps, LensExtension, React, DynamicPageType } from "@lens/extensions"; import { CoffeeDoodle } from "react-open-doodles"; import path from "path"; @@ -8,7 +8,7 @@ export default class ExampleExtension extends LensExtension { this.registerPage({ type: DynamicPageType.CLUSTER, path: "/extension-example", - menuTitle: "Example Extension", + title: "Example Extension", components: { Page: () => , MenuIcon: ExtensionIcon, @@ -33,19 +33,16 @@ export class ExtensionPage extends React.Component<{ extension: ExampleExtension } render() { - const { TabLayout } = this.props.extension.runtime.components; const doodleStyle = { width: "200px" } return ( - -
-
-

Hello from Example extension!

-

File: {__filename}

-
-
+
+
+

Hello from Example extension!

+

File: {__filename}

+
) } } diff --git a/src/extensions/extension-api.ts b/src/extensions/extension-api.ts index 7f364898dd..1e7f457754 100644 --- a/src/extensions/extension-api.ts +++ b/src/extensions/extension-api.ts @@ -1,12 +1,13 @@ // Lens-extensions api developer's kit -export type { LensRuntimeRendererEnv } from "./lens-runtime"; +// TODO: add more common re-usable UI components + refactor interfaces (Props -> ComponentProps) + +// TODO: figure out how to import as normal npm-package +export { default as React } from "react" -// APIs export * from "./lens-extension" +export { LensRuntimeRendererEnv } from "./lens-runtime"; export { DynamicPageType } from "./register-page"; -// TODO: add more common re-usable UI components + refactor interfaces (Props -> ComponentProps) -export { default as React } from "react" export * from "../renderer/components/icon" export * from "../renderer/components/tooltip" export * from "../renderer/components/button" diff --git a/src/extensions/lens-runtime.ts b/src/extensions/lens-runtime.ts index 1518dbc9de..6644ad7d76 100644 --- a/src/extensions/lens-runtime.ts +++ b/src/extensions/lens-runtime.ts @@ -1,17 +1,13 @@ -// Lens renderer runtime params available to extensions after activation +// Lens renderer runtime apis exposed to extensions once activated import logger from "../main/logger"; import { dynamicPages } from "./register-page"; -import { TabLayout } from "../renderer/components/layout/tab-layout"; import { navigate } from "../renderer/navigation"; export interface LensRuntimeRendererEnv { navigate: typeof navigate; logger: typeof logger; dynamicPages: typeof dynamicPages - components: { - TabLayout: typeof TabLayout - } } export function getLensRuntime(): LensRuntimeRendererEnv { @@ -19,8 +15,5 @@ export function getLensRuntime(): LensRuntimeRendererEnv { logger, navigate, dynamicPages, - components: { - TabLayout // fixme: refactor, import as pure component from "@lens/extensions" - } } } diff --git a/src/extensions/register-page.tsx b/src/extensions/register-page.tsx index 34317c1d93..2db368c6fe 100644 --- a/src/extensions/register-page.tsx +++ b/src/extensions/register-page.tsx @@ -2,18 +2,24 @@ import { computed, observable } from "mobx"; import React from "react"; -import type { IconProps } from "../renderer/components/icon"; +import { RouteProps } from "react-router"; +import { IconProps } from "../renderer/components/icon"; +import { cssNames, IClassName } from "../renderer/utils"; +import { TabLayout, TabRoute } from "../renderer/components/layout/tab-layout"; export enum DynamicPageType { GLOBAL = "lens-scope", CLUSTER = "cluster-view-scope", } -export interface PageRegistration { +export interface PageRegistration extends RouteProps { + className?: IClassName; + url?: string; // initial url to be used for building menus and tabs, otherwise "path" applied by default path: string; // route-path - menuTitle: string; + title: React.ReactNode; // used in sidebar's & tabs-layout type: DynamicPageType; components: PageComponents; + subPages?: (PageRegistration & TabRoute)[]; } export interface PageComponents { @@ -43,4 +49,15 @@ export class PagesStore { } } +export class DynamicPage extends React.Component<{ page: PageRegistration }> { + render() { + const { className, components: { Page }, subPages = [] } = this.props.page; + return ( + + + + ) + } +} + export const dynamicPages = new PagesStore(); diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 84be150cda..0b9330efbe 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -36,7 +36,7 @@ import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store import logger from "../../main/logger"; import { clusterIpc } from "../../common/cluster-ipc"; import { webFrame } from "electron"; -import { dynamicPages } from "../../extensions/register-page"; +import { DynamicPage, dynamicPages } from "../../extensions/register-page"; @observer export class App extends React.Component { @@ -74,8 +74,8 @@ export class App extends React.Component { - {dynamicPages.clusterPages.map(({ path, components: { Page } }) => { - return + {dynamicPages.clusterPages.map(page => { + return }/> })} diff --git a/src/renderer/components/layout/sidebar.tsx b/src/renderer/components/layout/sidebar.tsx index 68c82f8676..a8a20f8ff5 100644 --- a/src/renderer/components/layout/sidebar.tsx +++ b/src/renderer/components/layout/sidebar.tsx @@ -184,14 +184,14 @@ export class Sidebar extends React.Component { > {this.renderCustomResources()} - {dynamicPages.clusterPages.map(({ path, menuTitle, components: { MenuIcon } }) => { + {dynamicPages.clusterPages.map(({ path, title, components: { MenuIcon } }) => { return ( } /> ) diff --git a/src/renderer/components/layout/tab-layout.tsx b/src/renderer/components/layout/tab-layout.tsx index 82c0cac6cf..597cb6444e 100644 --- a/src/renderer/components/layout/tab-layout.tsx +++ b/src/renderer/components/layout/tab-layout.tsx @@ -1,5 +1,4 @@ import "./tab-layout.scss"; - import React, { ReactNode } from "react"; import { matchPath, RouteProps } from "react-router-dom"; import { observer } from "mobx-react"; @@ -7,7 +6,6 @@ import { cssNames } from "../../utils"; import { Tab, Tabs } from "../tabs"; import { ErrorBoundary } from "../error-boundary"; import { navigate, navigation } from "../../navigation"; -import { getHostedCluster } from "../../../common/cluster-store"; export interface TabRoute extends RouteProps { title: React.ReactNode; @@ -23,17 +21,13 @@ interface Props { export const TabLayout = observer(({ className, contentClass, tabs, children }: Props) => { const routePath = navigation.location.pathname; - const cluster = getHostedCluster(); - if (!cluster) { - return null; // fix: skip render when removing active (visible) cluster - } return (
{tabs && ( navigate(url)}> {tabs.map(({ title, path, url, ...routeProps }) => { const isActive = !!matchPath(routePath, { path, ...routeProps }); - return ; + return ; })} )}