Signed-off-by: Roman <ixrock@gmail.com>
Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>
This commit is contained in:
Roman authored and Lauri Nevala committed 2020-08-18 11:50:54 +03:00
1 parent 7d3e87685b
commit 8925186be6
11 files changed
+121 -73

No files matched your search

@@ -1,32 +1,34 @@
import "./cluster-manager.scss"
import React from "react";
import { Redirect, Route, Switch } from "react-router";
import { observer } from "mobx-react";
import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar";
import { cssNames, IClassName } from "../../utils";
import { ClusterId } from "../../../common/cluster-store";
import { Route, Switch } from "react-router";
import { LandingPage, landingRoute } from "../+landing-page";
import { LandingPage, landingRoute, landingURL } from "../+landing-page";
import { Preferences, preferencesRoute } from "../+preferences";
import { Workspaces, workspacesRoute } from "../+workspaces";
import { AddCluster, addClusterRoute } from "../+add-cluster";
import { ClusterStatus } from "./cluster-status";
import { clusterStatusRoute } from "./cluster-status.route";
interface Props {
className?: IClassName;
contentClass?: IClassName;
}
import { ClusterView } from "./cluster-view";
import { clusterViewRoute, clusterViewURL } from "./cluster-view.route";
import { clusterStore } from "../../../common/cluster-store";
@observer
export class ClusterManager extends React.Component<Props> {
activateView(clusterId: ClusterId) {
export class ClusterManager extends React.Component {
get startUrl() {
const { activeClusterId } = clusterStore;
if (activeClusterId) {
return clusterViewURL({
params: {
clusterId: activeClusterId
}
})
}
return landingURL()
}
render() {
const { className } = this.props;
return (
<div className={cssNames("ClusterManager", className)}>
<div className="ClusterManager">
<div id="draggable-top"/>
<div id="lens-view">
<Switch>
@@ -34,8 +36,8 @@ export class ClusterManager extends React.Component<Props> {
<Route component={Preferences} {...preferencesRoute}/>
<Route component={Workspaces} {...workspacesRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={ClusterStatus} {...clusterStatusRoute}/>
<Route render={() => <p>Lens</p>}/>
<Route component={ClusterView} {...clusterViewRoute}/>
<Redirect exact from="/" to={this.startUrl}/>
</Switch>
</div>
<ClustersMenu/>
@@ -1,8 +0,0 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const clusterStatusRoute: RouteProps = {
path: "/cluster-status"
}
export const clusterStatusURL = buildURL(clusterStatusRoute.path)
@@ -2,37 +2,37 @@ import type { KubeAuthProxyLog } from "../../../main/kube-auth-proxy";
import "./cluster-status.scss"
import React from "react";
import { disposeOnUnmount, observer } from "mobx-react";
import { observer } from "mobx-react";
import { ipcRenderer } from "electron";
import { autorun, computed, observable } from "mobx";
import { computed, observable } from "mobx";
import { clusterIpc } from "../../../common/cluster-ipc";
import { Icon } from "../icon";
import { Button } from "../button";
import { cssNames } from "../../utils";
import { navigate } from "../../navigation";
import { Cluster } from "../../../main/cluster";
import { ClusterId, clusterStore } from "../../../common/cluster-store";
interface Props {
clusterId: ClusterId;
}
@observer
export class ClusterStatus extends React.Component {
export class ClusterStatus extends React.Component<Props> {
@observable authOutput: KubeAuthProxyLog[] = [];
@observable isReconnecting = false;
// fixme
@computed get clusterId() {
return this.props.clusterId;
}
@computed get cluster(): Cluster {
return null;
return clusterStore.getById(this.clusterId);
}
@computed get hasErrors(): boolean {
return this.authOutput.some(({ error }) => error) || !!this.cluster.failureReason;
}
@disposeOnUnmount
autoRedirectToMain = autorun(() => {
if (this.cluster.accessible && !this.hasErrors) {
navigate("/");
}
})
async componentDidMount() {
if (this.cluster.disconnected) {
return;
@@ -48,11 +48,11 @@ export class ClusterStatus extends React.Component {
}
componentWillUnmount() {
ipcRenderer.removeAllListeners(`kube-auth:${this.cluster.id}`);
ipcRenderer.removeAllListeners(`kube-auth:${this.clusterId}`);
}
async refreshClusterState() {
return clusterIpc.activate.invokeFromRenderer();
return clusterIpc.activate.invokeFromRenderer(this.clusterId);
}
reconnect = async () => {
@@ -0,0 +1,22 @@
import { matchPath, RouteProps } from "react-router";
import { buildURL, navigation } from "../../navigation";
export interface IClusterViewRouteParams {
clusterId: string;
}
export const clusterViewRoute: RouteProps = {
path: "/cluster/:clusterId"
}
export const clusterViewURL = buildURL<IClusterViewRouteParams>(clusterViewRoute.path)
export function getMatchedClusterId(): string {
const matched = matchPath<IClusterViewRouteParams>(navigation.location.pathname, {
...clusterViewRoute,
exact: true,
})
if (matched) {
return matched.params.clusterId;
}
}
@@ -0,0 +1,10 @@
.ClusterView {
width: 100%;
height: 100%;
border: 0;
//display: none;
&.loaded {
display: block;
}
}
@@ -0,0 +1,46 @@
import React from "react";
import { autorun, computed, observable } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react";
import { ClusterId, clusterStore } from "../../../common/cluster-store";
import { getMatchedClusterId } from "./cluster-view.route";
import { Cluster } from "../../../main/cluster";
@observer
export class ClusterView extends React.Component {
static views = observable.map<ClusterId, /*HTMLIFrameElement*/ any>()
static isLoaded = observable.map<ClusterId, boolean>()
@computed get cluster() {
return clusterStore.getById(getMatchedClusterId())
}
@computed get clusterView() {
return ClusterView.views.get(this.cluster?.id)
}
componentDidMount() {
disposeOnUnmount(this, [
autorun(() => this.activateView(this.cluster))
])
}
activateView = (cluster: Cluster) => {
if (!cluster || ClusterView.views.has(cluster.id)) {
return;
}
const view = document.createElement("webview");
view.className = "ClusterView"
view.src = `${location.protocol}://${cluster.id}.${location.host}`
view.onload = () => console.log('CLUSTER VIEW READY!', cluster);
document.body.appendChild(view);
ClusterView.views.set(cluster.id, view);
}
render() {
const { cluster } = this;
if (cluster && cluster.accessible) {
}
return "";
}
}
@@ -20,7 +20,7 @@ import { landingURL } from "../+landing-page";
import { Tooltip } from "../tooltip";
import { ConfirmDialog } from "../confirm-dialog";
import { clusterIpc } from "../../../common/cluster-ipc";
import { clusterStatusURL } from "./cluster-status.route";
import { clusterViewURL, getMatchedClusterId } from "./cluster-view.route";
// fixme: allow to rearrange clusters with drag&drop
@@ -32,12 +32,9 @@ interface Props {
export class ClustersMenu extends React.Component<Props> {
@observable showHint = true;
showCluster = (clusterId: ClusterId) => {
if (clusterStore.activeClusterId === clusterId) {
navigate("/"); // redirect to index
} else {
clusterStore.activeClusterId = clusterId;
}
activateCluster = (clusterId: ClusterId) => {
clusterStore.activeClusterId = clusterId;
navigate(clusterViewURL({ params: { clusterId } }))
}
addCluster = () => {
@@ -57,9 +54,6 @@ export class ClustersMenu extends React.Component<Props> {
label: _i18n._(t`Disconnect`),
click: async () => {
await clusterIpc.disconnect.invokeFromRenderer(cluster.id);
if (cluster.id === clusterStore.activeClusterId) {
navigate(clusterStatusURL());
}
}
}))
}
@@ -110,8 +104,8 @@ export class ClustersMenu extends React.Component<Props> {
key={cluster.id}
showErrors={true}
cluster={cluster}
isActive={cluster.id === clusterStore.activeClusterId}
onClick={() => this.showCluster(cluster.id)}
isActive={cluster.id === getMatchedClusterId()}
onClick={() => this.activateCluster(cluster.id)}
onContextMenu={() => this.showContextMenu(cluster)}
/>
)