mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add common app routes to the protocol renderer router (#2272)
This commit is contained in:
1 parent
ca39379b3a
commit
0561f6bfd0
17 files changed
+129
-33
No files matched your search
@@ -184,10 +184,12 @@ export abstract class LensProtocolRouter extends Singleton {
|
||||
* @param pathSchema the URI path schema to match against for this handler
|
||||
* @param handler a function that will be called if a protocol path matches
|
||||
*/
|
||||
public addInternalHandler(urlSchema: string, handler: RouteHandler): void {
|
||||
public addInternalHandler(urlSchema: string, handler: RouteHandler): this {
|
||||
pathToRegexp(urlSchema); // verify now that the schema is valid
|
||||
logger.info(`${LensProtocolRouter.LoggingPrefix}: internal registering ${urlSchema}`);
|
||||
this.internalRoutes.set(urlSchema, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,14 +3,20 @@ import { compile } from "path-to-regexp";
|
||||
export interface IURLParams<P extends object = {}, Q extends object = {}> {
|
||||
params?: P;
|
||||
query?: Q;
|
||||
fragment?: string;
|
||||
}
|
||||
|
||||
export function buildURL<P extends object = {}, Q extends object = {}>(path: string | any) {
|
||||
const pathBuilder = compile(String(path));
|
||||
|
||||
return function ({ params, query }: IURLParams<P, Q> = {}) {
|
||||
return function ({ params, query, fragment }: IURLParams<P, Q> = {}): string {
|
||||
const queryParams = query ? new URLSearchParams(Object.entries(query)).toString() : "";
|
||||
const parts = [
|
||||
pathBuilder(params),
|
||||
queryParams && `?${queryParams}`,
|
||||
fragment && `#${fragment}`,
|
||||
];
|
||||
|
||||
return pathBuilder(params) + (queryParams ? `?${queryParams}` : "");
|
||||
return parts.filter(Boolean).join("");
|
||||
};
|
||||
}
|
||||
@@ -8,10 +8,21 @@ export interface AppPreferenceComponents {
|
||||
|
||||
export interface AppPreferenceRegistration {
|
||||
title: string;
|
||||
id?: string;
|
||||
components: AppPreferenceComponents;
|
||||
}
|
||||
|
||||
export class AppPreferenceRegistry extends BaseRegistry<AppPreferenceRegistration> {
|
||||
export interface RegisteredAppPreference extends AppPreferenceRegistration {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export class AppPreferenceRegistry extends BaseRegistry<AppPreferenceRegistration, RegisteredAppPreference> {
|
||||
getRegisteredItem(item: AppPreferenceRegistration): RegisteredAppPreference {
|
||||
return {
|
||||
id: item.id || item.title.toLowerCase().replace(/[^0-9a-zA-Z]+/g, "-"),
|
||||
...item,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const appPreferenceRegistry = new AppPreferenceRegistry();
|
||||
@@ -1,8 +1,8 @@
|
||||
import "./preferences.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { computed, observable, reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
|
||||
import { userStore } from "../../../common/user-store";
|
||||
import { isWindows } from "../../../common/vars";
|
||||
@@ -16,6 +16,7 @@ import { Select, SelectOption } from "../select";
|
||||
import { HelmCharts } from "./helm-charts";
|
||||
import { KubectlBinaries } from "./kubectl-binaries";
|
||||
import { ScrollSpy } from "../scroll-spy/scroll-spy";
|
||||
import { navigation } from "../../navigation";
|
||||
|
||||
@observer
|
||||
export class Preferences extends React.Component {
|
||||
@@ -29,6 +30,21 @@ export class Preferences extends React.Component {
|
||||
}));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => navigation.location.hash, hash => {
|
||||
const fragment = hash.slice(1); // hash is /^(#\w.)?$/
|
||||
|
||||
if (fragment) {
|
||||
// ignore empty framents
|
||||
document.getElementById(fragment)?.scrollIntoView();
|
||||
}
|
||||
}, {
|
||||
fireImmediately: true
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { preferences } = userStore;
|
||||
const header = <h2>Preferences</h2>;
|
||||
@@ -133,10 +149,10 @@ export class Preferences extends React.Component {
|
||||
<section>
|
||||
<h1>Extensions</h1>
|
||||
</section>
|
||||
{appPreferenceRegistry.getItems().map(({ title, components: { Hint, Input } }, index) => {
|
||||
{appPreferenceRegistry.getItems().map(({ title, id, components: { Hint, Input } }, index) => {
|
||||
return (
|
||||
<section key={index} id={title}>
|
||||
<h2>{title}</h2>
|
||||
<h2 id={id}>{title}</h2>
|
||||
<Input/>
|
||||
<small className="hint">
|
||||
<Hint/>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ConfirmDialog } from "./components/confirm-dialog";
|
||||
import { extensionLoader } from "../extensions/extension-loader";
|
||||
import { broadcastMessage } from "../common/ipc";
|
||||
import { CommandContainer } from "./components/command-palette/command-container";
|
||||
import { LensProtocolRouterRenderer } from "./protocol-handler/router";
|
||||
import { LensProtocolRouterRenderer, bindProtocolAddRouteHandlers } from "./protocol-handler";
|
||||
import { registerIpcHandlers } from "./ipc";
|
||||
import { ipcRenderer } from "electron";
|
||||
|
||||
@@ -21,6 +21,7 @@ export class LensApp extends React.Component {
|
||||
static async init() {
|
||||
extensionLoader.loadOnClusterManagerRenderer();
|
||||
LensProtocolRouterRenderer.getInstance<LensProtocolRouterRenderer>().init();
|
||||
bindProtocolAddRouteHandlers();
|
||||
window.addEventListener("offline", () => {
|
||||
broadcastMessage("network:offline");
|
||||
});
|
||||
|
||||
@@ -5,11 +5,11 @@ import { clusterViewRoute, IClusterViewRouteParams } from "../components/cluster
|
||||
import { navigation } from "./history";
|
||||
|
||||
export function navigate(location: LocationDescriptor) {
|
||||
const currentLocation = navigation.getPath();
|
||||
const currentLocation = navigation.location.pathname;
|
||||
|
||||
navigation.push(location);
|
||||
|
||||
if (currentLocation === navigation.getPath()) {
|
||||
if (currentLocation === navigation.location.pathname) {
|
||||
navigation.goBack(); // prevent sequences of same url in history
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ navigation.listen((location, action) => {
|
||||
const isClusterView = !process.isMainFrame;
|
||||
const domain = global.location.href;
|
||||
|
||||
logger.debug(`[NAVIGATION]: ${action}`, { isClusterView, domain, location });
|
||||
logger.debug(`[NAVIGATION]: ${action}-ing. Current is now:`, { isClusterView, domain, location });
|
||||
});
|
||||
@@ -1,10 +1,8 @@
|
||||
// Navigation (renderer)
|
||||
|
||||
import { bindEvents } from "./events";
|
||||
import { bindProtocolHandlers } from "./protocol-handlers";
|
||||
|
||||
export * from "./history";
|
||||
export * from "./helpers";
|
||||
|
||||
bindEvents();
|
||||
bindProtocolHandlers();
|
||||
@@ -1,10 +0,0 @@
|
||||
import { LensProtocolRouterRenderer } from "../protocol-handler/router";
|
||||
import { navigate } from "./helpers";
|
||||
|
||||
export function bindProtocolHandlers() {
|
||||
const lprr = LensProtocolRouterRenderer.getInstance<LensProtocolRouterRenderer>();
|
||||
|
||||
lprr.addInternalHandler("/preferences", () => {
|
||||
navigate("/preferences");
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { addClusterURL } from "../components/+add-cluster";
|
||||
import { clusterSettingsURL } from "../components/+cluster-settings";
|
||||
import { extensionsURL } from "../components/+extensions";
|
||||
import { landingURL } from "../components/+landing-page";
|
||||
import { preferencesURL } from "../components/+preferences";
|
||||
import { clusterViewURL } from "../components/cluster-manager/cluster-view.route";
|
||||
import { LensProtocolRouterRenderer } from "./router";
|
||||
import { navigate } from "../navigation/helpers";
|
||||
import { clusterStore } from "../../common/cluster-store";
|
||||
import { workspaceStore } from "../../common/workspace-store";
|
||||
|
||||
export function bindProtocolAddRouteHandlers() {
|
||||
LensProtocolRouterRenderer
|
||||
.getInstance<LensProtocolRouterRenderer>()
|
||||
.addInternalHandler("/preferences", ({ search: { highlight }}) => {
|
||||
navigate(preferencesURL({ fragment: highlight }));
|
||||
})
|
||||
.addInternalHandler("/", () => {
|
||||
navigate(landingURL());
|
||||
})
|
||||
.addInternalHandler("/landing", () => {
|
||||
navigate(landingURL());
|
||||
})
|
||||
.addInternalHandler("/landing/:workspaceId", ({ pathname: { workspaceId } }) => {
|
||||
if (workspaceStore.getById(workspaceId)) {
|
||||
workspaceStore.setActive(workspaceId);
|
||||
navigate(landingURL());
|
||||
} else {
|
||||
console.log("[APP-HANDLER]: workspace with given ID does not exist", { workspaceId });
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/cluster", () => {
|
||||
navigate(addClusterURL());
|
||||
})
|
||||
.addInternalHandler("/cluster/:clusterId", ({ pathname: { clusterId } }) => {
|
||||
const cluster = clusterStore.getById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
workspaceStore.setActive(cluster.workspace);
|
||||
navigate(clusterViewURL({ params: { clusterId } }));
|
||||
} else {
|
||||
console.log("[APP-HANDLER]: cluster with given ID does not exist", { clusterId });
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/cluster/:clusterId/settings", ({ pathname: { clusterId } }) => {
|
||||
const cluster = clusterStore.getById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
workspaceStore.setActive(cluster.workspace);
|
||||
navigate(clusterSettingsURL({ params: { clusterId } }));
|
||||
} else {
|
||||
console.log("[APP-HANDLER]: cluster with given ID does not exist", { clusterId });
|
||||
}
|
||||
})
|
||||
.addInternalHandler("/extensions", () => {
|
||||
navigate(extensionsURL());
|
||||
});
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from "./router.ts";
|
||||
export * from "./router";
|
||||
export * from "./app-handlers";
|
||||
Reference in new issue
Block a user