1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/+preferences/add-helm-repo-dialog.tsx
Sebastian Malton 9563ead2e6
Fixing Singleton typing to correctly return child class (#1914)
- Add distinction between `getInstance` and `getInstanceOrCreate` since
  it is not always possible to create an instance (since you might not
  know the correct arguments)

- Remove all the `export const *Store = *Store.getInstance<*Store>();`
  calls as it defeats the purpose of `Singleton`. Plus with the typing
  changes the appropriate `*Store.getInstance()` is "short enough".

- Special case the two extension export facades to not need to use
  `getInstanceOrCreate`. Plus since they are just facades it is always
  possible to create them.

- Move some other types to be also `Singleton`'s: ExtensionLoader,
  ExtensionDiscovery, ThemeStore, LocalizationStore, ...

- Fixed dev-run always using the same port with electron inspect

- Update Store documentation with new recommendations about creating
  instances of singletons

- Fix all unit tests to create their dependent singletons

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2021-04-21 09:59:59 -04:00

177 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import "./add-helm-repo-dialog.scss";
import React from "react";
import { remote, FileFilter } from "electron";
import { observable } from "mobx";
import { observer } from "mobx-react";
import { Dialog, DialogProps } from "../dialog";
import { Wizard, WizardStep } from "../wizard";
import { Input } from "../input";
import { Checkbox } from "../checkbox";
import { Button } from "../button";
import { systemName, isUrl, isPath } from "../input/input_validators";
import { SubTitle } from "../layout/sub-title";
import { Icon } from "../icon";
import { Notifications } from "../notifications";
import { HelmRepo, HelmRepoManager } from "../../../main/helm/helm-repo-manager";
interface Props extends Partial<DialogProps> {
onAddRepo: Function
}
enum FileType {
CaFile = "caFile",
KeyFile = "keyFile",
CertFile = "certFile",
}
@observer
export class AddHelmRepoDialog extends React.Component<Props> {
private emptyRepo = {name: "", url: "", username: "", password: "", insecureSkipTlsVerify: false, caFile:"", keyFile: "", certFile: ""};
private static keyExtensions = ["key", "keystore", "jks", "p12", "pfx", "pem"];
private static certExtensions = ["crt", "cer", "ca-bundle", "p7b", "p7c" , "p7s", "p12", "pfx", "pem"];
@observable static isOpen = false;
static open() {
AddHelmRepoDialog.isOpen = true;
}
static close() {
AddHelmRepoDialog.isOpen = false;
}
@observable helmRepo : HelmRepo = this.emptyRepo;
@observable showOptions = false;
close = () => {
AddHelmRepoDialog.close();
this.helmRepo = this.emptyRepo;
this.showOptions = false;
};
setFilepath(type: FileType, value: string) {
this.helmRepo[type] = value;
}
getFilePath(type: FileType) : string {
return this.helmRepo[type];
}
async selectFileDialog(type: FileType, fileFilter: FileFilter) {
const { dialog, BrowserWindow } = remote;
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
defaultPath: this.getFilePath(type),
properties: ["openFile", "showHiddenFiles"],
message: `Select file`,
buttonLabel: `Use file`,
filters: [
fileFilter,
{ name: "Any", extensions: ["*"]}
]
});
if (!canceled && filePaths.length) {
this.setFilepath(type, filePaths[0]);
}
}
async addCustomRepo() {
try {
await HelmRepoManager.getInstance().addСustomRepo(this.helmRepo);
Notifications.ok(<>Helm repository <b>{this.helmRepo.name}</b> has added</>);
this.props.onAddRepo();
this.close();
} catch (err) {
Notifications.error(<>Adding helm branch <b>{this.helmRepo.name}</b> has failed: {String(err)}</>);
}
}
renderFileInput(placeholder:string, fileType:FileType ,fileExtensions:string[]){
return(
<div className="flex gaps align-center">
<Input
placeholder={placeholder}
validators = {isPath}
className="box grow"
value={this.getFilePath(fileType)}
onChange={v => this.setFilepath(fileType, v)}
/>
<Icon
material="folder"
onClick={() => this.selectFileDialog(fileType, {name: placeholder, extensions: fileExtensions})}
tooltip="Browse"
/>
</div>);
}
renderOptions() {
return (
<>
<SubTitle title="Security settings" />
<Checkbox
label="Skip TLS certificate checks for the repository"
value={this.helmRepo.insecureSkipTlsVerify}
onChange={v => this.helmRepo.insecureSkipTlsVerify = v}
/>
{this.renderFileInput(`Key file`, FileType.KeyFile, AddHelmRepoDialog.keyExtensions)}
{this.renderFileInput(`Ca file`, FileType.CaFile, AddHelmRepoDialog.certExtensions)}
{this.renderFileInput(`Cerificate file`, FileType.CertFile, AddHelmRepoDialog.certExtensions)}
<SubTitle title="Chart Repository Credentials" />
<Input
placeholder="Username"
value={this.helmRepo.username} onChange= {v => this.helmRepo.username = v}
/>
<Input
type="password"
placeholder="Password"
value={this.helmRepo.password} onChange={v => this.helmRepo.password = v}
/>
</>);
}
render() {
const { ...dialogProps } = this.props;
const header = <h5>Add custom Helm Repo</h5>;
return (
<Dialog
{...dialogProps}
className="AddHelmRepoDialog"
isOpen={AddHelmRepoDialog.isOpen}
close={this.close}
>
<Wizard header={header} done={this.close}>
<WizardStep contentClass="flow column" nextLabel="Add" next={()=>{this.addCustomRepo();}}>
<div className="flex column gaps">
<Input
autoFocus required
placeholder="Helm repo name"
validators={systemName}
value={this.helmRepo.name} onChange={v => this.helmRepo.name = v}
/>
<Input
required
placeholder="URL"
validators={isUrl}
value={this.helmRepo.url} onChange={v => this.helmRepo.url = v}
/>
<Button plain className="accordion" onClick={() => this.showOptions = !this.showOptions} >
More
<Icon
small
tooltip="More"
material={this.showOptions ? "remove" : "add"}
/>
</Button>
{this.showOptions && this.renderOptions()}
</div>
</WizardStep>
</Wizard>
</Dialog>
);
}
}