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

converting app-preferences to use di

Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>
This commit is contained in:
Jim Ehrismann 2022-01-07 19:26:33 -05:00
parent e862d5bf1d
commit a185227ca2
14 changed files with 211 additions and 86 deletions

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../registries/app-preference-registry";
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../../renderer/components/+preferences/app-preferences/app-preference-registration";
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry";
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../registries/kube-object-menu-registry";
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry";

View File

@ -252,7 +252,6 @@ export class ExtensionLoader {
return this.autoInitExtensions(async (extension: LensRendererExtension) => {
const removeItems = [
registries.GlobalPageRegistry.getInstance().add(extension.globalPages, extension),
registries.AppPreferenceRegistry.getInstance().add(extension.appPreferences),
registries.EntitySettingRegistry.getInstance().add(extension.entitySettings),
registries.StatusBarRegistry.getInstance().add(extension.statusBarItems),
registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems),

View File

@ -15,13 +15,14 @@ import type { KubernetesCluster } from "../common/catalog-entities";
import type { WelcomeMenuRegistration } from "../renderer/components/+welcome/welcome-menu-items/welcome-menu-registration";
import type { WelcomeBannerRegistration } from "../renderer/components/+welcome/welcome-banner-items/welcome-banner-registration";
import type { CommandRegistration } from "../renderer/components/command-palette/registered-commands/commands";
import type { AppPreferenceRegistration } from "../renderer/components/+preferences/app-preferences/app-preference-registration";
export class LensRendererExtension extends LensExtension {
globalPages: registries.PageRegistration[] = [];
clusterPages: registries.PageRegistration[] = [];
clusterPageMenus: registries.ClusterPageMenuRegistration[] = [];
kubeObjectStatusTexts: registries.KubeObjectStatusRegistration[] = [];
appPreferences: registries.AppPreferenceRegistration[] = [];
appPreferences: AppPreferenceRegistration[] = [];
entitySettings: registries.EntitySettingRegistration[] = [];
statusBarItems: registries.StatusBarRegistration[] = [];
kubeObjectDetailItems: registries.KubeObjectDetailRegistration[] = [];

View File

@ -1,32 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type React from "react";
import { BaseRegistry } from "./base-registry";
export interface AppPreferenceComponents {
Hint: React.ComponentType<any>;
Input: React.ComponentType<any>;
}
export interface AppPreferenceRegistration {
title: string;
id?: string;
showInPreferencesTab?: string;
components: AppPreferenceComponents;
}
export interface RegisteredAppPreference extends AppPreferenceRegistration {
id: string;
}
export class AppPreferenceRegistry extends BaseRegistry<AppPreferenceRegistration, RegisteredAppPreference> {
getRegisteredItem(item: AppPreferenceRegistration): RegisteredAppPreference {
return {
id: item.id || item.title.toLowerCase().replace(/[^0-9a-zA-Z]+/g, "-"),
...item,
};
}
}

View File

@ -7,7 +7,6 @@
export * from "./page-registry";
export * from "./page-menu-registry";
export * from "./app-preference-registry";
export * from "./status-bar-registry";
export * from "./kube-object-detail-registry";
export * from "./kube-object-menu-registry";

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type React from "react";
export interface AppPreferenceComponents {
Hint: React.ComponentType<any>;
Input: React.ComponentType<any>;
}
export interface AppPreferenceRegistration {
title: string;
id?: string;
showInPreferencesTab?: string;
components: AppPreferenceComponents;
}

View File

@ -0,0 +1,34 @@
/**
* 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 { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
import rendererExtensionsInjectable from "../../../../extensions/renderer-extensions.injectable";
import { getAppPreferences } from "./get-app-preferences";
const appPreferencesInjectable = getInjectable({
instantiate: (di) =>
getAppPreferences({
extensions: di.inject(rendererExtensionsInjectable),
}),
lifecycle: lifecycleEnum.singleton,
});
export default appPreferencesInjectable;

View File

@ -0,0 +1,49 @@
/**
* 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 { computed, IComputedValue } from "mobx";
import type { LensRendererExtension } from "../../../../extensions/lens-renderer-extension";
import type { AppPreferenceRegistration } from "./app-preference-registration";
interface Dependencies {
extensions: IComputedValue<LensRendererExtension[]>;
}
interface RegisteredAppPreference extends AppPreferenceRegistration {
id: string;
}
function getRegisteredItem(item: AppPreferenceRegistration): RegisteredAppPreference {
return {
id: item.id || item.title.toLowerCase().replace(/[^0-9a-zA-Z]+/g, "-"),
...item,
};
}
export const getAppPreferences = ({ extensions }: Dependencies) => {
return computed(() => {
return [
...extensions.get()
.flatMap((extension) => extension.appPreferences)
.map(pref => getRegisteredItem(pref)),
];},
);
};

View File

@ -14,10 +14,12 @@ import { isWindows } from "../../../common/vars";
import { Switch } from "../switch";
import moment from "moment-timezone";
import { CONSTANTS, defaultExtensionRegistryUrl, ExtensionRegistryLocation } from "../../../common/user-store/preferences-helpers";
import { action } from "mobx";
import { action, IComputedValue } from "mobx";
import { isUrl } from "../input/input_validators";
import { AppPreferenceRegistry } from "../../../extensions/registries";
import { ExtensionSettings } from "./extension-settings";
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
import { withInjectables } from "@ogre-tools/injectable-react";
import appPreferencesInjectable from "./app-preferences/app-preferences.injectable";
const timezoneOptions: SelectOption<string>[] = moment.tz.names().map(zone => ({
label: zone,
@ -28,7 +30,11 @@ const updateChannelOptions: SelectOption<string>[] = Array.from(
([value, { label }]) => ({ value, label }),
);
export const Application = observer(() => {
interface Dependencies {
appPreferenceItems: IComputedValue<AppPreferenceRegistration[]>
}
const NonInjectedApplication: React.FC<Dependencies> = ({ appPreferenceItems }) => {
const userStore = UserStore.getInstance();
const defaultShell = process.env.SHELL
|| process.env.PTYSHELL
@ -40,7 +46,7 @@ export const Application = observer(() => {
const [customUrl, setCustomUrl] = React.useState(userStore.extensionRegistryUrl.customUrl || "");
const [shell, setShell] = React.useState(userStore.shell || "");
const extensionSettings = AppPreferenceRegistry.getInstance().getItems().filter((preference) => preference.showInPreferencesTab === "application");
const extensionSettings = appPreferenceItems.get().filter((preference) => preference.showInPreferencesTab === "application");
const themeStore = ThemeStore.getInstance();
return (
@ -125,10 +131,10 @@ export const Application = observer(() => {
/>
</section>
<hr/>
<hr />
<section id="other">
<SubTitle title="Start-up"/>
<SubTitle title="Start-up" />
<Switch checked={userStore.openAtLogin} onChange={() => userStore.openAtLogin = !userStore.openAtLogin}>
Automatically start Lens on login
</Switch>
@ -141,7 +147,7 @@ export const Application = observer(() => {
))}
<section id="update-channel">
<SubTitle title="Update Channel"/>
<SubTitle title="Update Channel" />
<Select
options={updateChannelOptions}
value={userStore.updateChannel}
@ -163,4 +169,14 @@ export const Application = observer(() => {
</section>
</section>
);
});
};
export const Application = withInjectables<Dependencies>(
observer(NonInjectedApplication),
{
getProps: (di) => ({
appPreferenceItems: di.inject(appPreferencesInjectable),
}),
},
);

View File

@ -3,12 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { SubTitle } from "../layout/sub-title";
import type { RegisteredAppPreference } from "../../../extensions/registries/app-preference-registry";
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
import React from "react";
import { cssNames } from "../../../renderer/utils";
interface ExtensionSettingsProps {
setting: RegisteredAppPreference;
setting: AppPreferenceRegistration;
size: "small" | "normal"
}

View File

@ -3,13 +3,21 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { withInjectables } from "@ogre-tools/injectable-react";
import type { IComputedValue } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { AppPreferenceRegistry } from "../../../extensions/registries";
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
import appPreferencesInjectable from "./app-preferences/app-preferences.injectable";
import { ExtensionSettings } from "./extension-settings";
export const Extensions = observer(() => {
const settings = AppPreferenceRegistry.getInstance().getItems();
interface Dependencies {
appPreferenceItems: IComputedValue<AppPreferenceRegistration[]>
}
const NonInjectedExtensions: React.FC<Dependencies> = ({ appPreferenceItems }) => {
const settings = appPreferenceItems.get();
return (
<section id="extensions">
@ -19,4 +27,14 @@ export const Extensions = observer(() => {
)}
</section>
);
});
};
export const Extensions = withInjectables<Dependencies>(
observer(NonInjectedExtensions),
{
getProps: (di) => ({
appPreferenceItems: di.inject(appPreferencesInjectable),
}),
},
);

View File

@ -4,7 +4,7 @@
*/
import "./preferences.scss";
import { makeObservable, observable } from "mobx";
import type { IComputedValue } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { matchPath, Redirect, Route, RouteProps, Switch } from "react-router";
@ -23,7 +23,6 @@ import {
telemetryRoute,
telemetryURL,
} from "../../../common/routes";
import { AppPreferenceRegistry } from "../../../extensions/registries/app-preference-registry";
import { navigateWithoutHistoryChange, navigation } from "../../navigation";
import { SettingLayout } from "../layout/setting-layout";
import { Tab, Tabs } from "../tabs";
@ -34,18 +33,18 @@ import { LensProxy } from "./proxy";
import { Telemetry } from "./telemetry";
import { Extensions } from "./extensions";
import { sentryDsn } from "../../../common/vars";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
import appPreferencesInjectable from "./app-preferences/app-preferences.injectable";
@observer
export class Preferences extends React.Component {
@observable historyLength: number | undefined;
interface Dependencies {
appPreferenceItems: IComputedValue<AppPreferenceRegistration[]>
}
constructor(props: {}) {
super(props);
makeObservable(this);
}
const NonInjectedPreferences: React.FC<Dependencies> = ({ appPreferenceItems }) => {
renderNavigation() {
const extensions = AppPreferenceRegistry.getInstance().getItems();
function renderNavigation() {
const extensions = appPreferenceItems.get();
const telemetryExtensions = extensions.filter(e => e.showInPreferencesTab == "telemetry");
const currentLocation = navigation.location.pathname;
const isActive = (route: RouteProps) => !!matchPath(currentLocation, { path: route.path, exact: route.exact });
@ -67,23 +66,31 @@ export class Preferences extends React.Component {
);
}
render() {
return (
<SettingLayout
navigation={this.renderNavigation()}
className="Preferences"
contentGaps={false}
>
<Switch>
<Route path={appURL()} component={Application}/>
<Route path={proxyURL()} component={LensProxy}/>
<Route path={kubernetesURL()} component={Kubernetes}/>
<Route path={editorURL()} component={Editor}/>
<Route path={telemetryURL()} component={Telemetry}/>
<Route path={extensionURL()} component={Extensions}/>
<Redirect exact from={`${preferencesURL()}/`} to={appURL()}/>
</Switch>
</SettingLayout>
);
}
}
return (
<SettingLayout
navigation={renderNavigation()}
className="Preferences"
contentGaps={false}
>
<Switch>
<Route path={appURL()} component={Application}/>
<Route path={proxyURL()} component={LensProxy}/>
<Route path={kubernetesURL()} component={Kubernetes}/>
<Route path={editorURL()} component={Editor}/>
<Route path={telemetryURL()} component={Telemetry}/>
<Route path={extensionURL()} component={Extensions}/>
<Redirect exact from={`${preferencesURL()}/`} to={appURL()}/>
</Switch>
</SettingLayout>
);
};
export const Preferences = withInjectables<Dependencies>(
observer(NonInjectedPreferences),
{
getProps: (di) => ({
appPreferenceItems: di.inject(appPreferencesInjectable),
}),
},
);

View File

@ -6,13 +6,20 @@ 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 "./extension-settings";
import type { AppPreferenceRegistration } from "./app-preferences/app-preference-registration";
import appPreferencesInjectable from "./app-preferences/app-preferences.injectable";
import type { IComputedValue } from "mobx";
import { withInjectables } from "@ogre-tools/injectable-react";
export const Telemetry = observer(() => {
const extensions = AppPreferenceRegistry.getInstance().getItems();
interface Dependencies {
appPreferenceItems: IComputedValue<AppPreferenceRegistration[]>
}
const NonInjectedTelemetry: React.FC<Dependencies> = ({ appPreferenceItems }) => {
const extensions = appPreferenceItems.get();
const telemetryExtensions = extensions.filter(e => e.showInPreferencesTab == "telemetry");
return (
@ -44,4 +51,14 @@ export const Telemetry = observer(() => {
}
</section>
);
});
};
export const Telemetry = withInjectables<Dependencies>(
observer(NonInjectedTelemetry),
{
getProps: (di) => ({
appPreferenceItems: di.inject(appPreferencesInjectable),
}),
},
);

View File

@ -6,7 +6,6 @@
import * as registries from "../../extensions/registries";
export function initRegistries() {
registries.AppPreferenceRegistry.createInstance();
registries.CatalogEntityDetailRegistry.createInstance();
registries.ClusterPageMenuRegistry.createInstance();
registries.ClusterPageRegistry.createInstance();