From bdd945a6d3eaa9d88937412168742b1f7c6597b4 Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Thu, 13 Oct 2022 14:16:59 +0300 Subject: [PATCH] Introduce competition for application preference tab Co-authored-by: Mikko Aspiala Signed-off-by: Janne Savolainen --- .../application-preference-page.injectable.ts | 23 +++++ .../application-preference-page.tsx | 11 +++ .../application-preference-tab.injectable.ts | 24 +++++ ...all-registry-preference-item.injectable.ts | 23 +++++ .../extension-install-registry.tsx | 88 +++++++++++++++++++ .../start-up-preference-item.injectable.ts | 23 +++++ .../application/start-up/start-up.tsx | 37 ++++++++ .../theme/theme-preference-item.injectable.ts | 23 +++++ .../application/theme/theme.tsx | 58 ++++++++++++ .../timezone-preference-item.injectable.ts | 23 +++++ .../application/timezone/timezone.tsx | 48 ++++++++++ ...date-channel-preference-item.injectable.ts | 23 +++++ .../update-channel/update-channel.tsx | 51 +++++++++++ 13 files changed, 455 insertions(+) create mode 100644 src/features/preferences/renderer/preference-items/application/application-preference-page.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/application-preference-page.tsx create mode 100644 src/features/preferences/renderer/preference-items/application/application-preference-tab.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry-preference-item.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry.tsx create mode 100644 src/features/preferences/renderer/preference-items/application/start-up/start-up-preference-item.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/start-up/start-up.tsx create mode 100644 src/features/preferences/renderer/preference-items/application/theme/theme-preference-item.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/theme/theme.tsx create mode 100644 src/features/preferences/renderer/preference-items/application/timezone/timezone-preference-item.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/timezone/timezone.tsx create mode 100644 src/features/preferences/renderer/preference-items/application/update-channel/update-channel-preference-item.injectable.ts create mode 100644 src/features/preferences/renderer/preference-items/application/update-channel/update-channel.tsx diff --git a/src/features/preferences/renderer/preference-items/application/application-preference-page.injectable.ts b/src/features/preferences/renderer/preference-items/application/application-preference-page.injectable.ts new file mode 100644 index 0000000000..1c193ed49e --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/application-preference-page.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../preference-item-injection-token"; +import { ApplicationPreferencePage } from "./application-preference-page"; + +const applicationPreferencePageInjectable = getInjectable({ + id: "application-preference-page", + + instantiate: () => ({ + kind: "page" as const, + id: "application-page", + parentId: "application-tab", + orderNumber: 0, + Component: ApplicationPreferencePage, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default applicationPreferencePageInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/application-preference-page.tsx b/src/features/preferences/renderer/preference-items/application/application-preference-page.tsx new file mode 100644 index 0000000000..10b416f7bb --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/application-preference-page.tsx @@ -0,0 +1,11 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; + +export const ApplicationPreferencePage = () => ( +
+

Application

+
+); diff --git a/src/features/preferences/renderer/preference-items/application/application-preference-tab.injectable.ts b/src/features/preferences/renderer/preference-items/application/application-preference-tab.injectable.ts new file mode 100644 index 0000000000..c89b35e894 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/application-preference-tab.injectable.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../preference-item-injection-token"; + +const applicationPreferenceTabInjectable = getInjectable({ + id: "application-preference-tab", + + instantiate: () => ({ + kind: "tab" as const, + id: "application-tab", + parentId: "preference-tabs" as const, + pathId: "app", + testId: "application-preferences-page", + label: "Application", + orderNumber: 10, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default applicationPreferenceTabInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry-preference-item.injectable.ts new file mode 100644 index 0000000000..3184f2e666 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { ExtensionInstallRegistry } from "./extension-install-registry"; + +const extensionInstallRegistryPreferenceItemInjectable = getInjectable({ + id: "extension-install-registry-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "extension-install-registry", + parentId: "application-page", + orderNumber: 20, + Component: ExtensionInstallRegistry, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default extensionInstallRegistryPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry.tsx b/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry.tsx new file mode 100644 index 0000000000..ce6aed0a5f --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/extension-install-registry/extension-install-registry.tsx @@ -0,0 +1,88 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { Select } from "../../../../../../renderer/components/select"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import { defaultExtensionRegistryUrl, defaultExtensionRegistryUrlLocation } from "../../../../../../common/user-store/preferences-helpers"; +import { Input } from "../../../../../../renderer/components/input"; +import { isUrl } from "../../../../../../renderer/components/input/input_validators"; +import type { UserStore } from "../../../../../../common/user-store"; +import { runInAction } from "mobx"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { observer } from "mobx-react"; + +interface Dependencies { + userStore: UserStore; +} + +const extensionInstallRegistryOptions = [ + { + value: "default", + label: "Default Url", + }, + { + value: "npmrc", + label: "Global .npmrc file's Url", + }, + { + value: "custom", + label: "Custom Url", + }, +] as const; + +const NonInjectedExtensionInstallRegistry = observer(({ userStore }: Dependencies) => { + const [customUrl, setCustomUrl] = React.useState(userStore.extensionRegistryUrl.customUrl || ""); + + return ( +
+ + (userStore.extensionRegistryUrl.customUrl = customUrl)} + placeholder="Custom Extension Registry URL..." + disabled={userStore.extensionRegistryUrl.location !== "custom"} + /> +
+ ); +}); + +export const ExtensionInstallRegistry = withInjectables( + NonInjectedExtensionInstallRegistry, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/application/start-up/start-up-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/application/start-up/start-up-preference-item.injectable.ts new file mode 100644 index 0000000000..045477f28c --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/start-up/start-up-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { StartUp } from "./start-up"; + +const startUpPreferenceItemInjectable = getInjectable({ + id: "start-up-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "start-up", + parentId: "application-page", + orderNumber: 30, + Component: StartUp, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default startUpPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/start-up/start-up.tsx b/src/features/preferences/renderer/preference-items/application/start-up/start-up.tsx new file mode 100644 index 0000000000..427705cca1 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/start-up/start-up.tsx @@ -0,0 +1,37 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import { Switch } from "../../../../../../renderer/components/switch"; +import { observer } from "mobx-react"; + +interface Dependencies { + userStore: UserStore; +} + +const NonInjectedStartUp = observer(({ userStore }: Dependencies) => ( +
+ + (userStore.openAtLogin = !userStore.openAtLogin)} + > + Automatically start Lens on login + +
+)); + +export const StartUp = withInjectables( + NonInjectedStartUp, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/application/theme/theme-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/application/theme/theme-preference-item.injectable.ts new file mode 100644 index 0000000000..b19c04dad3 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/theme/theme-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { Theme } from "./theme"; + +const themePreferenceItemInjectable = getInjectable({ + id: "theme-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "theme", + parentId: "application-page", + orderNumber: 10, + Component: Theme, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default themePreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/theme/theme.tsx b/src/features/preferences/renderer/preference-items/application/theme/theme.tsx new file mode 100644 index 0000000000..851cc638d4 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/theme/theme.tsx @@ -0,0 +1,58 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { Select } from "../../../../../../renderer/components/select"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import { observer } from "mobx-react"; +import type { UserStore } from "../../../../../../common/user-store"; +import type { ThemeStore } from "../../../../../../renderer/themes/store"; +import { defaultThemeId } from "../../../../../../common/vars"; +import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable"; +import themeStoreInjectable from "../../../../../../renderer/themes/store.injectable"; + +interface Dependencies { + userStore: UserStore; + themeStore: ThemeStore; +} + +const NonInjectedTheme = observer(({ userStore, themeStore }: Dependencies) => { + const themeOptions = [ + { + value: "system", // TODO: replace with a sentinal value that isn't string (and serialize it differently) + label: "Sync with computer", + }, + ...Array.from(themeStore.themes, ([themeId, { name }]) => ({ + value: themeId, + label: name, + })), + ]; + + return ( +
+ + userStore.localeTimezone = value?.value ?? defaultLocaleTimezone} + themeName="lens" + /> +
+ +)); + +export const Timezone = withInjectables( + NonInjectedTimezone, + + { + getProps: (di) => ({ + userStore: di.inject(userStoreInjectable), + }), + }, +); diff --git a/src/features/preferences/renderer/preference-items/application/update-channel/update-channel-preference-item.injectable.ts b/src/features/preferences/renderer/preference-items/application/update-channel/update-channel-preference-item.injectable.ts new file mode 100644 index 0000000000..c210fb5092 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/update-channel/update-channel-preference-item.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { preferenceItemInjectionToken } from "../../preference-item-injection-token"; +import { UpdateChannel } from "./update-channel"; + +const updateChannelPreferenceItemInjectable = getInjectable({ + id: "update-channel-preference-item", + + instantiate: () => ({ + kind: "item" as const, + id: "update-channel", + parentId: "application-page", + orderNumber: 50, + Component: UpdateChannel, + }), + + injectionToken: preferenceItemInjectionToken, +}); + +export default updateChannelPreferenceItemInjectable; diff --git a/src/features/preferences/renderer/preference-items/application/update-channel/update-channel.tsx b/src/features/preferences/renderer/preference-items/application/update-channel/update-channel.tsx new file mode 100644 index 0000000000..96d2b26d24 --- /dev/null +++ b/src/features/preferences/renderer/preference-items/application/update-channel/update-channel.tsx @@ -0,0 +1,51 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import React from "react"; +import { SubTitle } from "../../../../../../renderer/components/layout/sub-title"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import { Select } from "../../../../../../renderer/components/select"; +import { updateChannels } from "../../../../../application-update/common/update-channels"; +import type { SelectedUpdateChannel } from "../../../../../application-update/common/selected-update-channel/selected-update-channel.injectable"; +import selectedUpdateChannelInjectable from "../../../../../application-update/common/selected-update-channel/selected-update-channel.injectable"; +import { pipeline } from "@ogre-tools/fp"; +import { map, toPairs } from "lodash/fp"; +import { observer } from "mobx-react"; + +interface Dependencies { + selectedUpdateChannel: SelectedUpdateChannel; +} + +const updateChannelOptions = pipeline( + toPairs(updateChannels), + + map(([, channel]) => ({ + value: channel.id, + label: channel.label, + })), +); + + +const NonInjectedUpdateChannel = observer(({ selectedUpdateChannel }: Dependencies) => ( +
+ +