diff --git a/src/common/user-store.ts b/src/common/user-store.ts index b0294d9e5a..3df9125224 100644 --- a/src/common/user-store.ts +++ b/src/common/user-store.ts @@ -20,6 +20,7 @@ export interface UserStoreModel { export interface UserPreferences { httpsProxy?: string; + shell?: string; colorTheme?: string; allowUntrustedCAs?: boolean; allowTelemetry?: boolean; diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 88ae49d123..8920568c73 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -252,7 +252,7 @@ export class Cluster implements ClusterModel, ClusterState { * Kubernetes version */ get version(): string { - return String(this.metadata?.version || ""); + return String(this.metadata?.version ?? ""); } constructor(model: ClusterModel) { diff --git a/src/main/shell-session.ts b/src/main/shell-session.ts index 10a2f9ed47..a8c6a36e72 100644 --- a/src/main/shell-session.ts +++ b/src/main/shell-session.ts @@ -105,10 +105,11 @@ export class ShellSession extends EventEmitter { protected async getShellEnv() { const env = JSON.parse(JSON.stringify(await shellEnv())); const pathStr = [this.kubectlBinDir, this.helmBinDir, process.env.PATH].join(path.delimiter); + const shell = userStore.preferences.shell || process.env.SHELL || process.env.PTYSHELL; if(isWindows) { env["SystemRoot"] = process.env.SystemRoot; - env["PTYSHELL"] = process.env.SHELL || "powershell.exe"; + env["PTYSHELL"] = shell || "powershell.exe"; env["PATH"] = pathStr; env["LENS_SESSION"] = "true"; const lensWslEnv = "KUBECONFIG/up:LENS_SESSION/u"; @@ -118,8 +119,8 @@ export class ShellSession extends EventEmitter { } else { env["WSLENV"] = lensWslEnv; } - } else if(typeof(process.env.SHELL) != "undefined") { - env["PTYSHELL"] = process.env.SHELL; + } else if(shell !== undefined) { + env["PTYSHELL"] = shell; env["PATH"] = pathStr; } else { env["PTYSHELL"] = ""; // blank runs the system default shell diff --git a/src/renderer/components/+landing-page/workspace-overview.tsx b/src/renderer/components/+landing-page/workspace-overview.tsx index c095abb31b..96b8f3a791 100644 --- a/src/renderer/components/+landing-page/workspace-overview.tsx +++ b/src/renderer/components/+landing-page/workspace-overview.tsx @@ -10,7 +10,6 @@ import { clusterViewURL } from "../cluster-manager/cluster-view.route"; import { WorkspaceClusterMenu } from "./workspace-cluster-menu"; import { kebabCase } from "lodash"; import { addClusterURL } from "../+add-cluster"; - interface Props { workspace: Workspace; } @@ -24,6 +23,12 @@ enum sortBy { @observer export class WorkspaceOverview extends Component { + private workspaceClusterStore = new WorkspaceClusterStore(this.props.workspace.id); + + componentDidMount() { + this.workspaceClusterStore.loadAll(); + } + showCluster = ({ clusterId }: ClusterItem) => { navigate(clusterViewURL({ params: { clusterId } })); @@ -31,18 +36,15 @@ export class WorkspaceOverview extends Component { render() { const { workspace } = this.props; - const workspaceClusterStore = new WorkspaceClusterStore(workspace.id); - - workspaceClusterStore.loadAll(); return ( Clusters} + renderHeaderTitle="Clusters" isClusterScoped isSearchable={false} isSelectable={false} className="WorkspaceOverview" - store={workspaceClusterStore} + store={this.workspaceClusterStore} sortingCallbacks={{ [sortBy.name]: (item: ClusterItem) => item.name, [sortBy.distribution]: (item: ClusterItem) => item.distribution, @@ -67,7 +69,7 @@ export class WorkspaceOverview extends Component { onAdd: () => navigate(addClusterURL()), }} renderItemMenu={(clusterItem: ClusterItem) => ( - + )} /> ); diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 4256b48599..a2143652b2 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -5,6 +5,7 @@ import { computed, observable } from "mobx"; import { observer } from "mobx-react"; import { userStore } from "../../../common/user-store"; +import { isWindows } from "../../../common/vars"; import { appPreferenceRegistry } from "../../../extensions/registries/app-preference-registry"; import { themeStore } from "../../theme.store"; import { Checkbox } from "../checkbox"; @@ -19,6 +20,7 @@ import { ScrollSpy } from "../scroll-spy/scroll-spy"; @observer export class Preferences extends React.Component { @observable httpProxy = userStore.preferences.httpsProxy || ""; + @observable shell = userStore.preferences.shell || ""; @computed get themeOptions(): SelectOption[] { return themeStore.themes.map(theme => ({ @@ -31,6 +33,15 @@ export class Preferences extends React.Component { const { preferences } = userStore; const header =

Preferences

; const rootMargin = "80px 0px -85%"; // Cut header size from the top and 85% from the bottom of viewport + let defaultShell = process.env.SHELL || process.env.PTYSHELL; + + if (!defaultShell) { + if (isWindows) { + defaultShell = "powershell.exe"; + } else { + defaultShell = "System default shell"; + } + } return ( ( @@ -80,6 +91,20 @@ export class Preferences extends React.Component { Does not affect cluster communications! +
+

Terminal Shell

+ + this.shell = v} + onBlur={() => preferences.shell = this.shell} + /> + + The path of the shell that the terminal uses. + +

Start-up