1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Attempt to use MuiCheckbox for 3-state checkbox

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-08-03 16:08:19 -04:00
parent 9b4ca7f0ce
commit cdb2d35e12
6 changed files with 171 additions and 10 deletions

View File

@ -200,6 +200,19 @@ const openAtLogin: PreferenceDescription<boolean> = {
},
};
const extensionRegistryUrl: PreferenceDescription<boolean | string> = {
fromStore(val) {
return val ?? false;
},
toStore(val) {
if (val === false) {
return undefined;
}
return val;
}
};
const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map<string, ObservableToggleSet<string>>> = {
fromStore(val) {
return new Map(
@ -271,6 +284,7 @@ export const DESCRIPTORS = {
downloadBinariesPath,
kubectlBinariesPath,
openAtLogin,
extensionRegistryUrl,
hiddenTableColumns,
syncKubeconfigEntries,
editorConfiguration,

View File

@ -71,6 +71,22 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
@observable downloadBinariesPath?: string;
@observable kubectlBinariesPath?: string;
/**
* The extension registry URL
* - If `true` then used the registry configured in the `~/.npmrc`
* - If `false` then the default location
* - If a string, then use that
*/
@observable extensionRegistryUrl: boolean | string;
@computed get getUseConfiguredExtensionRegistryUrl(): boolean {
if (typeof this.extensionRegistryUrl === "boolean") {
return this.extensionRegistryUrl;
}
return false;
}
/**
* Download kubectl binaries matching cluster version
*/
@ -209,6 +225,7 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
this.downloadBinariesPath = DESCRIPTORS.downloadBinariesPath.fromStore(preferences?.downloadBinariesPath);
this.kubectlBinariesPath = DESCRIPTORS.kubectlBinariesPath.fromStore(preferences?.kubectlBinariesPath);
this.openAtLogin = DESCRIPTORS.openAtLogin.fromStore(preferences?.openAtLogin);
this.extensionRegistryUrl = DESCRIPTORS.extensionRegistryUrl.fromStore(preferences?.extensionRegistryUrl);
this.hiddenTableColumns.replace(DESCRIPTORS.hiddenTableColumns.fromStore(preferences?.hiddenTableColumns));
this.syncKubeconfigEntries.replace(DESCRIPTORS.syncKubeconfigEntries.fromStore(preferences?.syncKubeconfigEntries));
this.editorConfiguration = DESCRIPTORS.editorConfiguration.fromStore(preferences?.editorConfiguration);
@ -230,6 +247,7 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
downloadBinariesPath: DESCRIPTORS.downloadBinariesPath.toStore(this.downloadBinariesPath),
kubectlBinariesPath: DESCRIPTORS.kubectlBinariesPath.toStore(this.kubectlBinariesPath),
openAtLogin: DESCRIPTORS.openAtLogin.toStore(this.openAtLogin),
extensionRegistryUrl: DESCRIPTORS.extensionRegistryUrl.toStore(this.extensionRegistryUrl),
hiddenTableColumns: DESCRIPTORS.hiddenTableColumns.toStore(this.hiddenTableColumns),
syncKubeconfigEntries: DESCRIPTORS.syncKubeconfigEntries.toStore(this.syncKubeconfigEntries),
editorConfiguration: DESCRIPTORS.editorConfiguration.toStore(this.editorConfiguration),

View File

@ -47,6 +47,7 @@ import { Notice } from "./notice";
import { SettingLayout } from "../layout/setting-layout";
import { docsUrl } from "../../../common/vars";
import { dialog } from "../../remote-helpers";
import { UserStore } from "../../../common/user-store";
function getMessageFromError(error: any): string {
if (!error || typeof error !== "object") {
@ -299,9 +300,19 @@ async function unpackExtension(request: InstallRequestValidated, disposeDownload
}
}
const defaultBaseRegistryUrl = "https://registry.npmjs.com";
export const defaultBaseRegistryUrl = "https://registry.npmjs.com";
async function getBaseRegistryUrl(): Promise<string> {
const userStore = UserStore.getInstance();
if (userStore.extensionRegistryUrl === false) {
return defaultBaseRegistryUrl;
}
if (typeof userStore.extensionRegistryUrl === "string") {
return userStore.extensionRegistryUrl;
}
try {
const filteredEnv = Object.fromEntries(
Object.entries(process.env)

View File

@ -29,6 +29,8 @@ import { Input } from "../input";
import { isWindows } from "../../../common/vars";
import { FormSwitch, Switcher } from "../switch";
import moment from "moment-timezone";
import { defaultBaseRegistryUrl } from "../+extensions";
import { Checkbox } from "../mui/checkbox";
const timezoneOptions: SelectOption<string>[] = moment.tz.names().map(zone => ({
label: zone,
@ -43,8 +45,13 @@ export const Application = observer(() => {
? "powershell.exe"
: "System default shell"
);
const [shell, setShell] = React.useState(UserStore.getInstance().shell || "");
const userStore = UserStore.getInstance();
const [shell, setShell] = React.useState(userStore.shell || "");
const [extensionRegistryUrl, setExtensionRegistryUrl] = React.useState(
typeof userStore.extensionRegistryUrl === "string"
? userStore.extensionRegistryUrl
: ""
);
return (
<section id="application">
@ -53,8 +60,8 @@ export const Application = observer(() => {
<SubTitle title="Theme"/>
<Select
options={ThemeStore.getInstance().themeOptions}
value={UserStore.getInstance().colorTheme}
onChange={({ value }: SelectOption) => UserStore.getInstance().colorTheme = value}
value={userStore.colorTheme}
onChange={({ value }: SelectOption) => userStore.colorTheme = value}
themeName="lens"
/>
</section>
@ -68,8 +75,35 @@ export const Application = observer(() => {
placeholder={defaultShell}
value={shell}
onChange={v => setShell(v)}
onBlur={() => UserStore.getInstance().shell = shell}
onBlur={() => userStore.shell = shell}
/>
</section><hr />
<section id="registry">
<SubTitle title="Extension registry" />
<FormSwitch
control={
<Checkbox
checked={userStore.getUseConfiguredExtensionRegistryUrl}
indeterminate={typeof userStore.extensionRegistryUrl === "string"}
onChange={(event, checked) => {
userStore.extensionRegistryUrl = checked;
setExtensionRegistryUrl("");
}}
/>
}
label="Use .npmrc configuration"
/>
<Input
theme="round-black"
placeholder={defaultBaseRegistryUrl}
value={extensionRegistryUrl}
onChange={setExtensionRegistryUrl}
onBlur={() => userStore.extensionRegistryUrl = extensionRegistryUrl}
/>
<small className="hint">
The registry URL for installing extensions by name.
</small>
</section>
<hr/>
@ -79,8 +113,8 @@ export const Application = observer(() => {
<FormSwitch
control={
<Switcher
checked={UserStore.getInstance().openAtLogin}
onChange={v => UserStore.getInstance().openAtLogin = v.target.checked}
checked={userStore.openAtLogin}
onChange={v => userStore.openAtLogin = v.target.checked}
name="startup"
/>
}
@ -94,8 +128,8 @@ export const Application = observer(() => {
<SubTitle title="Locale Timezone" />
<Select
options={timezoneOptions}
value={UserStore.getInstance().localeTimezone}
onChange={({ value }: SelectOption) => UserStore.getInstance().setLocaleTimezone(value)}
value={userStore.localeTimezone}
onChange={({ value }: SelectOption) => userStore.setLocaleTimezone(value)}
themeName="lens"
/>
</section>

View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { Checkbox as MuiCheckbox, CheckboxClassKey, CheckboxProps, createStyles, Theme, withStyles } from "@material-ui/core";
import React from "react";
interface Styles extends Partial<Record<CheckboxClassKey, string>> {
}
interface Props extends CheckboxProps {
classes: Styles;
}
export const Checkbox = withStyles((theme: Theme) =>
createStyles({
root: {
width: 40,
height: 24,
padding: 0,
margin: "0 0 0 8px",
},
colorPrimary: { },
colorSecondary: { },
checked: {},
disabled: {},
indeterminate: {},
input: {},
}),
)(({ classes, ...props }: Props) => {
return (
<MuiCheckbox
classes={{
root: classes.root,
colorPrimary: classes.colorPrimary,
colorSecondary: classes.colorSecondary,
checked: classes.checked,
disabled: classes.disabled,
indeterminate: classes.indeterminate,
input: classes.input,
}}
{...props}
/>
);
});

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
export * from "./checkbox";