refactoring, fixes

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-21 18:37:53 +03:00
1 parent 13c29a7fed
commit 5040a4354b
12 files changed
+99 -65

No files matched your search

+4
View File
@@ -85,6 +85,10 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
return Array.from(this.clusters.values());
}
hasClusters() {
return this.clusters.size > 0;
}
hasContext(name: string) {
return this.clustersList.some(cluster => cluster.contextName === name);
}
@@ -7,7 +7,7 @@ import { Trans } from "@lingui/macro";
@observer
export class LandingPage extends React.Component {
render() {
const noClusters = !clusterStore.clusters.size;
const noClusters = !clusterStore.hasClusters();
return (
<div className="LandingPage flex">
{noClusters && (
+38 -10
View File
@@ -1,8 +1,6 @@
import "./app.scss";
import React from "react";
import { observer } from "mobx-react";
import { i18nStore } from "../i18n";
import { Terminal } from "./dock/terminal";
import { disposeOnUnmount, observer } from "mobx-react";
import { Redirect, Route, Switch } from "react-router";
import { Notifications } from "./notifications";
import { NotFound } from "./+404";
@@ -30,24 +28,50 @@ import { crdRoute } from "./+custom-resources";
import { isAllowedResource } from "../api/rbac";
import { AddCluster, addClusterRoute } from "./+add-cluster";
import { LandingPage, landingRoute, landingURL } from "./+landing-page";
import { clusterStore } from "../../common/cluster-store";
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
import { Workspaces, workspacesRoute } from "./+workspaces";
import { ErrorBoundary } from "./error-boundary";
import { computed, observable, reaction } from "mobx";
import { configStore } from "../config.store";
import { clusterIpc } from "../../common/cluster-ipc";
import { clusterStore } from "../../common/cluster-store";
import { ClusterStatus } from "./cluster-manager/cluster-status";
import { clusterStatusRoute, clusterStatusURL } from "./cluster-manager/cluster-status.route";
import { navigation } from "../navigation";
import { CubeSpinner } from "./spinner";
@observer
export class App extends React.Component {
static async init() {
await i18nStore.init();
@observable appReady = false;
@computed get clusterReady() {
const clusterId = location.hostname.split(".")[0];
return !!clusterStore.getById(clusterId)?.isReady;
}
async componentDidMount() {
await clusterIpc.activate.invokeFromRenderer();
await configStore.init();
await Terminal.preloadFonts();
this.appReady = true;
disposeOnUnmount(this, [
reaction(() => this.startURL, url => {
if (!this.clusterReady) {
navigation.replace(url);
}
}, {
fireImmediately: true
})
])
}
get startURL() {
if (!clusterStore.clusters.size) {
if (!clusterStore.hasClusters()) {
return landingURL();
}
if (!this.clusterReady) {
return clusterStatusURL();
}
if (isAllowedResource(["events", "nodes", "pods"])) {
return clusterURL();
}
@@ -55,14 +79,18 @@ export class App extends React.Component {
}
render() {
if (!this.appReady) {
return <CubeSpinner className="box center"/>
}
return (
<ErrorBoundary>
<Switch>
<Route component={LandingPage} {...landingRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={Workspaces} {...workspacesRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={Cluster} {...clusterRoute}/>
<Route component={ClusterStatus} {...clusterStatusRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Nodes} {...nodesRoute}/>
<Route component={Workloads} {...workloadsRoute}/>
<Route component={Config} {...configRoute}/>
@@ -1,39 +1,30 @@
import "./cluster-manager.scss"
import React from "react";
import { observer } from "mobx-react";
import { observable } from "mobx";
import { App } from "../app";
import { ClusterStatus } from "./cluster-status";
import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar";
import { cssNames, IClassName } from "../../utils";
import { clusterStore } from "../../../common/cluster-store";
import { clusterIpc } from "../../../common/cluster-ipc";
import { Terminal } from "../dock/terminal";
import { i18nStore } from "../../i18n";
interface Props {
className?: IClassName;
contentClass?: IClassName;
}
@observer
export class ClusterManager extends React.Component<Props> {
@observable isReady = false;
async componentDidMount() {
await clusterIpc.activate.invokeFromRenderer();
await App.init();
this.isReady = true;
static async init() {
await i18nStore.init()
await Terminal.preloadFonts()
}
render() {
const { className, contentClass } = this.props;
const isReady = this.isReady && clusterStore.activeCluster?.isReady;
return (
<div className={cssNames("ClusterManager", className)}>
<div id="draggable-top"/>
<div id="lens-view" className={cssNames("flex column", contentClass)}>
{isReady && <App/>}
{!isReady && <ClusterStatus/>}
<App/>
</div>
<ClustersMenu/>
<BottomBar/>
@@ -0,0 +1,8 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const clusterStatusRoute: RouteProps = {
path: "/cluster-status"
}
export const clusterStatusURL = buildURL(clusterStatusRoute.path)
@@ -48,9 +48,7 @@ export class ClusterStatus extends React.Component {
<div className="ClusterStatus flex column gaps">
{!hasErrors && <Icon material="cloud_queue"/>}
{hasErrors && <Icon material="cloud_off" className="error"/>}
<h2>
{cluster?.contextName}
</h2>
{cluster && <h2>{cluster.contextName}</h2>}
<pre className="kube-auth-out">
{authOutput.map((data, index) => {
const error = data.startsWith("[stderr]");
@@ -1,9 +1,13 @@
.ClustersMenu {
position: relative;
text-align: center;
padding: $padding * 2 $padding;
padding: $padding * 2;
background: var(--clusters-menu-bgc);
.is-mac & {
padding-top: $padding * 3;
}
> .startup-tooltip {
$bgc: $mainBackground;
$arrowSize: 10px;
@@ -35,16 +39,15 @@
> .clusters {
//@include hidden-scrollbar; // fixme: uncomment after refactoring tooltip.tsx
--flex-gap: #{$padding * 2};
padding: $padding;
margin: var(--flex-gap) 0;
.is-mac & {
margin-top: $padding * 2;
&:empty {
display: none;
}
}
> .add-cluster {
position: relative;
margin-top: $padding;
.Icon {
border-radius: $radius;
@@ -19,6 +19,7 @@ import { PageFiltersList } from "./page-filters-list";
import { PageFiltersSelect } from "./page-filters-select";
import { NamespaceSelectFilter } from "../+namespaces/namespace-select";
import { themeStore } from "../../theme.store";
import { configStore } from "../../config.store";
// todo: refactor, split to small re-usable components
@@ -115,11 +116,12 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
const stores = [store, ...dependentStores];
if (!isClusterScoped) stores.push(namespaceStore);
try {
await when(() => configStore.isLoaded); // todo: remove
await Promise.all(stores.map(store => store.loadAll()));
const subscriptions = stores.map(store => store.subscribe());
await when(() => this.isUnmounting);
subscriptions.forEach(dispose => dispose()); // unsubscribe all
} catch(error) {
} catch (error) {
console.log("catched", error)
}
}
@@ -356,8 +358,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
const modifiedHeader = customizeHeader(placeholders, header);
if (isReactNode(modifiedHeader)) {
header = modifiedHeader;
}
else {
} else {
header = this.renderHeaderContent({
...placeholders,
...modifiedHeader as IHeaderPlaceholders,
+2 -1
View File
@@ -24,7 +24,8 @@ class LensApp extends React.Component {
userStore.load(),
workspaceStore.load(),
clusterStore.load(),
])
]);
await ClusterManager.init();
render(<LensApp/>, rootElem);
}