1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/extensions/registries/page-registry.ts
Roman 39fc5a7f84 lint fixes, revert tests
Signed-off-by: Roman <ixrock@gmail.com>
2020-12-03 20:43:50 +02:00

98 lines
3.0 KiB
TypeScript

// 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 logger from "../../main/logger";
export interface PageRegistration {
/**
* Page-id, part of of extension's page url, must be unique within same extension
* When not provided, first registered page without "id" would be used for page-menus without target.pageId for same extension
*/
id?: string;
components: PageComponents;
/**
* Registered page params.
* Used to generate page url when provided in getExtensionPageUrl()-helper.
*/
params?: UrlParam[];
}
export interface PageComponents {
Page: React.ComponentType<any>;
}
export interface PageTarget<P = {}> {
extensionId?: string;
pageId?: string;
params?: Record<string, any | any[]> & P; // default target page params
}
export interface RegisteredPage extends PageRegistration {
extensionId: string;
url: string; // registered extension's page URL (without page params)
}
export function getExtensionPageUrl(target: PageTarget): string {
const { extensionId, pageId = "", params: targetParams = {} } = target;
let stringifiedParams = "";
// stringify params to matched target page
const page = 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("&")}`;
}
}
return path.posix.join("/extension", sanitizeExtensionName(extensionId), pageId, stringifiedParams);
}
export class PageRegistry extends BaseRegistry<RegisteredPage> {
@action
add(pages: PageRegistration | PageRegistration[], extension: LensExtension) {
try {
const items = [pages].flat().map(page => this.registerPage(page, extension));
return super.add(items);
} catch (error) {
return Function; // no-op
}
}
registerPage(page: PageRegistration, ext: LensExtension): RegisteredPage {
try {
const { id: pageId } = page;
const extensionId = ext.name;
return {
...page,
extensionId,
url: getExtensionPageUrl({ extensionId, pageId }),
};
} catch (error) {
logger.error(`Failed to register page: ${error}`, { error });
}
}
getByPageTarget(target: PageTarget): RegisteredPage | null {
return this.getItems().find(page => page.extensionId === target.extensionId && page.id === target.pageId) || null;
}
}
export const globalPageRegistry = new PageRegistry();
export const clusterPageRegistry = new PageRegistry();