cluster-manager view

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-10 12:47:50 +03:00
1 parent b05ed9822d
commit 6df56b5471
24 files changed
+167 -141

No files matched your search

Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1 @@
export * from "./workspaces"
Whitespace-only changes.
@@ -1,33 +1,3 @@
.Workspaces {
display: grid;
grid-template-areas: "draggable draggable" "menu lens-view" "bottom-bar bottom-bar";
grid-template-rows: auto 1fr min-content;
grid-template-columns: min-content 1fr;
height: 100%;
.draggable-top {
@include set-draggable;
grid-area: draggable;
height: 25px;
}
#lens-view {
grid-area: lens-view;
}
.ClusterMenu {
grid-area: menu;
}
.WorkspacesBottomBar {
grid-area: bottom-bar;
}
}
.WorkspacesMenu {
border-radius: $radius;
.workspaces-title {
padding: $padding;
}
}
}
@@ -1,19 +1,12 @@
import "./workspaces.scss"
import React from "react";
import { ClustersMenu } from "./clusters-menu";
import { WorkspacesBottomBar } from "./bottom-bar";
// todo: support `workspaceId` in URL
export class Workspaces extends React.Component {
render() {
return (
<div className="Workspaces">
<div className="draggable-top"/>
<div id="lens-view"/>
<ClustersMenu/>
<WorkspacesBottomBar/>
Workspaces
</div>
)
);
}
}
+34 -40
View File
@@ -1,15 +1,13 @@
import "./app.scss";
import React from "react";
import { render } from "react-dom";
import { Redirect, Route, Router, Switch } from "react-router";
import React, { Fragment } from "react";
import { observer } from "mobx-react";
import { I18nProvider } from '@lingui/react'
import { _i18n, i18nStore } from "../i18n";
import { browserHistory } from "../navigation";
import { i18nStore } from "../i18n";
import { configStore } from "../config.store";
import { Terminal } from "./dock/terminal";
import { Redirect, Route, Switch } from "react-router";
import { Notifications } from "./notifications";
import { NotFound } from "./+404";
import { configStore } from "../config.store";
import { UserManagement } from "./+user-management/user-management";
import { ConfirmDialog } from "./confirm-dialog";
import { usersManagementRoute } from "./+user-management/user-management.routes";
@@ -24,7 +22,6 @@ import { Cluster } from "./+cluster/cluster";
import { Config, configRoute } from "./+config";
import { Events } from "./+events/events";
import { eventRoute } from "./+events";
import { ErrorBoundary } from "./error-boundary";
import { Apps, appsRoute } from "./+apps";
import { KubeObjectDetails } from "./kube-object/kube-object-details";
import { AddRoleBindingDialog } from "./+user-management-roles-bindings";
@@ -33,7 +30,6 @@ 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 { Terminal } from "./dock/terminal";
@observer
export class App extends React.Component {
@@ -43,42 +39,40 @@ export class App extends React.Component {
await i18nStore.init();
await configStore.init();
await Terminal.preloadFonts();
render(<App/>, App.rootElem);
}
render() {
const homeUrl = isAllowedResource(["events", "nodes", "pods"]) ? clusterURL() : workloadsURL();
return (
<I18nProvider i18n={_i18n}>
<Router history={browserHistory}>
<ErrorBoundary>
<Switch>
<Switch>
<Route component={Cluster} {...clusterRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/>
<Route component={Network} {...networkRoute}/>
<Route component={Storage} {...storageRoute}/>
<Route component={Namespaces} {...namespacesRoute}/>
<Route component={Events} {...eventRoute}/>
<Route component={CustomResources} {...crdRoute}/>
<Route component={UserManagement} {...usersManagementRoute}/>
<Route component={Apps} {...appsRoute}/>
<Redirect exact from="/" to={homeUrl}/>
<Route path="*" component={NotFound}/>
</Switch>
</Switch>
<KubeObjectDetails/>
<Notifications/>
<ConfirmDialog/>
<KubeConfigDialog/>
<AddRoleBindingDialog/>
<PodLogsDialog/>
<DeploymentScaleDialog/>
</ErrorBoundary>
</Router>
</I18nProvider>
<Fragment>
<Switch>
<Switch>
{/* todo: remove */}
<Route children={() => <p className="info">App is running!</p>}/>
<Route component={Cluster} {...clusterRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/>
<Route component={Network} {...networkRoute}/>
<Route component={Storage} {...storageRoute}/>
<Route component={Namespaces} {...namespacesRoute}/>
<Route component={Events} {...eventRoute}/>
<Route component={CustomResources} {...crdRoute}/>
<Route component={UserManagement} {...usersManagementRoute}/>
<Route component={Apps} {...appsRoute}/>
<Redirect exact from="/" to={homeUrl}/>
<Route path="*" component={NotFound}/>
</Switch>
</Switch>
<KubeObjectDetails/>
<Notifications/>
<ConfirmDialog/>
<KubeConfigDialog/>
<AddRoleBindingDialog/>
<PodLogsDialog/>
<DeploymentScaleDialog/>
</Fragment>
)
}
}
@@ -1,4 +1,4 @@
.WorkspacesBottomBar {
.BottomBar {
font-size: $font-size-small;
background-color: #3d90ce;
padding: $padding / 2 $padding;
@@ -8,3 +8,11 @@
cursor: pointer;
}
}
#workspace-menu {
border-radius: $radius;
.workspaces-title {
padding: $padding;
}
}
@@ -13,26 +13,26 @@ import { workspaceStore } from "../../../common/workspace-store";
// todo: remove dummy actions + console.log
@observer
export class WorkspacesBottomBar extends React.Component {
export class BottomBar extends React.Component {
@observable menuVisible = false;
render() {
const { currentWorkspace, workspacesList } = workspaceStore;
return (
<div className="WorkspacesBottomBar flex gaps">
<div className="BottomBar flex gaps">
<div id="workspace" className="workspace flex align-center box right">
<Icon small material="layers"/> {currentWorkspace}
</div>
<Menu
usePortal
htmlFor="workspace"
className="WorkspacesMenu"
id="workspace-menu"
isOpen={this.menuVisible}
open={() => this.menuVisible = true}
close={() => this.menuVisible = false}
>
<Link
to="/workspaces"
to="#"
className="workspaces-title"
onClick={prevDefault(() => console.log('/navigate: workspaces page'))}>
<Trans>Workspaces</Trans>
@@ -0,0 +1,30 @@
import React from "react";
import { observer } from "mobx-react";
import { ClusterId, clusterStore } from "../../../common/cluster-store";
import { WorkspaceId, workspaceStore } from "../../../common/workspace-store";
export const clusterContext = React.createContext(getClusterContext());
export interface ClusterContextValue {
workspaceId: WorkspaceId;
clusterId?: ClusterId;
}
export function getClusterContext(): ClusterContextValue {
return {
clusterId: clusterStore.activeCluster,
workspaceId: workspaceStore.currentWorkspace,
}
}
@observer
export class ClusterContext extends React.Component {
render() {
const { Provider } = clusterContext;
return (
<Provider value={getClusterContext()}>
{this.props.children}
</Provider>
)
}
}
@@ -0,0 +1,26 @@
.ClusterManager {
display: grid;
grid-template-areas: "draggable draggable" "menu lens-view" "bottom-bar bottom-bar";
grid-template-rows: auto 1fr min-content;
grid-template-columns: min-content 1fr;
height: 100%;
.draggable-top {
@include set-draggable;
grid-area: draggable;
height: 25px;
}
#lens-view {
position: relative;
grid-area: lens-view;
}
.ClustersMenu {
grid-area: menu;
}
.BottomBar {
grid-area: bottom-bar;
}
}
@@ -0,0 +1,18 @@
import "./cluster-manager.scss"
import React from "react";
import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar";
export class ClusterManager extends React.Component {
render() {
const { children: lensView } = this.props;
return (
<div className="ClusterManager">
<div className="draggable-top"/>
<div id="lens-view">{lensView}</div>
<ClustersMenu/>
<BottomBar/>
</div>
)
}
}
@@ -43,7 +43,7 @@
color: white;
background: $colorSuccess;
font-weight: normal;
border-radius: 50%;
border-radius: $radius;
padding: 0;
}
}
@@ -1,14 +1,13 @@
import type { Cluster } from "../../../main/cluster";
import "./clusters-menu.scss"
import { remote } from "electron"
import React from "react";
import { observer } from "mobx-react";
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 { WorkspaceId } from "../../../common/workspace-store";
import { workspaceStore } from "../../../common/workspace-store";
import { ClusterIcon } from "../+cluster-settings/cluster-icon";
import { Icon } from "../icon";
import { cssNames, IClassName } from "../../utils";
@@ -19,7 +18,6 @@ import { Badge } from "../badge";
interface Props {
className?: IClassName;
workspaceId?: WorkspaceId;
}
@observer
@@ -54,9 +52,10 @@ export class ClustersMenu extends React.Component<Props> {
}
render() {
const { workspaceId, className } = this.props;
const clusters = clusterStore.getByWorkspaceId(workspaceId);
const { className } = this.props;
const { newContexts } = userStore;
const { currentWorkspace } = workspaceStore;
const clusters = clusterStore.getByWorkspaceId(currentWorkspace);
return (
<div className={cssNames("ClustersMenu flex gaps column", className)}>
{clusters.map(cluster => {
@@ -0,0 +1 @@
export * from "./cluster-manager"
@@ -7,7 +7,7 @@ import { t, Trans } from "@lingui/macro";
import { Button } from "../button";
import { navigation } from "../../navigation";
import { _i18n } from "../../i18n";
import { issuesTrackerUrl, slackUrl, buildVersion } from "../../../common/vars";
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
interface Props {
}
@@ -45,7 +45,6 @@ export class ErrorBoundary extends React.Component<Props, State> {
<div className="ErrorBoundary flex column gaps">
<h5>
<Trans>App crash at <span className="contrast">{pageUrl}</span></Trans>
{buildVersion && <p><Trans>Build version</Trans>: {buildVersion}</p>}
</h5>
<p>
<Trans>
+1
View File
@@ -21,6 +21,7 @@ export interface MenuProps {
isOpen?: boolean;
open(): void;
close(): void;
id?: string;
className?: string;
htmlFor?: string;
autoFocus?: boolean;