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

added more routes, refactoring

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-07-15 14:09:31 +03:00
parent e5aff1fdc8
commit d20e61b3e2
22 changed files with 119 additions and 58 deletions

View File

@ -25,14 +25,14 @@ export function broadcastMessage({ channel, filter }: IpcBroadcastOpts, ...args:
filter = webContent => webContent.getType() === "window"
}
webContents.getAllWebContents().filter(filter).forEach(webContent => {
logger.info(`[IPC]: broadcasting ${channel} to ${webContent.getType()}=${webContent.id}`);
logger.debug(`[IPC]: broadcasting ${channel} to ${webContent.getType()}=${webContent.id}`);
webContent.send(channel, ...args);
})
}
// fixme: support timeout
// todo: support timeout
export async function invokeMessage<T = any>(channel: IpcChannel, ...args: any[]): Promise<T> {
logger.info(`[IPC]: invoke channel "${channel}"`, { args });
logger.debug(`[IPC]: invoke channel "${channel}"`, { args });
return ipcRenderer.invoke(channel, ...args);
}

View File

@ -24,7 +24,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
});
}
@observable currentWorkspace = WorkspaceStore.defaultId;
@observable currentWorkspaceId = WorkspaceStore.defaultId;
@observable workspaces = observable.map<WorkspaceId, Workspace>({
[WorkspaceStore.defaultId]: {
@ -33,6 +33,10 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
}
});
@computed get currentWorkspace(): Workspace {
return this.getById(this.currentWorkspaceId);
}
@computed get workspacesList() {
return Array.from(this.workspaces.values());
}
@ -41,12 +45,6 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
return this.workspaces.get(id);
}
@action
setCurrent(id: WorkspaceId) {
if (!this.getById(id)) return;
this.currentWorkspace = id;
}
@action
public saveWorkspace(workspace: Workspace) {
const id = workspace.id;
@ -65,8 +63,8 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
if (id === WorkspaceStore.defaultId) {
throw new Error("Cannot remove default workspace");
}
if (id === this.currentWorkspace) {
this.currentWorkspace = WorkspaceStore.defaultId;
if (id === this.currentWorkspaceId) {
this.currentWorkspaceId = WorkspaceStore.defaultId;
}
this.workspaces.delete(id);
clusterStore.removeByWorkspaceId(id)
@ -75,7 +73,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
@action
protected fromStore({ currentWorkspace, workspaces = [] }: WorkspaceStoreModel) {
if (currentWorkspace) {
this.currentWorkspace = currentWorkspace
this.currentWorkspaceId = currentWorkspace
}
if (workspaces.length) {
this.workspaces.clear();
@ -87,7 +85,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
toJSON(): WorkspaceStoreModel {
return toJS({
currentWorkspace: this.currentWorkspace,
currentWorkspace: this.currentWorkspaceId,
workspaces: this.workspacesList,
}, {
recurseEverything: true

View File

@ -1,11 +1,11 @@
import "./add-cluster.scss"
import React from "react";
import { observable } from "mobx";
import { observer } from "mobx-react";
interface Props {
}
@observable
@observer
export class AddCluster extends React.Component<Props> {
render() {
return (

View File

@ -0,0 +1,8 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const clusterSettingsRoute: RouteProps = {
path: "/cluster-settings"
}
export const clusterSettingsURL = buildURL(clusterSettingsRoute.path)

View File

@ -1,9 +1,8 @@
import "./cluster-settings.scss"
import React from "react";
import { observer } from "mobx-react";
interface Props {
}
@observer
export class ClusterSettings extends React.Component {
render() {
return (

View File

@ -1 +1,2 @@
export * from "./cluster-settings.route"
export * from "./cluster-settings"

View File

@ -0,0 +1 @@
export * from "./landing-page"

View File

@ -1,9 +1,8 @@
import "./landing-page.scss"
import React from "react";
import { observer } from "mobx-react";
interface Props {
}
@observer
export class LandingPage extends React.Component {
render() {
return (

View File

@ -0,0 +1,2 @@
export * from "./preferences.route"
export * from "./preferences"

View File

@ -0,0 +1,8 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const preferencesRoute: RouteProps = {
path: "/preferences"
}
export const preferencesURL = buildURL(preferencesRoute.path)

View File

@ -1,9 +1,8 @@
import "./preferences.scss"
import React from "react";
import { observer } from "mobx-react";
interface Props {
}
@observer
export class Preferences extends React.Component {
render() {
return (

View File

@ -0,0 +1,2 @@
export * from "./whats-new.route"
export * from "./whats-new"

View File

@ -0,0 +1,8 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const whatsNewRoute: RouteProps = {
path: "/what-s-new"
}
export const whatsNewURL = buildURL(whatsNewRoute.path)

View File

@ -1,9 +1,8 @@
import "./whats-new.scss"
import React from "react";
import { observer } from "mobx-react";
interface Props {
}
@observer
export class WhatsNew extends React.Component {
render() {
return (

View File

@ -1 +1,2 @@
export * from "./workspaces.route"
export * from "./workspaces"

View File

@ -0,0 +1,8 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const workspacesRoute: RouteProps = {
path: "/workspaces"
}
export const workspacesURL = buildURL(workspacesRoute.path)

View File

@ -1,6 +1,8 @@
import "./workspaces.scss"
import React from "react";
import { observer } from "mobx-react";
@observer
export class Workspaces extends React.Component {
render() {
return (

View File

@ -1,6 +1,7 @@
import "./app.scss";
import React, { Fragment } from "react";
import { observer } from "mobx-react";
import { i18nStore } from "../i18n";
import { configStore } from "../config.store";
import { Terminal } from "./dock/terminal";
@ -29,7 +30,12 @@ import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale
import { CustomResources } from "./+custom-resources/custom-resources";
import { crdRoute } from "./+custom-resources";
import { isAllowedResource } from "../api/rbac";
import { AddCluster, addClusterRoute } from "./+add-cluster";
import { LandingPage } from "./+landing-page";
import { clusterStore } from "../../common/cluster-store";
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
@observer
export class App extends React.Component {
static rootElem = document.getElementById('app');
@ -40,11 +46,15 @@ export class App extends React.Component {
}
render() {
const showLanding = clusterStore.clusters.size === 0;
const homeUrl = isAllowedResource(["events", "nodes", "pods"]) ? clusterURL() : workloadsURL();
return (
<Fragment>
<Switch>
<Switch>
{showLanding && <Route component={LandingPage}/>}
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Cluster} {...clusterRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>

View File

@ -1,10 +1,13 @@
.BottomBar {
$spacing: $padding / 2;
font-size: $font-size-small;
background-color: #3d90ce;
padding: $padding / 2 $padding;
padding: $spacing $padding;
color: white;
#workspace {
#current-workspace {
--flex-gap: #{$spacing};
cursor: pointer;
}
}

View File

@ -1,5 +1,4 @@
import "./bottom-bar.scss"
import React from "react";
import { observable } from "mobx";
import { observer } from "mobx-react";
@ -7,41 +6,47 @@ import { Link } from "react-router-dom";
import { Trans } from "@lingui/macro";
import { Icon } from "../icon";
import { Menu, MenuItem } from "../menu";
import { prevDefault } from "../../utils";
import { workspaceStore } from "../../../common/workspace-store";
// todo: remove dummy actions + console.log
import { WorkspaceId, workspaceStore } from "../../../common/workspace-store";
import { workspacesURL } from "../+workspaces";
@observer
export class BottomBar extends React.Component {
@observable menuVisible = false;
selectWorkspace = (workspaceId: WorkspaceId) => {
workspaceStore.currentWorkspaceId = workspaceId;
}
render() {
const { currentWorkspace, workspacesList } = workspaceStore;
const menuId = "workspaces-menu"
return (
<div className="BottomBar flex gaps">
<div id="workspace" className="workspace flex align-center box right">
<Icon small material="layers"/> {currentWorkspace}
<div id="current-workspace" className="flex gaps align-center box right">
<Icon small material="layers"/>
<span className="workspace-name">{currentWorkspace.name}</span>
</div>
<Menu
usePortal
htmlFor="workspace"
id="workspace-menu"
htmlFor="current-workspace"
isOpen={this.menuVisible}
open={() => this.menuVisible = true}
close={() => this.menuVisible = false}
>
<Link
to="#"
className="workspaces-title"
onClick={prevDefault(() => console.log('/navigate: workspaces page'))}>
<Link className="workspaces-title" to={workspacesURL()}>
<Trans>Workspaces</Trans>
</Link>
{workspacesList.map(workspace => {
const { id, name, description } = workspace;
{workspacesList.map(({ id, name, description }) => {
return (
<MenuItem key={id} onClick={() => console.log(`navigate: /workspaces/${id}`)} title={description}>
<Icon small material="layers"/> {name}
<MenuItem
key={id}
active={id === currentWorkspace.id}
onClick={() => this.selectWorkspace(id)}
title={description}
>
<Icon small material="layers"/>
<span className="workspace">{name}</span>
</MenuItem>
)
})}

View File

@ -13,7 +13,7 @@ export interface ClusterContextValue {
export function getClusterContext(): ClusterContextValue {
return {
clusterId: clusterStore.activeClusterId,
workspaceId: workspaceStore.currentWorkspace,
workspaceId: workspaceStore.currentWorkspaceId,
}
}

View File

@ -6,12 +6,15 @@ import { _i18n } from "../../i18n";
import { t, Trans } from "@lingui/macro";
import type { Cluster } from "../../../main/cluster";
import { userStore } from "../../../common/user-store";
import { clusterStore } from "../../../common/cluster-store";
import { ClusterId, clusterStore } from "../../../common/cluster-store";
import { workspaceStore } from "../../../common/workspace-store";
import { ClusterIcon } from "../+cluster-settings/cluster-icon";
import { Icon } from "../icon";
import { cssNames, IClassName } from "../../utils";
import { Badge } from "../badge";
import { navigate } from "../../navigation";
import { addClusterURL } from "../+add-cluster";
import { clusterSettingsURL } from "../+cluster-settings";
// fixme: allow to rearrange clusters with drag&drop
// fixme: make add-icon's tooltip visible on init
@ -22,13 +25,16 @@ interface Props {
@observer
export class ClustersMenu extends React.Component<Props> {
showCluster = (cluster: Cluster) => {
clusterStore.activeClusterId = cluster.id;
console.log('show lens for cluster:', cluster.contextName);
showCluster = (clusterId: ClusterId) => {
if (clusterStore.activeClusterId === clusterId) {
navigate("/"); // redirect to index
} else {
clusterStore.activeClusterId = clusterId;
}
}
addCluster = () => {
console.log('navigate: /add-cluster')
navigate(addClusterURL());
}
showContextMenu = (cluster: Cluster) => {
@ -37,15 +43,17 @@ export class ClustersMenu extends React.Component<Props> {
menu.append(new MenuItem({
label: _i18n._(t`Settings`),
click: () => console.log(`navigate to cluster settings`, cluster)
click: () => navigate(clusterSettingsURL())
}));
if (cluster.initialized) {
menu.append(new MenuItem({
label: _i18n._(t`Disconnect`),
click: () => console.log(`disconnect cluster and navigate to workspaces`, cluster.contextName)
click: () => {
console.log(`//fixme: disconnect cluster`, cluster);
navigate("/");
}
}))
}
menu.popup({
window: remote.getCurrentWindow()
})
@ -54,8 +62,8 @@ export class ClustersMenu extends React.Component<Props> {
render() {
const { className } = this.props;
const { newContexts } = userStore;
const { currentWorkspace } = workspaceStore;
const clusters = clusterStore.getByWorkspaceId(currentWorkspace);
const { currentWorkspaceId } = workspaceStore;
const clusters = clusterStore.getByWorkspaceId(currentWorkspaceId);
return (
<div className={cssNames("ClustersMenu flex gaps column", className)}>
{clusters.map(cluster => {
@ -65,7 +73,7 @@ export class ClustersMenu extends React.Component<Props> {
showErrors={true}
cluster={cluster}
isActive={cluster.id === clusterStore.activeClusterId}
onClick={() => this.showCluster(cluster)}
onClick={() => this.showCluster(cluster.id)}
onContextMenu={() => this.showContextMenu(cluster)}
/>
)