1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/+preferences/preferences.tsx
Lauri Nevala 47f9bcaef0 Respect PTYSHELL env variable if set
Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>
2021-02-19 22:44:53 +02:00

222 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import "./preferences.scss";
import React from "react";
import { observer } from "mobx-react";
import { action, computed, observable } from "mobx";
import { Icon } from "../icon";
import { Select, SelectOption } from "../select";
import { userStore } from "../../../common/user-store";
import { HelmRepo, repoManager } from "../../../main/helm/helm-repo-manager";
import { Input } from "../input";
import { Checkbox } from "../checkbox";
import { Notifications } from "../notifications";
import { Badge } from "../badge";
import { Button } from "../button";
import { themeStore } from "../../theme.store";
import { Tooltip } from "../tooltip";
import { KubectlBinaries } from "./kubectl-binaries";
import { appPreferenceRegistry } from "../../../extensions/registries/app-preference-registry";
import { PageLayout } from "../layout/page-layout";
import { AddHelmRepoDialog } from "./add-helm-repo-dialog";
@observer
export class Preferences extends React.Component {
@observable helmLoading = false;
@observable helmRepos: HelmRepo[] = [];
@observable helmAddedRepos = observable.map<string, HelmRepo>();
@observable httpProxy = userStore.preferences.httpsProxy || "";
@observable shell = userStore.preferences.shell || "";
@computed get themeOptions(): SelectOption<string>[] {
return themeStore.themes.map(theme => ({
label: theme.name,
value: theme.id,
}));
}
@computed get helmOptions(): SelectOption<HelmRepo>[] {
return this.helmRepos.map(repo => ({
label: repo.name,
value: repo,
}));
}
async componentDidMount() {
await this.loadHelmRepos();
}
@action
async loadHelmRepos() {
this.helmLoading = true;
try {
if (!this.helmRepos.length) {
this.helmRepos = await repoManager.loadAvailableRepos(); // via https://helm.sh
}
const repos = await repoManager.repositories(); // via helm-cli
this.helmAddedRepos.clear();
repos.forEach(repo => this.helmAddedRepos.set(repo.name, repo));
} catch (err) {
Notifications.error(String(err));
}
this.helmLoading = false;
}
async addRepo(repo: HelmRepo) {
try {
await repoManager.addRepo(repo);
this.helmAddedRepos.set(repo.name, repo);
} catch (err) {
Notifications.error(<>Adding helm branch <b>{repo.name}</b> has failed: {String(err)}</>);
}
}
async removeRepo(repo: HelmRepo) {
try {
await repoManager.removeRepo(repo);
this.helmAddedRepos.delete(repo.name);
} catch (err) {
Notifications.error(
<>Removing helm branch <b>{repo.name}</b> has failed: {String(err)}</>
);
}
}
onRepoSelect = async ({ value: repo }: SelectOption<HelmRepo>) => {
const isAdded = this.helmAddedRepos.has(repo.name);
if (isAdded) {
Notifications.ok(<>Helm branch <b>{repo.name}</b> already in use</>);
return;
}
this.helmLoading = true;
await this.addRepo(repo);
this.helmLoading = false;
};
formatHelmOptionLabel = ({ value: repo }: SelectOption<HelmRepo>) => {
const isAdded = this.helmAddedRepos.has(repo.name);
return (
<div className="flex gaps">
<span>{repo.name}</span>
{isAdded && <Icon small material="check" className="box right"/>}
</div>
);
};
render() {
const { preferences } = userStore;
const header = <h2>Preferences</h2>;
return (
<PageLayout showOnTop className="Preferences" header={header}>
<h2>Color Theme</h2>
<Select
options={this.themeOptions}
value={preferences.colorTheme}
onChange={({ value }: SelectOption) => preferences.colorTheme = value}
/>
<h2>HTTP Proxy</h2>
<Input
theme="round-black"
placeholder={`Type HTTP proxy url (example: http://proxy.acme.org:8080)`}
value={this.httpProxy}
onChange={v => this.httpProxy = v}
onBlur={() => preferences.httpsProxy = this.httpProxy}
/>
<small className="hint">
Proxy is used only for non-cluster communication.
</small>
<h2>Terminal Shell</h2>
<Input
theme="round-black"
placeholder={process.env.SHELL || process.env.PTYSHELL}
value={this.shell}
onChange={v => this.shell = v}
onBlur={() => preferences.shell = this.shell}
/>
<small className="hint">
The path of the shell that the terminal uses.
</small>
<KubectlBinaries preferences={preferences}/>
<h2>Helm</h2>
<div className="flex gaps">
<Select id="HelmRepoSelect"
placeholder="Repositories"
isLoading={this.helmLoading}
isDisabled={this.helmLoading}
options={this.helmOptions}
onChange={this.onRepoSelect}
formatOptionLabel={this.formatHelmOptionLabel}
controlShouldRenderValue={false}
className="box grow"
/>
<Button
primary
label="Add Custom Helm Repo"
onClick={AddHelmRepoDialog.open}
/>
</div>
<AddHelmRepoDialog onAddRepo={()=>this.loadHelmRepos()}/>
<div className="repos flex gaps column">
{Array.from(this.helmAddedRepos).map(([name, repo]) => {
const tooltipId = `message-${name}`;
return (
<Badge key={name} className="added-repo flex gaps align-center justify-space-between">
<span id={tooltipId} className="repo">{name}</span>
<Icon
material="delete"
onClick={() => this.removeRepo(repo)}
tooltip="Remove"
/>
<Tooltip targetId={tooltipId} formatters={{ narrow: true }}>
{repo.url}
</Tooltip>
</Badge>
);
})}
</div>
<h2>Auto start-up</h2>
<Checkbox
label="Automatically start Lens on login"
value={preferences.openAtLogin}
onChange={v => preferences.openAtLogin = v}
/>
<h2>Certificate Trust</h2>
<Checkbox
label="Allow untrusted Certificate Authorities"
value={preferences.allowUntrustedCAs}
onChange={v => preferences.allowUntrustedCAs = v}
/>
<small className="hint">
This will make Lens to trust ANY certificate authority without any validations.{" "}
Needed with some corporate proxies that do certificate re-writing.{" "}
Does not affect cluster communications!
</small>
<div className="extensions flex column gaps">
{appPreferenceRegistry.getItems().map(({ title, components: { Hint, Input } }, index) => {
return (
<div key={index} className="preference">
<h2>{title}</h2>
<Input/>
<small className="hint">
<Hint/>
</small>
</div>
);
})}
</div>
</PageLayout>
);
}
}