diff --git a/locales/en/messages.po b/locales/en/messages.po index c967c5901a..ad8798db04 100644 --- a/locales/en/messages.po +++ b/locales/en/messages.po @@ -72,7 +72,7 @@ msgid "Active" msgstr "Active" #: 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" msgstr "Add Cluster" @@ -228,7 +228,7 @@ msgstr "Are you sure you want to drain <0>{nodeName}?" msgid "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." 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" 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" msgstr "Disconnect" @@ -1711,8 +1711,8 @@ msgid "Reclaim Policy" msgstr "Reclaim Policy" #: src/renderer/components/cluster-manager/cluster-status.tsx:52 -msgid "Reconnect" -msgstr "Reconnect" +#~ msgid "Reconnect" +#~ msgstr "Reconnect" #: src/renderer/components/+config-autoscalers/hpa-details.tsx:70 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75 @@ -1741,8 +1741,8 @@ msgid "Releases" msgstr "Releases" #: 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:62 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:60 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:64 #: 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:85 @@ -2085,7 +2085,7 @@ msgstr "Set" msgid "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" msgstr "Settings" @@ -2259,7 +2259,7 @@ msgstr "This field is required" msgid "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." msgstr "This is the quick launch menu." diff --git a/locales/fi/messages.po b/locales/fi/messages.po index cd6b540f90..4fba45271a 100644 --- a/locales/fi/messages.po +++ b/locales/fi/messages.po @@ -72,7 +72,7 @@ msgid "Active" msgstr "" #: 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" msgstr "" @@ -228,7 +228,7 @@ msgstr "" msgid "Arguments" 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." msgstr "" @@ -699,7 +699,7 @@ msgstr "" msgid "Desired number of replicas" msgstr "" -#: src/renderer/components/cluster-manager/clusters-menu.tsx:51 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:52 msgid "Disconnect" msgstr "" @@ -1694,8 +1694,8 @@ msgid "Reclaim Policy" msgstr "" #: src/renderer/components/cluster-manager/cluster-status.tsx:52 -msgid "Reconnect" -msgstr "" +#~ msgid "Reconnect" +#~ msgstr "" #: src/renderer/components/+config-autoscalers/hpa-details.tsx:70 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:75 @@ -1724,8 +1724,8 @@ msgid "Releases" msgstr "" #: 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:62 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:60 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:64 #: 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:85 @@ -2068,7 +2068,7 @@ msgstr "" msgid "Set quota" msgstr "" -#: src/renderer/components/cluster-manager/clusters-menu.tsx:46 +#: src/renderer/components/cluster-manager/clusters-menu.tsx:47 msgid "Settings" msgstr "" @@ -2242,7 +2242,7 @@ msgstr "" msgid "This field must contain only lowercase latin characters, numbers and dash." 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." msgstr "" diff --git a/locales/ru/messages.po b/locales/ru/messages.po index fc4b01d90c..d77d9d92d7 100644 --- a/locales/ru/messages.po +++ b/locales/ru/messages.po @@ -73,7 +73,7 @@ msgid "Active" msgstr "Активный" #: 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" msgstr "" @@ -229,7 +229,7 @@ msgstr "Выполнить команду drain для ноды <0>{nodeName} { return Array.from(this.clusters.values()); } + hasClusters() { + return this.clusters.size > 0; + } + hasContext(name: string) { return this.clustersList.some(cluster => cluster.contextName === name); } diff --git a/src/renderer/components/+landing-page/landing-page.tsx b/src/renderer/components/+landing-page/landing-page.tsx index e1753c2b32..8de9810210 100644 --- a/src/renderer/components/+landing-page/landing-page.tsx +++ b/src/renderer/components/+landing-page/landing-page.tsx @@ -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 (
{noClusters && ( diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 94b978c623..b187e27d24 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -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 + } return ( - - + + + diff --git a/src/renderer/components/cluster-manager/cluster-manager.tsx b/src/renderer/components/cluster-manager/cluster-manager.tsx index 24d9ccaf14..61562a73ad 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.tsx +++ b/src/renderer/components/cluster-manager/cluster-manager.tsx @@ -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 { - @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 (
- {isReady && } - {!isReady && } +
diff --git a/src/renderer/components/cluster-manager/cluster-status.route.ts b/src/renderer/components/cluster-manager/cluster-status.route.ts new file mode 100644 index 0000000000..c3443f0e99 --- /dev/null +++ b/src/renderer/components/cluster-manager/cluster-status.route.ts @@ -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) diff --git a/src/renderer/components/cluster-manager/cluster-status.tsx b/src/renderer/components/cluster-manager/cluster-status.tsx index c320bb92ff..c950677279 100644 --- a/src/renderer/components/cluster-manager/cluster-status.tsx +++ b/src/renderer/components/cluster-manager/cluster-status.tsx @@ -48,9 +48,7 @@ export class ClusterStatus extends React.Component {
{!hasErrors && } {hasErrors && } -

- {cluster?.contextName} -

+ {cluster &&

{cluster.contextName}

}
           {authOutput.map((data, index) => {
             const error = data.startsWith("[stderr]");
diff --git a/src/renderer/components/cluster-manager/clusters-menu.scss b/src/renderer/components/cluster-manager/clusters-menu.scss
index 051a615686..37a361d43e 100644
--- a/src/renderer/components/cluster-manager/clusters-menu.scss
+++ b/src/renderer/components/cluster-manager/clusters-menu.scss
@@ -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;
diff --git a/src/renderer/components/item-object-list/item-list-layout.tsx b/src/renderer/components/item-object-list/item-list-layout.tsx
index 80c1f76d70..4b11e1254d 100644
--- a/src/renderer/components/item-object-list/item-list-layout.tsx
+++ b/src/renderer/components/item-object-list/item-list-layout.tsx
@@ -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 {
     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 {
       const modifiedHeader = customizeHeader(placeholders, header);
       if (isReactNode(modifiedHeader)) {
         header = modifiedHeader;
-      }
-      else {
+      } else {
         header = this.renderHeaderContent({
           ...placeholders,
           ...modifiedHeader as IHeaderPlaceholders,
diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx
index d1631782bb..ee909f3494 100644
--- a/src/renderer/index.tsx
+++ b/src/renderer/index.tsx
@@ -24,7 +24,8 @@ class LensApp extends React.Component {
       userStore.load(),
       workspaceStore.load(),
       clusterStore.load(),
-    ])
+    ]);
+    await ClusterManager.init();
     render(, rootElem);
   }