1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

moving cluster-settings view lens-app views (common)

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-08-12 18:44:17 +03:00
parent 67ef29372c
commit 2e9bb3e926
13 changed files with 55 additions and 43 deletions

View File

@ -1,3 +1,4 @@
import type { ClusterId } from "../common/cluster-store";
import { app, BrowserWindow, dialog, Menu, MenuItem, MenuItemConstructorOptions, shell } from "electron" import { app, BrowserWindow, dialog, Menu, MenuItem, MenuItemConstructorOptions, shell } from "electron"
import { autorun } from "mobx"; import { autorun } from "mobx";
import { WindowManager } from "./window-manager"; import { WindowManager } from "./window-manager";
@ -29,12 +30,12 @@ export function buildMenu(windowManager: WindowManager) {
return menuItems; return menuItems;
} }
function navigate(url: string, toClusterView = false) { function navigate(url: string, clusterId?: ClusterId) {
logger.info(`[MENU]: navigating to ${url}`); logger.info(`[MENU]: navigating to ${url}`);
windowManager.navigate({ windowManager.navigate({
channel: "menu:navigate", channel: "menu:navigate",
url: url, url: url,
clusterId: toClusterView ? windowManager.activeClusterId : null, clusterId: clusterId,
}) })
} }
@ -100,7 +101,11 @@ export function buildMenu(windowManager: WindowManager) {
{ {
label: 'Cluster Settings', label: 'Cluster Settings',
click() { click() {
navigate(clusterSettingsURL(), true) navigate(clusterSettingsURL({
params: {
clusterId: windowManager.activeClusterId
}
}))
} }
} }
]), ]),

View File

@ -1,8 +1,12 @@
import type { IClusterViewRouteParams } from "../cluster-manager/cluster-view.route";
import { RouteProps } from "react-router"; import { RouteProps } from "react-router";
import { buildURL } from "../../navigation"; import { buildURL } from "../../navigation";
export const clusterSettingsRoute: RouteProps = { export interface IClusterSettingsRouteParams extends IClusterViewRouteParams {
path: "/cluster-settings"
} }
export const clusterSettingsURL = buildURL(clusterSettingsRoute.path) export const clusterSettingsRoute: RouteProps = {
path: `/cluster/:clusterId/settings`,
}
export const clusterSettingsURL = buildURL<IClusterSettingsRouteParams>(clusterSettingsRoute.path)

View File

@ -7,15 +7,15 @@ import { Features } from "./features";
import { Removal } from "./removal"; import { Removal } from "./removal";
import { Status } from "./status"; import { Status } from "./status";
import { General } from "./general"; import { General } from "./general";
import { getHostedCluster } from "../../../common/cluster-store";
import { WizardLayout } from "../layout/wizard-layout"; import { WizardLayout } from "../layout/wizard-layout";
import { ClusterIcon } from "../cluster-icon"; import { ClusterIcon } from "../cluster-icon";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { getMatchedCluster } from "../cluster-manager/cluster-view.route";
@observer @observer
export class ClusterSettings extends React.Component { export class ClusterSettings extends React.Component {
render() { render() {
const cluster = getHostedCluster(); const cluster = getMatchedCluster();
const header = ( const header = (
<> <>
<ClusterIcon <ClusterIcon
@ -25,7 +25,7 @@ export class ClusterSettings extends React.Component {
/> />
<h2>{cluster.preferences.clusterName}</h2> <h2>{cluster.preferences.clusterName}</h2>
<Link to="/"> <Link to="/">
<Icon material="close" big /> <Icon material="close" big/>
</Link> </Link>
</> </>
); );

View File

@ -28,7 +28,6 @@ import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale
import { CustomResources } from "./+custom-resources/custom-resources"; import { CustomResources } from "./+custom-resources/custom-resources";
import { crdRoute } from "./+custom-resources"; import { crdRoute } from "./+custom-resources";
import { isAllowedResource } from "../../common/rbac"; import { isAllowedResource } from "../../common/rbac";
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
import { ErrorBoundary } from "./error-boundary"; import { ErrorBoundary } from "./error-boundary";
import { Terminal } from "./dock/terminal"; import { Terminal } from "./dock/terminal";
import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store"; import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store";
@ -56,7 +55,6 @@ export class App extends React.Component {
<ErrorBoundary> <ErrorBoundary>
<Switch> <Switch>
<Route component={Cluster} {...clusterRoute}/> <Route component={Cluster} {...clusterRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Nodes} {...nodesRoute}/> <Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/> <Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/> <Route component={Config} {...configRoute}/>

View File

@ -6,26 +6,22 @@
height: 100%; height: 100%;
main { main {
grid-area: main;
position: relative; position: relative;
grid-area: main;
display: flex; display: flex;
> * { > * {
flex: 1; position: absolute;
} left: 0;
} top: 0;
right: 0;
bottom: 0;
display: flex;
background-color: $mainBackground;
#lens-views { > * {
grid-area: main; flex: 1;
display: flex; }
overflow: hidden;
&.active {
z-index: 1;
}
> * {
flex: 1;
} }
} }

View File

@ -3,7 +3,6 @@ import React from "react";
import { Redirect, Route, Switch } from "react-router"; import { Redirect, Route, Switch } from "react-router";
import { reaction } from "mobx"; import { reaction } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { cssNames } from "../../utils";
import { ClustersMenu } from "./clusters-menu"; import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar"; import { BottomBar } from "./bottom-bar";
import { LandingPage, landingRoute, landingURL } from "../+landing-page"; import { LandingPage, landingRoute, landingURL } from "../+landing-page";
@ -11,6 +10,7 @@ import { Preferences, preferencesRoute } from "../+preferences";
import { Workspaces, workspacesRoute } from "../+workspaces"; import { Workspaces, workspacesRoute } from "../+workspaces";
import { AddCluster, addClusterRoute } from "../+add-cluster"; import { AddCluster, addClusterRoute } from "../+add-cluster";
import { ClusterView } from "./cluster-view"; import { ClusterView } from "./cluster-view";
import { ClusterSettings, clusterSettingsRoute } from "../+cluster-settings";
import { clusterViewRoute, clusterViewURL, getMatchedCluster, getMatchedClusterId } from "./cluster-view.route"; import { clusterViewRoute, clusterViewURL, getMatchedCluster, getMatchedClusterId } from "./cluster-view.route";
import { clusterStore } from "../../../common/cluster-store"; import { clusterStore } from "../../../common/cluster-store";
import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views"; import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views";
@ -48,18 +48,18 @@ export class ClusterManager extends React.Component {
} }
render() { render() {
const cluster = getMatchedCluster();
return ( return (
<div className="ClusterManager"> <div className="ClusterManager">
<div id="draggable-top"/> <div id="draggable-top"/>
<div id="lens-views" className={cssNames({ active: !!cluster })}/>
<main> <main>
<div id="lens-views"/>
<Switch> <Switch>
<Route component={LandingPage} {...landingRoute}/> <Route component={LandingPage} {...landingRoute}/>
<Route component={Preferences} {...preferencesRoute}/> <Route component={Preferences} {...preferencesRoute}/>
<Route component={Workspaces} {...workspacesRoute}/> <Route component={Workspaces} {...workspacesRoute}/>
<Route component={AddCluster} {...addClusterRoute}/> <Route component={AddCluster} {...addClusterRoute}/>
<Route component={ClusterView} {...clusterViewRoute}/> <Route component={ClusterView} {...clusterViewRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Redirect exact to={this.startUrl}/> <Redirect exact to={this.startUrl}/>
</Switch> </Switch>
</main> </main>

View File

@ -67,7 +67,7 @@ export class ClusterStatus extends React.Component<Props> {
const failureReason = cluster.failureReason; const failureReason = cluster.failureReason;
const isError = hasErrors || isDisconnected; const isError = hasErrors || isDisconnected;
return ( return (
<div className={cssNames("ClusterStatus flex column gaps", this.props.className)}> <div className={cssNames("ClusterStatus flex column gaps box center", this.props.className)}>
{isError && ( {isError && (
<Icon <Icon
material="cloud_off" material="cloud_off"
@ -75,7 +75,7 @@ export class ClusterStatus extends React.Component<Props> {
/> />
)} )}
<h2> <h2>
{cluster.contextName} {cluster.preferences.clusterName}
</h2> </h2>
{!isDisconnected && ( {!isDisconnected && (
<pre className="kube-auth-out"> <pre className="kube-auth-out">

View File

@ -3,21 +3,26 @@ import { ipcRenderer } from "electron";
import { matchPath, RouteProps } from "react-router"; import { matchPath, RouteProps } from "react-router";
import { buildURL, navigation } from "../../navigation"; import { buildURL, navigation } from "../../navigation";
import { clusterStore, getHostedClusterId } from "../../../common/cluster-store"; import { clusterStore, getHostedClusterId } from "../../../common/cluster-store";
import { clusterSettingsRoute } from "../+cluster-settings/cluster-settings.route";
export interface IClusterViewRouteParams { export interface IClusterViewRouteParams {
clusterId: string; clusterId: string;
} }
export const clusterViewRoute: RouteProps = { export const clusterViewRoute: RouteProps = {
path: "/cluster/:clusterId" exact: true,
path: "/cluster/:clusterId",
} }
export const clusterViewURL = buildURL<IClusterViewRouteParams>(clusterViewRoute.path) export const clusterViewURL = buildURL<IClusterViewRouteParams>(clusterViewRoute.path)
export function getMatchedClusterId(): string { export function getMatchedClusterId(): string {
const matched = matchPath<IClusterViewRouteParams>(navigation.location.pathname, { const matched = matchPath<IClusterViewRouteParams>(navigation.location.pathname, {
...clusterViewRoute,
exact: true, exact: true,
path: [
clusterViewRoute.path,
clusterSettingsRoute.path,
].flat(),
}) })
if (matched) { if (matched) {
return matched.params.clusterId; return matched.params.clusterId;

View File

@ -1,7 +1,5 @@
.ClusterView { .ClusterView {
position: relative; &:empty {
width: 100%; display: none;
height: 100%; }
display: flex;
flex: 1;
} }

View File

@ -11,7 +11,7 @@ export class ClusterView extends React.Component {
const cluster = getMatchedCluster(); const cluster = getMatchedCluster();
const showStatus = cluster && (!cluster.available || !hasLoadedView(cluster.id)) const showStatus = cluster && (!cluster.available || !hasLoadedView(cluster.id))
return ( return (
<div className="ClusterView flex column"> <div className="ClusterView">
{showStatus && ( {showStatus && (
<ClusterStatus key={cluster.id} clusterId={cluster.id} className="box center"/> <ClusterStatus key={cluster.id} clusterId={cluster.id} className="box center"/>
)} )}

View File

@ -21,7 +21,6 @@ import { Tooltip } from "../tooltip";
import { ConfirmDialog } from "../confirm-dialog"; import { ConfirmDialog } from "../confirm-dialog";
import { clusterIpc } from "../../../common/cluster-ipc"; import { clusterIpc } from "../../../common/cluster-ipc";
import { clusterViewURL, getMatchedClusterId } from "./cluster-view.route"; import { clusterViewURL, getMatchedClusterId } from "./cluster-view.route";
import { navigateInClusterView } from "./lens-views";
// fixme: allow to rearrange clusters with drag&drop // fixme: allow to rearrange clusters with drag&drop
@ -49,7 +48,11 @@ export class ClustersMenu extends React.Component<Props> {
menu.append(new MenuItem({ menu.append(new MenuItem({
label: _i18n._(t`Settings`), label: _i18n._(t`Settings`),
click: () => { click: () => {
navigateInClusterView(clusterSettingsURL(), cluster.id) navigate(clusterSettingsURL({
params: {
clusterId: cluster.id
}
}))
} }
})); }));
if (cluster.online) { if (cluster.online) {

View File

@ -48,11 +48,12 @@ export class MainLayout extends React.Component<Props> {
render() { render() {
const { className, contentClass, headerClass, tabs, footer, footerClass, children } = this.props; const { className, contentClass, headerClass, tabs, footer, footerClass, children } = this.props;
const routePath = navigation.location.pathname; const routePath = navigation.location.pathname;
const cluster = getHostedCluster();
return ( return (
<div className={cssNames("MainLayout", className, themeStore.activeTheme.type)}> <div className={cssNames("MainLayout", className, themeStore.activeTheme.type)}>
<header className={cssNames("flex gaps align-center", headerClass)}> <header className={cssNames("flex gaps align-center", headerClass)}>
<span className="cluster"> <span className="cluster">
{getHostedCluster().contextName} {cluster.preferences?.clusterName || cluster.contextName}
</span> </span>
</header> </header>

View File

@ -12,7 +12,7 @@ export const navigation = createObservableHistory(history);
// handle navigation from other process (e.g. system menus in main, common->cluster view interactions) // handle navigation from other process (e.g. system menus in main, common->cluster view interactions)
if (ipcRenderer) { if (ipcRenderer) {
ipcRenderer.on("menu:navigate", (event, location: LocationDescriptor) => { ipcRenderer.on("menu:navigate", (event, location: LocationDescriptor) => {
logger.info(`Navigation via IPC to location: ${JSON.stringify(location)}`, event); logger.info(`[IPC]: ${event.type} ${JSON.stringify(location)}`, event);
navigate(location); navigate(location);
}) })
} }
@ -26,6 +26,8 @@ export interface IURLParams<P = {}, Q = {}> {
query?: IQueryParams & Q; query?: IQueryParams & Q;
} }
// todo: extract building urls to commons (also used in menu.ts)
// fixme: missing types validation for params & query
export function buildURL<P extends object, Q = object>(path: string | string[]) { export function buildURL<P extends object, Q = object>(path: string | string[]) {
const pathBuilder = compile(path.toString()); const pathBuilder = compile(path.toString());
return function ({ params, query }: IURLParams<P, Q> = {}) { return function ({ params, query }: IURLParams<P, Q> = {}) {