From 3ea47fe764c7c45817269dc6453b9bbbe1391209 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 5 Aug 2021 16:36:19 +0300 Subject: [PATCH] Convert Preferences to Route-based component Signed-off-by: Alex Andreev --- src/common/routes/preferences.ts | 25 ++ .../components/+preferences/application.tsx | 104 ++++++ .../components/+preferences/extensions.tsx | 38 +++ .../components/+preferences/kubernetes.tsx | 47 +++ .../components/+preferences/preferences.tsx | 306 ++++-------------- .../components/+preferences/proxy.tsx | 71 ++++ .../components/+preferences/telemetry.tsx | 63 ++++ src/renderer/theme.store.ts | 8 + 8 files changed, 427 insertions(+), 235 deletions(-) create mode 100644 src/renderer/components/+preferences/application.tsx create mode 100644 src/renderer/components/+preferences/extensions.tsx create mode 100644 src/renderer/components/+preferences/kubernetes.tsx create mode 100644 src/renderer/components/+preferences/proxy.tsx create mode 100644 src/renderer/components/+preferences/telemetry.tsx diff --git a/src/common/routes/preferences.ts b/src/common/routes/preferences.ts index 45fd3074c8..bae7e6257e 100644 --- a/src/common/routes/preferences.ts +++ b/src/common/routes/preferences.ts @@ -26,4 +26,29 @@ export const preferencesRoute: RouteProps = { path: "/preferences" }; +export const appRoute: RouteProps = { + path: `${preferencesRoute.path}/app` +}; + +export const proxyRoute: RouteProps = { + path: `${preferencesRoute.path}/proxy` +}; + +export const kubernetesRoute: RouteProps = { + path: `${preferencesRoute.path}/kubernetes` +}; + +export const telemetryRoute: RouteProps = { + path: `${preferencesRoute.path}/telemetry` +}; + +export const extensionRoute: RouteProps = { + path: `${preferencesRoute.path}/extensions` +}; + export const preferencesURL = buildURL(preferencesRoute.path); +export const appURL = buildURL(appRoute.path); +export const proxyURL = buildURL(proxyRoute.path); +export const kubernetesURL = buildURL(kubernetesRoute.path); +export const telemetryURL = buildURL(telemetryRoute.path); +export const extensionURL = buildURL(extensionRoute.path); diff --git a/src/renderer/components/+preferences/application.tsx b/src/renderer/components/+preferences/application.tsx new file mode 100644 index 0000000000..ac05012f2f --- /dev/null +++ b/src/renderer/components/+preferences/application.tsx @@ -0,0 +1,104 @@ +/** + * 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 React from "react"; +import { observer } from "mobx-react"; +import { SubTitle } from "../layout/sub-title"; +import { Select, SelectOption } from "../select"; +import { ThemeStore } from "../../theme.store"; +import { UserStore } from "../../../common/user-store"; +import { Input } from "../input"; +import { isWindows } from "../../../common/vars"; +import { FormSwitch, Switcher } from "../switch"; +import moment from "moment-timezone"; + +const timezoneOptions: SelectOption[] = moment.tz.names().map(zone => ({ + label: zone, + value: zone, +})); + +export const Application = observer(() => { + const defaultShell = process.env.SHELL + || process.env.PTYSHELL + || ( + isWindows + ? "powershell.exe" + : "System default shell" + ); + + const [shell, setShell] = React.useState(UserStore.getInstance().shell || ""); + + return ( +
+

Application

+
+ + setShell(v)} + onBlur={() => UserStore.getInstance().shell = shell} + /> +
+ +
+ +
+ + UserStore.getInstance().openAtLogin = v.target.checked} + name="startup" + /> + } + label="Automatically start Lens on login" + /> +
+ +
+ +
+ + -
- -
-
-
- - ); - } - render() { - const extensions = AppPreferenceRegistry.getInstance().getItems(); - const telemetryExtensions = extensions.filter(e => e.showInPreferencesTab == Pages.Telemetry); - const defaultShell = process.env.SHELL - || process.env.PTYSHELL - || ( - isWindows - ? "powershell.exe" - : "System default shell" - ); - return ( - {this.activeTab == Pages.Application && ( -
-

Application

-
- - this.shell = v} - onBlur={() => UserStore.getInstance().shell = this.shell} - /> -
- -
- -
- - UserStore.getInstance().openAtLogin = v.target.checked} - name="startup" - /> - } - label="Automatically start Lens on login" - /> -
- -
- -
- - this.httpProxy = v} - onBlur={() => UserStore.getInstance().httpsProxy = this.httpProxy} - /> - - Proxy is used only for non-cluster communication. - -
- -
- -
- - UserStore.getInstance().allowUntrustedCAs = v.target.checked} - name="startup" - /> - } - label="Allow untrusted Certificate Authorities" - /> - - 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! - -
-
- )} - {this.activeTab == Pages.Kubernetes && ( -
-
-

Kubernetes

- -
-
-
-

Kubeconfig Syncs

- -
-
-
-

Helm Charts

- -
-
- )} - {this.activeTab == Pages.Telemetry && ( -
-

Telemetry

- {telemetryExtensions.map(this.renderExtension)} - {sentryDsn ? ( - -
- - { - UserStore.getInstance().allowErrorReporting = value; - }} - /> -
- - Automatic error reports provide vital information about issues and application crashes. - It is highly recommended to keep this feature enabled to ensure fast turnaround for issues you might encounter. - -
-
-
-
) : - // we don't need to shows the checkbox at all if Sentry dsn is not a valid url - null - } -
- )} - {this.activeTab == Pages.Extensions && ( -
-

Extensions

- {extensions.filter(e => !e.showInPreferencesTab).map(this.renderExtension)} -
- )} + + + + + + + +
); } } + +export function ExtensionSettings({ title, id, components: { Hint, Input } }: RegisteredAppPreference) { + return ( + +
+ + +
+ +
+
+
+
+ ); +} diff --git a/src/renderer/components/+preferences/proxy.tsx b/src/renderer/components/+preferences/proxy.tsx new file mode 100644 index 0000000000..b85bd5e0e1 --- /dev/null +++ b/src/renderer/components/+preferences/proxy.tsx @@ -0,0 +1,71 @@ +/** + * 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 { observer } from "mobx-react"; +import React from "react"; + +import { UserStore } from "../../../common/user-store"; +import { Input } from "../input"; +import { SubTitle } from "../layout/sub-title"; +import { FormSwitch, Switcher } from "../switch"; + +export const LensProxy = observer(() => { + const [proxy, setProxy] = React.useState(UserStore.getInstance().httpsProxy || ""); + + return ( +
+
+

Proxy

+ + setProxy(v)} + onBlur={() => UserStore.getInstance().httpsProxy = proxy} + /> + + Proxy is used only for non-cluster communication. + +
+ +
+ +
+ + UserStore.getInstance().allowUntrustedCAs = v.target.checked} + name="startup" + /> + } + label="Allow untrusted Certificate Authorities" + /> + + 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! + +
+
+ ); +}); diff --git a/src/renderer/components/+preferences/telemetry.tsx b/src/renderer/components/+preferences/telemetry.tsx new file mode 100644 index 0000000000..5414382f92 --- /dev/null +++ b/src/renderer/components/+preferences/telemetry.tsx @@ -0,0 +1,63 @@ +/** + * 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 { observer } from "mobx-react"; +import React from "react"; +import { UserStore } from "../../../common/user-store"; +import { sentryDsn } from "../../../common/vars"; +import { AppPreferenceRegistry } from "../../../extensions/registries"; +import { Checkbox } from "../checkbox"; +import { SubTitle } from "../layout/sub-title"; +import { ExtensionSettings } from "./preferences"; + +export const Telemetry = observer(() => { + const extensions = AppPreferenceRegistry.getInstance().getItems(); + const telemetryExtensions = extensions.filter(e => e.showInPreferencesTab == "telemetry"); + + return ( +
+

Telemetry

+ {telemetryExtensions.map((extension) => )} + {sentryDsn ? ( + +
+ + { + UserStore.getInstance().allowErrorReporting = value; + }} + /> +
+ + Automatic error reports provide vital information about issues and application crashes. + It is highly recommended to keep this feature enabled to ensure fast turnaround for issues you might encounter. + +
+
+
+
) : + // we don't need to shows the checkbox at all if Sentry dsn is not a valid url + null + } +
+ ); +}); diff --git a/src/renderer/theme.store.ts b/src/renderer/theme.store.ts index 5bfd76210d..28faa49999 100644 --- a/src/renderer/theme.store.ts +++ b/src/renderer/theme.store.ts @@ -25,6 +25,7 @@ import { UserStore } from "../common/user-store"; import logger from "../main/logger"; import darkTheme from "./themes/lens-dark.json"; import lightTheme from "./themes/lens-light.json"; +import type { SelectOption } from "./components/select"; export type ThemeId = string; @@ -67,6 +68,13 @@ export class ThemeStore extends Singleton { return this.allThemes.get(this.activeThemeId) ?? this.allThemes.get("lens-dark"); } + @computed get themeOptions(): SelectOption[] { + return this.themes.map(theme => ({ + label: theme.name, + value: theme.id, + })); + } + constructor() { super();