diff --git a/src/common/custom-errors.ts b/src/common/custom-errors.ts index 98c5334d6c..0016af87ca 100644 --- a/src/common/custom-errors.ts +++ b/src/common/custom-errors.ts @@ -23,13 +23,14 @@ import path from "path"; export class ExecValidationNotFoundError extends Error { constructor(execPath: string) { - super(`User Exec command "${execPath}" not found on host.`); let message = `User Exec command "${execPath}" not found on host.`; if (!path.isAbsolute(execPath)) { message += ` Please ensure binary is found in PATH or use absolute path to binary in Kubeconfig`; } - this.message = message; + + super(message); + this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } diff --git a/src/renderer/components/+add-cluster/add-cluster.scss b/src/renderer/components/+add-cluster/add-cluster.scss index faac757c40..8abb38e9d0 100644 --- a/src/renderer/components/+add-cluster/add-cluster.scss +++ b/src/renderer/components/+add-cluster/add-cluster.scss @@ -50,4 +50,11 @@ display: block; padding-top: 6px; } + + .actions-panel { + .Spinner { + vertical-align: middle; + margin-left: $spacing; + } + } } diff --git a/src/renderer/components/+add-cluster/add-cluster.tsx b/src/renderer/components/+add-cluster/add-cluster.tsx index e987c1d4bb..16a6dec19e 100644 --- a/src/renderer/components/+add-cluster/add-cluster.tsx +++ b/src/renderer/components/+add-cluster/add-cluster.tsx @@ -24,7 +24,7 @@ import "./add-cluster.scss"; import type { KubeConfig } from "@kubernetes/client-node"; import fse from "fs-extra"; import { debounce } from "lodash"; -import { action, computed, observable, makeObservable } from "mobx"; +import { action, computed, observable, makeObservable, runInAction } from "mobx"; import { observer } from "mobx-react"; import path from "path"; import React from "react"; @@ -41,6 +41,7 @@ import { SettingLayout } from "../layout/setting-layout"; import MonacoEditor from "react-monaco-editor"; import { ThemeStore } from "../../theme.store"; import { UserStore } from "../../../common/user-store"; +import { Spinner } from "../spinner"; interface Option { config: KubeConfig; @@ -62,6 +63,7 @@ export class AddCluster extends React.Component { @observable kubeContexts = observable.map(); @observable customConfig = ""; @observable isWaiting = false; + @observable isCheckingInput = false; @observable errorText: string; constructor(props: {}) { @@ -80,14 +82,35 @@ export class AddCluster extends React.Component { ].filter(Boolean); } - @action - refreshContexts = debounce(() => { - const { config, error } = loadConfigFromString(this.customConfig.trim() || "{}"); + _refreshContexts = debounce(() => { + runInAction(() => { + try { + const text = this.customConfig.trim(); - this.kubeContexts.replace(getContexts(config)); - this.errorText = error?.toString(); + if (!text) { + return this.kubeContexts.clear(); + } + + const { config, error } = loadConfigFromString(text); + + this.kubeContexts.replace(getContexts(config)); + this.errorText = error?.toString(); + } catch (error) { + this.kubeContexts.clear(); + this.errorText = error?.toString() || "An error occured"; + } finally { + this.isCheckingInput = false; + } + }); }, 500); + refreshContexts = () => { + // Clear the kubeContexts immediately + this.isCheckingInput = true; + this.kubeContexts.clear(); + this._refreshContexts(); + }; + @action addClusters = async () => { this.isWaiting = true; @@ -145,6 +168,7 @@ export class AddCluster extends React.Component { tooltip={this.kubeContexts.size === 0 || "Paste in at least one cluster to add."} tooltipOverrideDisabled /> + {this.isCheckingInput && } );