mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix: merge page url chunks with native URL()-api, simplified default page-params registration
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
fcb18b6dd1
commit
0fd981866b
@ -1,10 +1,10 @@
|
|||||||
import { Component, LensRendererExtension, Navigation } from "@k8slens/extensions";
|
import { Component, LensRendererExtension, Navigation } from "@k8slens/extensions";
|
||||||
import { CoffeeDoodle } from "react-open-doodles";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
import { CoffeeDoodle } from "react-open-doodles";
|
||||||
|
|
||||||
export const exampleIdPageParam = Navigation.createUrlParam<string>({
|
export const exampleId = Navigation.createUrlParam<string>({
|
||||||
name: "exampleId",
|
name: "exampleId",
|
||||||
defaultValue: "demo",
|
defaultValue: "demo",
|
||||||
});
|
});
|
||||||
@ -22,7 +22,7 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const exampleName = exampleIdPageParam.get();
|
const exampleName = exampleId.get();
|
||||||
const doodleStyle = {
|
const doodleStyle = {
|
||||||
width: "200px"
|
width: "200px"
|
||||||
};
|
};
|
||||||
@ -36,7 +36,7 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
|
|||||||
<p>Location: <i>{location.href}</i></p>
|
<p>Location: <i>{location.href}</i></p>
|
||||||
|
|
||||||
<p className="url-params-demo flex column gaps">
|
<p className="url-params-demo flex column gaps">
|
||||||
<a onClick={() => exampleIdPageParam.set("secret")}>Show secret button</a>
|
<a onClick={() => exampleId.set("secret")}>Show secret button</a>
|
||||||
{exampleName === "secret" && (
|
{exampleName === "secret" && (
|
||||||
<Component.Button accent label="Deactivate" onClick={this.deactivate}/>
|
<Component.Button accent label="Deactivate" onClick={this.deactivate}/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { LensRendererExtension } from "@k8slens/extensions";
|
import { LensRendererExtension } from "@k8slens/extensions";
|
||||||
import { ExampleIcon, ExamplePage, exampleIdPageParam } from "./page";
|
import { ExampleIcon, ExamplePage } from "./page";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export default class ExampleExtension extends LensRendererExtension {
|
export default class ExampleExtension extends LensRendererExtension {
|
||||||
@ -10,9 +10,11 @@ export default class ExampleExtension extends LensRendererExtension {
|
|||||||
components: {
|
components: {
|
||||||
Page: () => <ExamplePage extension={this}/>,
|
Page: () => <ExamplePage extension={this}/>,
|
||||||
},
|
},
|
||||||
params: [
|
params: {
|
||||||
exampleIdPageParam,
|
// setup param "exampleId" with default value "demo"
|
||||||
]
|
// could be also {[paramName: string]: UrlParam} for advanced use-cases (custom parse/stringify)
|
||||||
|
exampleId: "demo"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -25,9 +27,7 @@ export default class ExampleExtension extends LensRendererExtension {
|
|||||||
target: {
|
target: {
|
||||||
pageId: "example",
|
pageId: "example",
|
||||||
params: {
|
params: {
|
||||||
// cause target page has registered a url-param with name "exampleId" == exampleNameUrlParam.name
|
exampleId: "demo-sample-2"
|
||||||
// passing values to page to generate final link
|
|
||||||
exampleId: "demo-2"
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -43,15 +43,17 @@ export class ClusterPageMenuRegistry extends PageMenuRegistry<ClusterPageMenuReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSubItems(parent: ClusterPageMenuRegistration) {
|
getSubItems(parent: ClusterPageMenuRegistration) {
|
||||||
return this.getItems().filter((item) => {
|
return this.getItems().filter((item) => (
|
||||||
return item.parentId === parent.id && item.target.extensionId === parent.target.extensionId;
|
item.parentId === parent.id &&
|
||||||
});
|
item.target.extensionId === parent.target.extensionId
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
getByPage({ id: pageId, extensionId }: RegisteredPage) {
|
getByPage({ id: pageId, extensionId }: RegisteredPage) {
|
||||||
return this.getItems().find((item) => {
|
return this.getItems().find((item) => (
|
||||||
return item.target.pageId == pageId && item.target.extensionId === extensionId;
|
item.target.pageId == pageId &&
|
||||||
});
|
item.target.extensionId === extensionId
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
// Extensions-api -> Custom page registration
|
// Extensions-api -> Custom page registration
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import type { UrlParam } from "../../renderer/navigation/url-param";
|
|
||||||
|
|
||||||
import path from "path";
|
|
||||||
import { action } from "mobx";
|
import { action } from "mobx";
|
||||||
import { BaseRegistry } from "./base-registry";
|
import { BaseRegistry } from "./base-registry";
|
||||||
import { LensExtension, sanitizeExtensionName } from "../lens-extension";
|
import { LensExtension, sanitizeExtensionName } from "../lens-extension";
|
||||||
|
import { UrlParam } from "../../renderer/navigation/url-param";
|
||||||
import logger from "../../main/logger";
|
import logger from "../../main/logger";
|
||||||
|
|
||||||
export interface PageRegistration {
|
export interface PageRegistration {
|
||||||
@ -17,19 +15,24 @@ export interface PageRegistration {
|
|||||||
components: PageComponents;
|
components: PageComponents;
|
||||||
/**
|
/**
|
||||||
* Registered page params.
|
* Registered page params.
|
||||||
* Used to generate page url when provided in getExtensionPageUrl()-helper.
|
* Used to generate final page url when provided in getExtensionPageUrl()-helper.
|
||||||
|
* Advanced usage: provide `UrlParam` as values to customize parsing/stringification from/to URL.
|
||||||
*/
|
*/
|
||||||
params?: UrlParam[];
|
params?: PageTargetParams<string | UrlParam>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PageComponents {
|
export interface PageComponents {
|
||||||
Page: React.ComponentType<any>;
|
Page: React.ComponentType<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PageTarget<P = {}> {
|
export interface PageTarget<P = PageTargetParams> {
|
||||||
extensionId?: string;
|
extensionId?: string;
|
||||||
pageId?: string;
|
pageId?: string;
|
||||||
params?: Record<string, any | any[]> & P; // default target page params
|
params?: P;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageTargetParams<V = any> {
|
||||||
|
[paramName: string]: V;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegisteredPage extends PageRegistration {
|
export interface RegisteredPage extends PageRegistration {
|
||||||
@ -38,27 +41,26 @@ export interface RegisteredPage extends PageRegistration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getExtensionPageUrl(target: PageTarget): string {
|
export function getExtensionPageUrl(target: PageTarget): string {
|
||||||
const { extensionId, pageId = "", params: targetParams = {} } = target;
|
const { extensionId, pageId = "", params: targetPageParams = {} } = target;
|
||||||
let stringifiedParams = "";
|
|
||||||
|
const pagePath = ["/extension", sanitizeExtensionName(extensionId), pageId].join("/");
|
||||||
|
const pageUrl = new URL(pagePath, `http://localhost`);
|
||||||
|
|
||||||
// stringify params to matched target page
|
// stringify params to matched target page
|
||||||
const page = globalPageRegistry.getByPageTarget(target) || clusterPageRegistry.getByPageTarget(target);
|
const targetPage = globalPageRegistry.getByPageTarget(target) || clusterPageRegistry.getByPageTarget(target);
|
||||||
|
|
||||||
if (page?.params) {
|
if (targetPage?.params) {
|
||||||
const searchParams = page.params.map(urlParam => {
|
Object.entries(targetPage.params).forEach(([name, param]) => {
|
||||||
return urlParam.toSearchString({
|
const paramValue = targetPageParams[name];
|
||||||
value: targetParams[urlParam.name] ?? urlParam.getDefaultValue(),
|
if (param instanceof UrlParam) {
|
||||||
mergeGlobals: false,
|
pageUrl.searchParams.set(name, param.stringify(paramValue));
|
||||||
withPrefix: false,
|
} else {
|
||||||
});
|
pageUrl.searchParams.set(name, String(paramValue ?? param));
|
||||||
});
|
}
|
||||||
|
})
|
||||||
if (searchParams.length > 0) {
|
|
||||||
stringifiedParams = `?${searchParams.join("&")}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.posix.join("/extension", sanitizeExtensionName(extensionId), pageId, stringifiedParams);
|
return pageUrl.href.replace(pageUrl.origin, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageRegistry extends BaseRegistry<RegisteredPage> {
|
export class PageRegistry extends BaseRegistry<RegisteredPage> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user