1
0
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:
Roman 2020-12-07 13:54:08 +02:00
parent fcb18b6dd1
commit 0fd981866b
4 changed files with 44 additions and 40 deletions

View File

@ -1,10 +1,10 @@
import { Component, LensRendererExtension, Navigation } from "@k8slens/extensions";
import { CoffeeDoodle } from "react-open-doodles";
import React from "react";
import path from "path";
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",
defaultValue: "demo",
});
@ -22,7 +22,7 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
};
render() {
const exampleName = exampleIdPageParam.get();
const exampleName = exampleId.get();
const doodleStyle = {
width: "200px"
};
@ -36,7 +36,7 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
<p>Location: <i>{location.href}</i></p>
<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" && (
<Component.Button accent label="Deactivate" onClick={this.deactivate}/>
)}

View File

@ -1,5 +1,5 @@
import { LensRendererExtension } from "@k8slens/extensions";
import { ExampleIcon, ExamplePage, exampleIdPageParam } from "./page";
import { ExampleIcon, ExamplePage } from "./page";
import React from "react";
export default class ExampleExtension extends LensRendererExtension {
@ -10,9 +10,11 @@ export default class ExampleExtension extends LensRendererExtension {
components: {
Page: () => <ExamplePage extension={this}/>,
},
params: [
exampleIdPageParam,
]
params: {
// 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: {
pageId: "example",
params: {
// cause target page has registered a url-param with name "exampleId" == exampleNameUrlParam.name
// passing values to page to generate final link
exampleId: "demo-2"
exampleId: "demo-sample-2"
},
},
},

View File

@ -43,15 +43,17 @@ export class ClusterPageMenuRegistry extends PageMenuRegistry<ClusterPageMenuReg
}
getSubItems(parent: ClusterPageMenuRegistration) {
return this.getItems().filter((item) => {
return item.parentId === parent.id && item.target.extensionId === parent.target.extensionId;
});
return this.getItems().filter((item) => (
item.parentId === parent.id &&
item.target.extensionId === parent.target.extensionId
));
}
getByPage({ id: pageId, extensionId }: RegisteredPage) {
return this.getItems().find((item) => {
return item.target.pageId == pageId && item.target.extensionId === extensionId;
});
return this.getItems().find((item) => (
item.target.pageId == pageId &&
item.target.extensionId === extensionId
));
}
}

View File

@ -1,11 +1,9 @@
// Extensions-api -> Custom page registration
import type React from "react";
import type { UrlParam } from "../../renderer/navigation/url-param";
import path from "path";
import { action } from "mobx";
import { BaseRegistry } from "./base-registry";
import { LensExtension, sanitizeExtensionName } from "../lens-extension";
import { UrlParam } from "../../renderer/navigation/url-param";
import logger from "../../main/logger";
export interface PageRegistration {
@ -17,19 +15,24 @@ export interface PageRegistration {
components: PageComponents;
/**
* 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 {
Page: React.ComponentType<any>;
}
export interface PageTarget<P = {}> {
export interface PageTarget<P = PageTargetParams> {
extensionId?: 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 {
@ -38,27 +41,26 @@ export interface RegisteredPage extends PageRegistration {
}
export function getExtensionPageUrl(target: PageTarget): string {
const { extensionId, pageId = "", params: targetParams = {} } = target;
let stringifiedParams = "";
const { extensionId, pageId = "", params: targetPageParams = {} } = target;
const pagePath = ["/extension", sanitizeExtensionName(extensionId), pageId].join("/");
const pageUrl = new URL(pagePath, `http://localhost`);
// 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) {
const searchParams = page.params.map(urlParam => {
return urlParam.toSearchString({
value: targetParams[urlParam.name] ?? urlParam.getDefaultValue(),
mergeGlobals: false,
withPrefix: false,
});
});
if (searchParams.length > 0) {
stringifiedParams = `?${searchParams.join("&")}`;
}
if (targetPage?.params) {
Object.entries(targetPage.params).forEach(([name, param]) => {
const paramValue = targetPageParams[name];
if (param instanceof UrlParam) {
pageUrl.searchParams.set(name, param.stringify(paramValue));
} else {
pageUrl.searchParams.set(name, String(paramValue ?? param));
}
})
}
return path.posix.join("/extension", sanitizeExtensionName(extensionId), pageId, stringifiedParams);
return pageUrl.href.replace(pageUrl.origin, "");
}
export class PageRegistry extends BaseRegistry<RegisteredPage> {