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

refactoring, fixes

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

View File

@ -72,7 +72,7 @@ msgid "Active"
msgstr "Active" msgstr "Active"
#: src/renderer/components/+add-cluster/add-cluster.tsx:118 #: src/renderer/components/+add-cluster/add-cluster.tsx:118
#: src/renderer/components/cluster-manager/clusters-menu.tsx:97 #: src/renderer/components/cluster-manager/clusters-menu.tsx:99
msgid "Add Cluster" msgid "Add Cluster"
msgstr "Add Cluster" msgstr "Add Cluster"
@ -228,7 +228,7 @@ msgstr "Are you sure you want to drain <0>{nodeName}</0>?"
msgid "Arguments" msgid "Arguments"
msgstr "Arguments" msgstr "Arguments"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84 #: src/renderer/components/cluster-manager/clusters-menu.tsx:86
msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button." msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button."
msgstr "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button." msgstr "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button."
@ -703,7 +703,7 @@ msgstr "Description"
msgid "Desired number of replicas" msgid "Desired number of replicas"
msgstr "Desired number of replicas" msgstr "Desired number of replicas"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:51 #: src/renderer/components/cluster-manager/clusters-menu.tsx:52
msgid "Disconnect" msgid "Disconnect"
msgstr "Disconnect" msgstr "Disconnect"
@ -1711,8 +1711,8 @@ msgid "Reclaim Policy"
msgstr "Reclaim Policy" msgstr "Reclaim Policy"
#: src/renderer/components/cluster-manager/cluster-status.tsx:52 #: src/renderer/components/cluster-manager/cluster-status.tsx:52
msgid "Reconnect" #~ msgid "Reconnect"
msgstr "Reconnect" #~ msgstr "Reconnect"
#: src/renderer/components/+config-autoscalers/hpa-details.tsx:70 #: src/renderer/components/+config-autoscalers/hpa-details.tsx:70
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75
@ -1741,8 +1741,8 @@ msgid "Releases"
msgstr "Releases" msgstr "Releases"
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:58 #: src/renderer/components/cluster-manager/clusters-menu.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:62 #: src/renderer/components/cluster-manager/clusters-menu.tsx:64
#: src/renderer/components/item-object-list/item-list-layout.tsx:179 #: src/renderer/components/item-object-list/item-list-layout.tsx:179
#: src/renderer/components/menu/menu-actions.tsx:49 #: src/renderer/components/menu/menu-actions.tsx:49
#: src/renderer/components/menu/menu-actions.tsx:85 #: src/renderer/components/menu/menu-actions.tsx:85
@ -2085,7 +2085,7 @@ msgstr "Set"
msgid "Set quota" msgid "Set quota"
msgstr "Set quota" msgstr "Set quota"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:46 #: src/renderer/components/cluster-manager/clusters-menu.tsx:47
msgid "Settings" msgid "Settings"
msgstr "Settings" msgstr "Settings"
@ -2259,7 +2259,7 @@ msgstr "This field is required"
msgid "This field must contain only lowercase latin characters, numbers and dash." msgid "This field must contain only lowercase latin characters, numbers and dash."
msgstr "This field must contain only lowercase latin characters, numbers and dash." msgstr "This field must contain only lowercase latin characters, numbers and dash."
#: src/renderer/components/cluster-manager/clusters-menu.tsx:82 #: src/renderer/components/cluster-manager/clusters-menu.tsx:84
msgid "This is the quick launch menu." msgid "This is the quick launch menu."
msgstr "This is the quick launch menu." msgstr "This is the quick launch menu."

View File

@ -72,7 +72,7 @@ msgid "Active"
msgstr "" msgstr ""
#: src/renderer/components/+add-cluster/add-cluster.tsx:118 #: src/renderer/components/+add-cluster/add-cluster.tsx:118
#: src/renderer/components/cluster-manager/clusters-menu.tsx:97 #: src/renderer/components/cluster-manager/clusters-menu.tsx:99
msgid "Add Cluster" msgid "Add Cluster"
msgstr "" msgstr ""
@ -228,7 +228,7 @@ msgstr ""
msgid "Arguments" msgid "Arguments"
msgstr "" msgstr ""
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84 #: src/renderer/components/cluster-manager/clusters-menu.tsx:86
msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button." msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button."
msgstr "" msgstr ""
@ -699,7 +699,7 @@ msgstr ""
msgid "Desired number of replicas" msgid "Desired number of replicas"
msgstr "" msgstr ""
#: src/renderer/components/cluster-manager/clusters-menu.tsx:51 #: src/renderer/components/cluster-manager/clusters-menu.tsx:52
msgid "Disconnect" msgid "Disconnect"
msgstr "" msgstr ""
@ -1694,8 +1694,8 @@ msgid "Reclaim Policy"
msgstr "" msgstr ""
#: src/renderer/components/cluster-manager/cluster-status.tsx:52 #: src/renderer/components/cluster-manager/cluster-status.tsx:52
msgid "Reconnect" #~ msgid "Reconnect"
msgstr "" #~ msgstr ""
#: src/renderer/components/+config-autoscalers/hpa-details.tsx:70 #: src/renderer/components/+config-autoscalers/hpa-details.tsx:70
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75
@ -1724,8 +1724,8 @@ msgid "Releases"
msgstr "" msgstr ""
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:58 #: src/renderer/components/cluster-manager/clusters-menu.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:62 #: src/renderer/components/cluster-manager/clusters-menu.tsx:64
#: src/renderer/components/item-object-list/item-list-layout.tsx:179 #: src/renderer/components/item-object-list/item-list-layout.tsx:179
#: src/renderer/components/menu/menu-actions.tsx:49 #: src/renderer/components/menu/menu-actions.tsx:49
#: src/renderer/components/menu/menu-actions.tsx:85 #: src/renderer/components/menu/menu-actions.tsx:85
@ -2068,7 +2068,7 @@ msgstr ""
msgid "Set quota" msgid "Set quota"
msgstr "" msgstr ""
#: src/renderer/components/cluster-manager/clusters-menu.tsx:46 #: src/renderer/components/cluster-manager/clusters-menu.tsx:47
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -2242,7 +2242,7 @@ msgstr ""
msgid "This field must contain only lowercase latin characters, numbers and dash." msgid "This field must contain only lowercase latin characters, numbers and dash."
msgstr "" msgstr ""
#: src/renderer/components/cluster-manager/clusters-menu.tsx:82 #: src/renderer/components/cluster-manager/clusters-menu.tsx:84
msgid "This is the quick launch menu." msgid "This is the quick launch menu."
msgstr "" msgstr ""

View File

@ -73,7 +73,7 @@ msgid "Active"
msgstr "Активный" msgstr "Активный"
#: src/renderer/components/+add-cluster/add-cluster.tsx:118 #: src/renderer/components/+add-cluster/add-cluster.tsx:118
#: src/renderer/components/cluster-manager/clusters-menu.tsx:97 #: src/renderer/components/cluster-manager/clusters-menu.tsx:99
msgid "Add Cluster" msgid "Add Cluster"
msgstr "" msgstr ""
@ -229,7 +229,7 @@ msgstr "Выполнить команду drain для ноды <0>{nodeName}</0
msgid "Arguments" msgid "Arguments"
msgstr "Аргументы" msgstr "Аргументы"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84 #: src/renderer/components/cluster-manager/clusters-menu.tsx:86
msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button." msgid "Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button."
msgstr "" msgstr ""
@ -704,7 +704,7 @@ msgstr "Описание"
msgid "Desired number of replicas" msgid "Desired number of replicas"
msgstr "Нужный уровень реплик" msgstr "Нужный уровень реплик"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:51 #: src/renderer/components/cluster-manager/clusters-menu.tsx:52
msgid "Disconnect" msgid "Disconnect"
msgstr "" msgstr ""
@ -1712,8 +1712,8 @@ msgid "Reclaim Policy"
msgstr "Политика отката" msgstr "Политика отката"
#: src/renderer/components/cluster-manager/cluster-status.tsx:52 #: src/renderer/components/cluster-manager/cluster-status.tsx:52
msgid "Reconnect" #~ msgid "Reconnect"
msgstr "" #~ msgstr ""
#: src/renderer/components/+config-autoscalers/hpa-details.tsx:70 #: src/renderer/components/+config-autoscalers/hpa-details.tsx:70
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75
@ -1742,8 +1742,8 @@ msgid "Releases"
msgstr "Релизы" msgstr "Релизы"
#: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:58 #: src/renderer/components/cluster-manager/clusters-menu.tsx:60
#: src/renderer/components/cluster-manager/clusters-menu.tsx:62 #: src/renderer/components/cluster-manager/clusters-menu.tsx:64
#: src/renderer/components/item-object-list/item-list-layout.tsx:179 #: src/renderer/components/item-object-list/item-list-layout.tsx:179
#: src/renderer/components/menu/menu-actions.tsx:49 #: src/renderer/components/menu/menu-actions.tsx:49
#: src/renderer/components/menu/menu-actions.tsx:85 #: src/renderer/components/menu/menu-actions.tsx:85
@ -2086,7 +2086,7 @@ msgstr "Установлено"
msgid "Set quota" msgid "Set quota"
msgstr "Установить квоту" msgstr "Установить квоту"
#: src/renderer/components/cluster-manager/clusters-menu.tsx:46 #: src/renderer/components/cluster-manager/clusters-menu.tsx:47
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -2260,7 +2260,7 @@ msgstr "Это обязательное поле"
msgid "This field must contain only lowercase latin characters, numbers and dash." msgid "This field must contain only lowercase latin characters, numbers and dash."
msgstr "Это поле может содержать только латинские буквы в нижнем регистре, номера и дефис." msgstr "Это поле может содержать только латинские буквы в нижнем регистре, номера и дефис."
#: src/renderer/components/cluster-manager/clusters-menu.tsx:82 #: src/renderer/components/cluster-manager/clusters-menu.tsx:84
msgid "This is the quick launch menu." msgid "This is the quick launch menu."
msgstr "" msgstr ""

View File

@ -85,6 +85,10 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
return Array.from(this.clusters.values()); return Array.from(this.clusters.values());
} }
hasClusters() {
return this.clusters.size > 0;
}
hasContext(name: string) { hasContext(name: string) {
return this.clustersList.some(cluster => cluster.contextName === name); return this.clustersList.some(cluster => cluster.contextName === name);
} }

View File

@ -7,7 +7,7 @@ import { Trans } from "@lingui/macro";
@observer @observer
export class LandingPage extends React.Component { export class LandingPage extends React.Component {
render() { render() {
const noClusters = !clusterStore.clusters.size; const noClusters = !clusterStore.hasClusters();
return ( return (
<div className="LandingPage flex"> <div className="LandingPage flex">
{noClusters && ( {noClusters && (

View File

@ -1,8 +1,6 @@
import "./app.scss"; import "./app.scss";
import React from "react"; import React from "react";
import { observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { i18nStore } from "../i18n";
import { Terminal } from "./dock/terminal";
import { Redirect, Route, Switch } from "react-router"; import { Redirect, Route, Switch } from "react-router";
import { Notifications } from "./notifications"; import { Notifications } from "./notifications";
import { NotFound } from "./+404"; import { NotFound } from "./+404";
@ -30,24 +28,50 @@ import { crdRoute } from "./+custom-resources";
import { isAllowedResource } from "../api/rbac"; import { isAllowedResource } from "../api/rbac";
import { AddCluster, addClusterRoute } from "./+add-cluster"; import { AddCluster, addClusterRoute } from "./+add-cluster";
import { LandingPage, landingRoute, landingURL } from "./+landing-page"; import { LandingPage, landingRoute, landingURL } from "./+landing-page";
import { clusterStore } from "../../common/cluster-store";
import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings"; import { ClusterSettings, clusterSettingsRoute } from "./+cluster-settings";
import { Workspaces, workspacesRoute } from "./+workspaces"; import { Workspaces, workspacesRoute } from "./+workspaces";
import { ErrorBoundary } from "./error-boundary"; import { ErrorBoundary } from "./error-boundary";
import { computed, observable, reaction } from "mobx";
import { configStore } from "../config.store"; 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 @observer
export class App extends React.Component { export class App extends React.Component {
static async init() { @observable appReady = false;
await i18nStore.init();
@computed get clusterReady() {
const clusterId = location.hostname.split(".")[0];
return !!clusterStore.getById(clusterId)?.isReady;
}
async componentDidMount() {
await clusterIpc.activate.invokeFromRenderer();
await configStore.init(); 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() { get startURL() {
if (!clusterStore.clusters.size) { if (!clusterStore.hasClusters()) {
return landingURL(); return landingURL();
} }
if (!this.clusterReady) {
return clusterStatusURL();
}
if (isAllowedResource(["events", "nodes", "pods"])) { if (isAllowedResource(["events", "nodes", "pods"])) {
return clusterURL(); return clusterURL();
} }
@ -55,14 +79,18 @@ export class App extends React.Component {
} }
render() { render() {
if (!this.appReady) {
return <CubeSpinner className="box center"/>
}
return ( return (
<ErrorBoundary> <ErrorBoundary>
<Switch> <Switch>
<Route component={LandingPage} {...landingRoute}/> <Route component={LandingPage} {...landingRoute}/>
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={Workspaces} {...workspacesRoute}/> <Route component={Workspaces} {...workspacesRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/> <Route component={AddCluster} {...addClusterRoute}/>
<Route component={Cluster} {...clusterRoute}/> <Route component={Cluster} {...clusterRoute}/>
<Route component={ClusterStatus} {...clusterStatusRoute}/>
<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

@ -1,39 +1,30 @@
import "./cluster-manager.scss" import "./cluster-manager.scss"
import React from "react"; import React from "react";
import { observer } from "mobx-react";
import { observable } from "mobx";
import { App } from "../app"; import { App } from "../app";
import { ClusterStatus } from "./cluster-status";
import { ClustersMenu } from "./clusters-menu"; import { ClustersMenu } from "./clusters-menu";
import { BottomBar } from "./bottom-bar"; import { BottomBar } from "./bottom-bar";
import { cssNames, IClassName } from "../../utils"; import { cssNames, IClassName } from "../../utils";
import { clusterStore } from "../../../common/cluster-store"; import { Terminal } from "../dock/terminal";
import { clusterIpc } from "../../../common/cluster-ipc"; import { i18nStore } from "../../i18n";
interface Props { interface Props {
className?: IClassName; className?: IClassName;
contentClass?: IClassName; contentClass?: IClassName;
} }
@observer
export class ClusterManager extends React.Component<Props> { export class ClusterManager extends React.Component<Props> {
@observable isReady = false; static async init() {
await i18nStore.init()
async componentDidMount() { await Terminal.preloadFonts()
await clusterIpc.activate.invokeFromRenderer();
await App.init();
this.isReady = true;
} }
render() { render() {
const { className, contentClass } = this.props; const { className, contentClass } = this.props;
const isReady = this.isReady && clusterStore.activeCluster?.isReady;
return ( return (
<div className={cssNames("ClusterManager", className)}> <div className={cssNames("ClusterManager", className)}>
<div id="draggable-top"/> <div id="draggable-top"/>
<div id="lens-view" className={cssNames("flex column", contentClass)}> <div id="lens-view" className={cssNames("flex column", contentClass)}>
{isReady && <App/>} <App/>
{!isReady && <ClusterStatus/>}
</div> </div>
<ClustersMenu/> <ClustersMenu/>
<BottomBar/> <BottomBar/>

View File

@ -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)

View File

@ -48,9 +48,7 @@ export class ClusterStatus extends React.Component {
<div className="ClusterStatus flex column gaps"> <div className="ClusterStatus flex column gaps">
{!hasErrors && <Icon material="cloud_queue"/>} {!hasErrors && <Icon material="cloud_queue"/>}
{hasErrors && <Icon material="cloud_off" className="error"/>} {hasErrors && <Icon material="cloud_off" className="error"/>}
<h2> {cluster && <h2>{cluster.contextName}</h2>}
{cluster?.contextName}
</h2>
<pre className="kube-auth-out"> <pre className="kube-auth-out">
{authOutput.map((data, index) => { {authOutput.map((data, index) => {
const error = data.startsWith("[stderr]"); const error = data.startsWith("[stderr]");

View File

@ -1,9 +1,13 @@
.ClustersMenu { .ClustersMenu {
position: relative; position: relative;
text-align: center; text-align: center;
padding: $padding * 2 $padding; padding: $padding * 2;
background: var(--clusters-menu-bgc); background: var(--clusters-menu-bgc);
.is-mac & {
padding-top: $padding * 3;
}
> .startup-tooltip { > .startup-tooltip {
$bgc: $mainBackground; $bgc: $mainBackground;
$arrowSize: 10px; $arrowSize: 10px;
@ -35,16 +39,15 @@
> .clusters { > .clusters {
//@include hidden-scrollbar; // fixme: uncomment after refactoring tooltip.tsx //@include hidden-scrollbar; // fixme: uncomment after refactoring tooltip.tsx
--flex-gap: #{$padding * 2}; --flex-gap: #{$padding * 2};
padding: $padding; margin: var(--flex-gap) 0;
.is-mac & { &:empty {
margin-top: $padding * 2; display: none;
} }
} }
> .add-cluster { > .add-cluster {
position: relative; position: relative;
margin-top: $padding;
.Icon { .Icon {
border-radius: $radius; border-radius: $radius;

View File

@ -19,6 +19,7 @@ import { PageFiltersList } from "./page-filters-list";
import { PageFiltersSelect } from "./page-filters-select"; import { PageFiltersSelect } from "./page-filters-select";
import { NamespaceSelectFilter } from "../+namespaces/namespace-select"; import { NamespaceSelectFilter } from "../+namespaces/namespace-select";
import { themeStore } from "../../theme.store"; import { themeStore } from "../../theme.store";
import { configStore } from "../../config.store";
// todo: refactor, split to small re-usable components // todo: refactor, split to small re-usable components
@ -115,6 +116,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
const stores = [store, ...dependentStores]; const stores = [store, ...dependentStores];
if (!isClusterScoped) stores.push(namespaceStore); if (!isClusterScoped) stores.push(namespaceStore);
try { try {
await when(() => configStore.isLoaded); // todo: remove
await Promise.all(stores.map(store => store.loadAll())); await Promise.all(stores.map(store => store.loadAll()));
const subscriptions = stores.map(store => store.subscribe()); const subscriptions = stores.map(store => store.subscribe());
await when(() => this.isUnmounting); await when(() => this.isUnmounting);
@ -356,8 +358,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
const modifiedHeader = customizeHeader(placeholders, header); const modifiedHeader = customizeHeader(placeholders, header);
if (isReactNode(modifiedHeader)) { if (isReactNode(modifiedHeader)) {
header = modifiedHeader; header = modifiedHeader;
} } else {
else {
header = this.renderHeaderContent({ header = this.renderHeaderContent({
...placeholders, ...placeholders,
...modifiedHeader as IHeaderPlaceholders, ...modifiedHeader as IHeaderPlaceholders,

View File

@ -24,7 +24,8 @@ class LensApp extends React.Component {
userStore.load(), userStore.load(),
workspaceStore.load(), workspaceStore.load(),
clusterStore.load(), clusterStore.load(),
]) ]);
await ClusterManager.init();
render(<LensApp/>, rootElem); render(<LensApp/>, rootElem);
} }