diff --git a/extensions/support-page/renderer.tsx b/extensions/support-page/renderer.tsx
index 0137ea7771..92d460fdfc 100644
--- a/extensions/support-page/renderer.tsx
+++ b/extensions/support-page/renderer.tsx
@@ -5,6 +5,8 @@ import { SupportPage } from "./src/support";
export default class SupportPageRendererExtension extends LensRendererExtension {
globalPages: Interface.PageRegistration[] = [
{
+ id: "support",
+ routePath: "/support",
components: {
Page: SupportPage,
}
@@ -14,7 +16,7 @@ export default class SupportPageRendererExtension extends LensRendererExtension
statusBarItems: Interface.StatusBarRegistration[] = [
{
item: (
-
this.navigate()}>
+
this.navigate("/support")}>
)
diff --git a/src/extensions/lens-extension.ts b/src/extensions/lens-extension.ts
index 164c84baa5..f1ffb9184b 100644
--- a/src/extensions/lens-extension.ts
+++ b/src/extensions/lens-extension.ts
@@ -14,7 +14,6 @@ export interface LensExtensionManifest {
}
export class LensExtension {
- readonly routePrefix = "/extension/:name"
readonly manifest: LensExtensionManifest;
readonly manifestPath: string;
readonly isBundled: boolean;
diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts
index 0055344a66..de9aae40ec 100644
--- a/src/extensions/lens-main-extension.ts
+++ b/src/extensions/lens-main-extension.ts
@@ -2,13 +2,14 @@ import type { MenuRegistration } from "./registries/menu-registry";
import { observable } from "mobx";
import { LensExtension } from "./lens-extension"
import { WindowManager } from "../main/window-manager";
+import { getPageUrl } from "./registries/page-registry"
export class LensMainExtension extends LensExtension {
@observable.shallow appMenus: MenuRegistration[] = []
async navigate(location?: string, frameId?: number) {
const windowManager = WindowManager.getInstance
();
- const url = this.getPageUrl(location); // get full path to extension's page
+ const url = getPageUrl(this, location); // get full path to extension's page
await windowManager.navigate(url, frameId);
}
}
diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts
index 87ca214805..5968124cbc 100644
--- a/src/extensions/lens-renderer-extension.ts
+++ b/src/extensions/lens-renderer-extension.ts
@@ -1,6 +1,7 @@
import type { AppPreferenceRegistration, ClusterFeatureRegistration, KubeObjectDetailRegistration, KubeObjectMenuRegistration, KubeObjectStatusRegistration, PageMenuRegistration, PageRegistration, StatusBarRegistration, } from "./registries"
import { observable } from "mobx";
import { LensExtension } from "./lens-extension"
+import { getPageUrl } from "./registries/page-registry"
export class LensRendererExtension extends LensExtension {
@observable.shallow globalPages: PageRegistration[] = []
@@ -16,6 +17,6 @@ export class LensRendererExtension extends LensExtension {
async navigate(location?: string) {
const { navigate } = await import("../renderer/navigation");
- navigate(this.getPageUrl(location));
+ navigate(getPageUrl(this, location));
}
}
diff --git a/src/extensions/registries/page-menu-registry.ts b/src/extensions/registries/page-menu-registry.ts
index 0748fad187..34fe50154c 100644
--- a/src/extensions/registries/page-menu-registry.ts
+++ b/src/extensions/registries/page-menu-registry.ts
@@ -5,13 +5,18 @@ import { action } from "mobx";
import type { IconProps } from "../../renderer/components/icon";
import { BaseRegistry } from "./base-registry";
import { LensExtension } from "../lens-extension";
-import { getPageUrl } from "./page-registry";
+import { PageRegistration } from "../interfaces";
+
+export interface PageMenuTarget {
+ pageId: string;
+ extensionId: string;
+ params: object;
+}
export interface PageMenuRegistration {
- url?: string; // when not provided initial extension's path used, e.g. "/extension/lens-extension-name"
+ target?: PageMenuTarget;
title: React.ReactNode;
components: PageMenuComponents;
- subMenus?: PageSubMenuRegistration[];
}
export interface PageSubMenuRegistration {
@@ -24,18 +29,15 @@ export interface PageMenuComponents {
}
export class PageMenuRegistry extends BaseRegistry {
+
@action
add(items: T[], ext?: LensExtension) {
const normalizedItems = items.map((i) => {
- i.url = getPageUrl(ext, i.url)
+ i.target.extensionId = ext.name
return i
})
return super.add(normalizedItems);
}
-
- getByRoutePath(routePath: string) {
- return this.getItems().find((i) => i.url === routePath)
- }
}
export const globalPageMenuRegistry = new PageMenuRegistry>();
diff --git a/src/extensions/registries/page-registry.ts b/src/extensions/registries/page-registry.ts
index 2511f28a95..f82cce2196 100644
--- a/src/extensions/registries/page-registry.ts
+++ b/src/extensions/registries/page-registry.ts
@@ -5,12 +5,13 @@ import { action } from "mobx";
import { compile } from "path-to-regexp";
import { BaseRegistry } from "./base-registry";
import { LensExtension } from "../lens-extension"
+import { PageMenuTarget } from "./page-menu-registry";
export interface PageRegistration {
+ id: string; // hello-world:id
routePath?: string; // additional (suffix) route path to base extension's route: "/extension/:name"
exact?: boolean; // route matching flag, see: https://reactrouter.com/web/api/NavLink/exact-bool
components: PageComponents;
- subPages?: SubPageRegistration[];
}
export interface SubPageRegistration {
@@ -41,8 +42,8 @@ export class PageRegistry extends BaseRegistry {
return super.add(normalizedItems);
}
- getByUrl(url: string) {
- return this.getItems().find((i) => i.routePath === url)
+ getByPageMenuTarget(target: PageMenuTarget) {
+ return this.getItems().find((page) => page.routePath.startsWith(`/extension/${target.extensionId}/`) && page.id === target.pageId)
}
}
diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx
index 193a1a8796..cb8d02172b 100755
--- a/src/renderer/components/app.tsx
+++ b/src/renderer/components/app.tsx
@@ -74,27 +74,8 @@ export class App extends React.Component {
}
renderExtensionRoutes() {
- return clusterPageRegistry.getItems().map(({ components: { Page }, exact, routePath, subPages }) => {
+ return clusterPageRegistry.getItems().map(({ components: { Page }, exact, routePath }) => {
const Component = () => {
- if (subPages) {
- const tabs: TabLayoutRoute[] = subPages.map(({ exact, routePath, components: { Page } }) => {
- const menuItem = clusterPageMenuRegistry.getByRoutePath(routePath);
- if (!menuItem) return;
- return {
- routePath, exact,
- component: Page,
- url: menuItem.url,
- title: menuItem.title,
- }
- }).filter(Boolean);
- if (tabs.length > 0) {
- return (
-
-
-
- )
- }
- }
return
};
return
diff --git a/src/renderer/components/cluster-manager/clusters-menu.tsx b/src/renderer/components/cluster-manager/clusters-menu.tsx
index 4c81e967b6..302e4e76d2 100644
--- a/src/renderer/components/cluster-manager/clusters-menu.tsx
+++ b/src/renderer/components/cluster-manager/clusters-menu.tsx
@@ -23,6 +23,7 @@ import { ConfirmDialog } from "../confirm-dialog";
import { clusterIpc } from "../../../common/cluster-ipc";
import { clusterViewURL } from "./cluster-view.route";
import { globalPageMenuRegistry, globalPageRegistry } from "../../../extensions/registries";
+import { compile } from "path-to-regexp";
interface Props {
className?: IClassName;
@@ -148,8 +149,8 @@ export class ClustersMenu extends React.Component {
)}
- {globalPageMenuRegistry.getItems().map(({ title, url, components: { Icon } }) => {
- const registeredPage = globalPageRegistry.getByUrl(url);
+ {globalPageMenuRegistry.getItems().map(({ title, target, components: { Icon } }) => {
+ const registeredPage = globalPageRegistry.getByPageMenuTarget(target);
if (!registeredPage) return;
const { routePath, exact } = registeredPage;
return (
@@ -157,7 +158,7 @@ export class ClustersMenu extends React.Component
{
key={routePath}
tooltip={title}
active={isActiveRoute({ path: routePath, exact })}
- onClick={() => navigate(url)}
+ onClick={() => navigate(compile(routePath)(target.params))}
/>
)
})}
diff --git a/src/renderer/components/layout/sidebar.tsx b/src/renderer/components/layout/sidebar.tsx
index 74fdd37b0b..8485f1e134 100644
--- a/src/renderer/components/layout/sidebar.tsx
+++ b/src/renderer/components/layout/sidebar.tsx
@@ -30,6 +30,7 @@ import { isActiveRoute } from "../../navigation";
import { isAllowedResource } from "../../../common/rbac"
import { Spinner } from "../spinner";
import { clusterPageMenuRegistry, clusterPageRegistry } from "../../../extensions/registries";
+import { compile } from "path-to-regexp";
const SidebarContext = React.createContext({ pinned: false });
type SidebarContextValue = {
@@ -191,10 +192,11 @@ export class Sidebar extends React.Component {
>
{this.renderCustomResources()}
- {clusterPageMenuRegistry.getItems().map(({ title, url, components: { Icon } }) => {
- const registeredPage = clusterPageRegistry.getByUrl(url);
+ {clusterPageMenuRegistry.getItems().map(({ title, target, components: { Icon } }) => {
+ const registeredPage = clusterPageRegistry.getByPageMenuTarget(target);
if (!registeredPage) return;
const { routePath, exact } = registeredPage;
+ const url = compile(routePath)(target.params)
return (