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

Introduce competition for application preference tab

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2022-10-13 14:16:59 +03:00
parent 0dc45c7ce9
commit bdd945a6d3
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
13 changed files with 455 additions and 0 deletions

View File

@ -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;

View File

@ -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 = () => (
<div>
<h2 data-testid="application-header">Application</h2>
</div>
);

View File

@ -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;

View File

@ -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;

View File

@ -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 (
<section id="extensionRegistryUrl">
<SubTitle title="Extension Install Registry" />
<Select
id="extension-install-registry-input"
options={extensionInstallRegistryOptions}
value={userStore.extensionRegistryUrl.location}
onChange={(value) =>
runInAction(() => {
userStore.extensionRegistryUrl.location =
value?.value ?? defaultExtensionRegistryUrlLocation;
if (userStore.extensionRegistryUrl.location === "custom") {
userStore.extensionRegistryUrl.customUrl = "";
}
})
}
themeName="lens"
/>
<p className="mt-4 mb-5 leading-relaxed">
{
"This setting is to change the registry URL for installing extensions by name. "
}
{`If you are unable to access the default registry (${defaultExtensionRegistryUrl}) you can change it in your `}
<b>.npmrc</b>
{" file or in the input below."}
</p>
<Input
theme="round-black"
validators={isUrl}
value={customUrl}
onChange={setCustomUrl}
onBlur={() => (userStore.extensionRegistryUrl.customUrl = customUrl)}
placeholder="Custom Extension Registry URL..."
disabled={userStore.extensionRegistryUrl.location !== "custom"}
/>
</section>
);
});
export const ExtensionInstallRegistry = withInjectables<Dependencies>(
NonInjectedExtensionInstallRegistry,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
}),
},
);

View File

@ -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;

View File

@ -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) => (
<section id="other">
<SubTitle title="Start-up" />
<Switch
checked={userStore.openAtLogin}
onChange={() => (userStore.openAtLogin = !userStore.openAtLogin)}
>
Automatically start Lens on login
</Switch>
</section>
));
export const StartUp = withInjectables<Dependencies>(
NonInjectedStartUp,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
}),
},
);

View File

@ -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;

View File

@ -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 (
<section id="appearance">
<SubTitle title="Theme" />
<Select
id="theme-input"
options={themeOptions}
value={userStore.colorTheme}
onChange={(value) =>
(userStore.colorTheme = value?.value ?? defaultThemeId)
}
themeName="lens"
/>
</section>
);
});
export const Theme = withInjectables<Dependencies>(
NonInjectedTheme,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
themeStore: di.inject(themeStoreInjectable),
}),
},
);

View File

@ -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 { Timezone } from "./timezone";
const timezonePreferenceItemInjectable = getInjectable({
id: "timezone-preference-item",
instantiate: () => ({
kind: "item" as const,
id: "timezone",
parentId: "application-page",
orderNumber: 60,
Component: Timezone,
}),
injectionToken: preferenceItemInjectionToken,
});
export default timezonePreferenceItemInjectable;

View File

@ -0,0 +1,48 @@
/**
* 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 { Select } from "../../../../../../renderer/components/select";
import { defaultLocaleTimezone } from "../../../../../../common/user-store/preferences-helpers";
import moment from "moment-timezone";
import { observer } from "mobx-react";
interface Dependencies {
userStore: UserStore;
}
const timezoneOptions = moment.tz.names()
.map(timezone => ({
value: timezone,
label: timezone.replace("_", " "),
}));
const NonInjectedTimezone = observer(({ userStore }: Dependencies) => (
<section id="locale">
<SubTitle title="Locale Timezone" />
<Select
id="timezone-input"
options={timezoneOptions}
value={userStore.localeTimezone}
onChange={value => userStore.localeTimezone = value?.value ?? defaultLocaleTimezone}
themeName="lens"
/>
</section>
));
export const Timezone = withInjectables<Dependencies>(
NonInjectedTimezone,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
}),
},
);

View File

@ -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;

View File

@ -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) => (
<section id="update-channel">
<SubTitle title="Update Channel" />
<Select
id="update-channel-input"
options={updateChannelOptions}
value={selectedUpdateChannel.value.get().id}
onChange={(selected) => selectedUpdateChannel.setValue(selected?.value)}
themeName="lens"
/>
</section>
));
export const UpdateChannel = withInjectables<Dependencies>(
NonInjectedUpdateChannel,
{
getProps: (di) => ({
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
}),
},
);