diff --git a/src/common/utils/composable-responsibilities/orderable/orderable.ts b/src/common/utils/composable-responsibilities/orderable/orderable.ts index e0425cc0a7..2b4d95b3f4 100644 --- a/src/common/utils/composable-responsibilities/orderable/orderable.ts +++ b/src/common/utils/composable-responsibilities/orderable/orderable.ts @@ -19,3 +19,7 @@ export const orderByOrderNumber = (maybeOrderables: T[ : Number.MAX_SAFE_INTEGER, maybeOrderables, ); + +export const byOrderNumber = (left: T, right: T) => ( + left.orderNumber - right.orderNumber +); diff --git a/src/extensions/extension-loader/extension-loader.ts b/src/extensions/extension-loader/extension-loader.ts index 5c63451276..23840b67c4 100644 --- a/src/extensions/extension-loader/extension-loader.ts +++ b/src/extensions/extension-loader/extension-loader.ts @@ -261,7 +261,6 @@ export class ExtensionLoader { return this.autoInitExtensions(async (ext) => { const extension = ext as LensRendererExtension; const removeItems = [ - registries.EntitySettingRegistry.getInstance().add(extension.entitySettings), registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems), ]; diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts index d0a2a979e6..fb60d6aed8 100644 --- a/src/extensions/lens-renderer-extension.ts +++ b/src/extensions/lens-renderer-extension.ts @@ -29,6 +29,7 @@ import type { KubeObjectHandlerRegistration } from "../renderer/kube-object/hand import type { AppPreferenceTabRegistration } from "../features/preferences/renderer/compliance-for-legacy-extension-api/app-preference-tab-registration"; import type { KubeObjectDetailRegistration } from "../renderer/components/kube-object-details/kube-object-detail-registration"; import type { ClusterFrameChildComponent } from "../renderer/frames/cluster-frame/cluster-frame-child-component-injection-token"; +import type { EntitySettingRegistration } from "../renderer/components/+entity-settings/extension-registrator.injectable"; export class LensRendererExtension extends LensExtension { globalPages: registries.PageRegistration[] = []; @@ -38,7 +39,7 @@ export class LensRendererExtension extends LensExtension; -} - -export interface EntitySettingRegistration { - apiVersions: string[]; - kind: string; - title: string; - components: EntitySettingComponents; - source?: string; - id?: string; - priority?: number; - group?: string; -} - -export interface RegisteredEntitySetting extends EntitySettingRegistration { - id: string; -} - -export class EntitySettingRegistry extends BaseRegistry { - getRegisteredItem(item: EntitySettingRegistration): RegisteredEntitySetting { - return { - id: item.id || item.title.toLowerCase(), - ...item, - }; - } - - getItemsForKind(kind: string, apiVersion: string, source?: string) { - let items = this.getItems().filter((item) => { - return item.kind === kind && item.apiVersions.includes(apiVersion); - }); - - if (source) { - items = items.filter((item) => { - return !item.source || item.source === source; - }); - } - - return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50)); - } -} diff --git a/src/extensions/registries/index.ts b/src/extensions/registries/index.ts index f916600903..2841b4c031 100644 --- a/src/extensions/registries/index.ts +++ b/src/extensions/registries/index.ts @@ -7,6 +7,5 @@ export * from "./page-registry"; export * from "./page-menu-registry"; -export * from "./entity-setting-registry"; export * from "./catalog-entity-detail-registry"; export * from "./protocol-handler"; diff --git a/src/renderer/components/+catalog/columns/extensions-registrator.injectable.ts b/src/renderer/components/+catalog/columns/extensions-registrator.injectable.ts index c4223da3ea..7482f216ee 100644 --- a/src/renderer/components/+catalog/columns/extensions-registrator.injectable.ts +++ b/src/renderer/components/+catalog/columns/extensions-registrator.injectable.ts @@ -3,7 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { ExtensionRegistrator } from "../../../../extensions/extension-loader/extension-registrator-injection-token"; import { extensionRegistratorInjectionToken } from "../../../../extensions/extension-loader/extension-registrator-injection-token"; import type { LensRendererExtension } from "../../../../extensions/lens-renderer-extension"; import type { AdditionalCategoryColumnRegistration } from "../custom-category-columns"; @@ -11,12 +10,10 @@ import { customCatalogCategoryColumnInjectionToken } from "./custom-token"; const customCategoryColumnsRegistratorInjectable = getInjectable({ id: "custom-category-columns-registrator", - instantiate: (): ExtensionRegistrator => { - return (ext) => { - const extension = ext as LensRendererExtension; + instantiate: () => (ext) => { + const extension = ext as LensRendererExtension; - return extension.additionalCategoryColumns.map(getInjectableForColumnRegistrationFor(extension)); - }; + return extension.additionalCategoryColumns.map(getInjectableForColumnRegistrationFor(extension)); }, injectionToken: extensionRegistratorInjectionToken, }); diff --git a/src/renderer/components/+entity-settings/active-tabs.injectable.ts b/src/renderer/components/+entity-settings/active-tabs.injectable.ts new file mode 100644 index 0000000000..1c9e22e803 --- /dev/null +++ b/src/renderer/components/+entity-settings/active-tabs.injectable.ts @@ -0,0 +1,79 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import { action } from "mobx"; +import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable"; +import type { CatalogEntity } from "../../api/catalog-entity"; +import observableHistoryInjectable from "../../navigation/observable-history.injectable"; +import type { RegisteredEntitySetting } from "./extension-registrator.injectable"; +import catalogEntitySettingItemsInjectable from "./settings.injectable"; + +export interface SettingTabs { + title: string; + id: string; +} + +export interface SettingGroup { + title: string; + tabs: SettingTabs[]; +} + +export interface ActiveEntitySettingDetails { + tabId: string | undefined; + setting: RegisteredEntitySetting | undefined; + groups: SettingGroup[]; +} + +export interface ActiveEntitySettings { + get: () => ActiveEntitySettingDetails; + set: (tabId: string) => void; +} + +const settingsGroup = "Settings"; +const defaultExtensionsGroup = "Extensions"; + +const getSettingGroups = (items: RegisteredEntitySetting[]): SettingGroup[] => { + const groupNames = new Set(items.map(({ group }) => group)); + const titles = [...groupNames].sort((left, right) => { + if (left === settingsGroup) return -1; + if (left === defaultExtensionsGroup) return 1; + + return left <= right ? -1 : 1; + }); + + return titles.map(title => ({ + title, + tabs: items + .filter(({ group }) => group === title) + .sort(byOrderNumber), + })); +}; + +const activeEntitySettingsTabInjectable = getInjectable({ + id: "active-entity-settings-tab", + instantiate: (di, entity): ActiveEntitySettings => { + const observableHistory = di.inject(observableHistoryInjectable); + const items = di.inject(catalogEntitySettingItemsInjectable, entity); + + return { + get: () => { + const defaultTabId = items.get()[0]?.id; + const tabId = observableHistory.location.hash.slice(1) || defaultTabId; + const setting = items.get().find(({ id }) => id === tabId); + const groups = getSettingGroups(items.get()); + + return { tabId, setting, groups }; + }, + set: action((tabId) => { + observableHistory.location.hash = tabId; + }), + }; + }, + lifecycle: lifecycleEnum.keyedSingleton({ + getInstanceKey: (di, entity: CatalogEntity) => `${entity.apiVersion}/${entity.kind}[${entity.metadata.source ?? ""}]`, + }), +}); + +export default activeEntitySettingsTabInjectable; diff --git a/src/renderer/components/+entity-settings/current-entity.injectable.ts b/src/renderer/components/+entity-settings/current-entity.injectable.ts new file mode 100644 index 0000000000..fded6d096a --- /dev/null +++ b/src/renderer/components/+entity-settings/current-entity.injectable.ts @@ -0,0 +1,20 @@ +/** + * 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 { computed } from "mobx"; +import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; +import entitySettingsRouteParametersInjectable from "./route-parameters.injectable"; + +const currentCatalogEntityForSettingsInjectable = getInjectable({ + id: "current-catalog-entity-for-settings", + instantiate: (di) => { + const { entityId } = di.inject(entitySettingsRouteParametersInjectable); + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + + return computed(() => catalogEntityRegistry.getById(entityId.get())); + }, +}); + +export default currentCatalogEntityForSettingsInjectable; diff --git a/src/renderer/components/+entity-settings/entity-settings.tsx b/src/renderer/components/+entity-settings/entity-settings.tsx index b1c672ae2e..994ad0aefd 100644 --- a/src/renderer/components/+entity-settings/entity-settings.tsx +++ b/src/renderer/components/+entity-settings/entity-settings.tsx @@ -7,155 +7,115 @@ import styles from "./entity-settings.module.scss"; import React from "react"; import type { IComputedValue } from "mobx"; -import { observable, makeObservable, computed } from "mobx"; import { observer } from "mobx-react"; import { Tabs, Tab } from "../tabs"; import type { CatalogEntity } from "../../api/catalog-entity"; -import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry"; -import { EntitySettingRegistry } from "../../../extensions/registries"; -import { groupBy } from "lodash"; import { SettingLayout } from "../layout/setting-layout"; -import logger from "../../../common/logger"; import { Avatar } from "../avatar"; import { withInjectables } from "@ogre-tools/injectable-react"; -import entitySettingsRouteParametersInjectable from "./entity-settings-route-parameters.injectable"; -import type { ObservableHistory } from "mobx-observable-history"; -import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; -import observableHistoryInjectable from "../../navigation/observable-history.injectable"; +import currentCatalogEntityForSettingsInjectable from "./current-entity.injectable"; +import type { ActiveEntitySettings } from "./active-tabs.injectable"; +import activeEntitySettingsTabInjectable from "./active-tabs.injectable"; interface Dependencies { - entityId: IComputedValue; - entityRegistry: CatalogEntityRegistry; - observableHistory: ObservableHistory; + entity: IComputedValue; } -@observer -class NonInjectedEntitySettings extends React.Component { - @observable activeTab?: string; +const NonInjectedEntitySettings = observer((props: Dependencies) => { + const entity = props.entity.get(); - constructor(props: Dependencies) { - super(props); - makeObservable(this); - - const { hash } = this.props.observableHistory.location; - - if (hash) { - const menuId = hash.slice(1); - const item = this.menuItems.find((item) => item.id === menuId); - - if (item) { - this.activeTab = item.id; - } - } + if (!entity) { + return null; } - @computed - get entityId() { - return this.props.entityId.get(); - } + return ; +}); - get entity() { - return this.props.entityRegistry.getById(this.entityId); - } - - get menuItems() { - if (!this.entity) return []; - - return EntitySettingRegistry.getInstance().getItemsForKind(this.entity.kind, this.entity.apiVersion, this.entity.metadata.source); - } - - get activeSetting() { - this.activeTab ||= this.menuItems[0]?.id; - - return this.menuItems.find((setting) => setting.id === this.activeTab); - } - - onTabChange = (tabId: string) => { - this.activeTab = tabId; - }; - - renderNavigation(entity: CatalogEntity) { - const groups = Object.entries(groupBy(this.menuItems, (item) => item.group || "Extensions")); - - groups.sort((a, b) => { - if (a[0] === "Settings") return -1; - if (a[0] === "Extensions") return 1; - - return a[0] <= b[0] ? -1 : 1; - }); - - return ( - <> -
- -
- {entity.getName()} -
-
- - { groups.map((group, groupIndex) => ( - -
-
{group[0]}
- { group[1].map((setting, index) => ( - - ))} -
- ))} -
- - ); - } - - render() { - const { activeSetting, entity } = this; - - if (!entity) { - logger.error("[ENTITY-SETTINGS]: entity not found", this.entityId); - - return null; - } - - return ( - - { - activeSetting && ( -
-

{activeSetting.title}

-
- -
-
- ) - } -
- ); - } -} - -export const EntitySettings = withInjectables(NonInjectedEntitySettings, { +export const EntitySettingsRouteComponent = withInjectables(NonInjectedEntitySettings, { getProps: (di) => ({ - ...di.inject(entitySettingsRouteParametersInjectable), - entityRegistry: di.inject(catalogEntityRegistryInjectable), - observableHistory: di.inject(observableHistoryInjectable), + entity: di.inject(currentCatalogEntityForSettingsInjectable), + }), +}); + +interface CatalogEntitySettingsProps { + entity: CatalogEntity; +} + +interface CatalogEntitySettingsDeps { + activeEntitySettingsTab: ActiveEntitySettings; +} + +const NonInjectedCatalogEntitySettings = observer((props: CatalogEntitySettingsProps & CatalogEntitySettingsDeps) => { + const { + activeEntitySettingsTab, + entity, + } = props; + const { tabId, setting, groups } = activeEntitySettingsTab.get(); + + const renderNavigation = () => ( + <> +
+ +
+ {entity.getName()} +
+
+ + { + groups.map(({ tabs, title }) => ( + +
+
{title}
+ { + tabs.map((setting) => ( + + )) + } +
+ )) + } +
+ + ); + + return ( + + { + (tabId && setting) && ( +
+

{setting.title}

+
+ +
+
+ ) + } +
+ ); +}); + +const CatalogEntitySettings = withInjectables(NonInjectedCatalogEntitySettings, { + getProps: (di, props) => ({ + ...props, + activeEntitySettingsTab: di.inject(activeEntitySettingsTabInjectable, props.entity), }), }); diff --git a/src/renderer/components/+entity-settings/extension-registrator.injectable.ts b/src/renderer/components/+entity-settings/extension-registrator.injectable.ts new file mode 100644 index 0000000000..19187d921d --- /dev/null +++ b/src/renderer/components/+entity-settings/extension-registrator.injectable.ts @@ -0,0 +1,75 @@ +/** + * 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 { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token"; +import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension"; +import type { CatalogEntity } from "../../api/catalog-entity"; +import { entitySettingInjectionToken } from "./token"; + +export interface EntitySettingViewProps { + entity: CatalogEntity; +} + +export interface EntitySettingComponents { + View: React.ComponentType; +} + +export interface EntitySettingRegistration { + apiVersions: string[]; + kind: string; + title: string; + components: EntitySettingComponents; + source?: string; + id?: string; + priority?: number; + group?: string; +} + +export interface RegisteredEntitySetting { + id: string; + orderNumber: number; + apiVersions: Set; + kind: string; + title: string; + components: EntitySettingComponents; + source?: string; + group: string; +} + +const entitySettingExtensionRegistratorInjectable = getInjectable({ + id: "entity-setting-extension-registrator", + instantiate: () => (ext) => { + const extension = ext as LensRendererExtension; + + return extension.entitySettings.map(getInjectableForEntitySettingRegistrationFor(extension)); + }, + injectionToken: extensionRegistratorInjectionToken, +}); + +export default entitySettingExtensionRegistratorInjectable; + +const getInjectableForEntitySettingRegistrationFor = (extension: LensRendererExtension) => ({ + apiVersions, + components, + kind, + title, + group = "Extensions", + id = title.toLowerCase(), + priority, + source, +}: EntitySettingRegistration) => getInjectable({ + id: `${extension.manifest.name}:${group}/${kind}:${id}`, + instantiate: () => ({ + apiVersions: new Set(apiVersions), + components, + id, + kind, + orderNumber: priority ?? 50, + title, + group, + source, + }), + injectionToken: entitySettingInjectionToken, +}); diff --git a/src/renderer/components/+entity-settings/has-settings.injectable.ts b/src/renderer/components/+entity-settings/has-settings.injectable.ts new file mode 100644 index 0000000000..7712951a42 --- /dev/null +++ b/src/renderer/components/+entity-settings/has-settings.injectable.ts @@ -0,0 +1,20 @@ +/** + * 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 type { CatalogEntity } from "../../api/catalog-entity"; +import catalogEntitySettingItemsInjectable from "./settings.injectable"; + +export type HasCatalogEntitySettingItems = (entity: CatalogEntity) => boolean; + +const hasCatalogEntitySettingItemsInjectable = getInjectable({ + id: "has-catalog-entity-settings", + instantiate: (di): HasCatalogEntitySettingItems => (entity) => { + const items = di.inject(catalogEntitySettingItemsInjectable, entity); + + return items.get().length > 0; + }, +}); + +export default hasCatalogEntitySettingItemsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/general-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/general-settings.injectable.tsx new file mode 100644 index 0000000000..737e0db5c4 --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/general-settings.injectable.tsx @@ -0,0 +1,71 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { KubernetesCluster } from "../../../../common/catalog-entities"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterIconSetting } from "../../cluster-settings/icon-settings"; +import { ClusterKubeconfig } from "../../cluster-settings/kubeconfig"; +import { ClusterNameSetting } from "../../cluster-settings/name-setting"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedGeneralKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ ); +} + +const GeneralKubernetesClusterSettings = withInjectables(NonInjectedGeneralKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const generalKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "general-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + source: "local", + title: "General", + group: "Settings", + id: "general", + priority: 40, + components: { + View: GeneralKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default generalKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/metrics-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/metrics-settings.injectable.tsx new file mode 100644 index 0000000000..e5afa9fba1 --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/metrics-settings.injectable.tsx @@ -0,0 +1,64 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterMetricsSetting } from "../../cluster-settings/metrics-setting"; +import { ClusterPrometheusSetting } from "../../cluster-settings/prometheus-setting"; +import { ShowMetricsSetting } from "../../cluster-settings/show-metrics"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedMetricsKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+
+ +
+
+
+ + +
+
+ ); +} + +const MetricsKubernetesClusterSettings = withInjectables(NonInjectedMetricsKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const metricsKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "metrics-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Metrics", + group: "Settings", + id: "metrics", + priority: 40, + components: { + View: MetricsKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default metricsKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/namespace-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/namespace-settings.injectable.tsx new file mode 100644 index 0000000000..9e0f404ad0 --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/namespace-settings.injectable.tsx @@ -0,0 +1,55 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterAccessibleNamespaces } from "../../cluster-settings/accessible-namespaces"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedProxyKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+ +
+ ); +} + +const NamespaceKubernetesClusterSettings = withInjectables(NonInjectedProxyKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const namespaceKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "namespace-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Namespace", + group: "Settings", + id: "namespace", + priority: 40, + components: { + View: NamespaceKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default namespaceKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/node-shell-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/node-shell-settings.injectable.tsx new file mode 100644 index 0000000000..b013d5ea5e --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/node-shell-settings.injectable.tsx @@ -0,0 +1,55 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterNodeShellSetting } from "../../cluster-settings/node-shell-setting"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedNodeShellKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+ +
+ ); +} + +const NodeShellKubernetesClusterSettings = withInjectables(NonInjectedNodeShellKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const nodeShellKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "node-shell-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Node Shell", + group: "Settings", + id: "node-shell", + priority: 40, + components: { + View: NodeShellKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default nodeShellKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/proxy-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/proxy-settings.injectable.tsx new file mode 100644 index 0000000000..7db969b504 --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/proxy-settings.injectable.tsx @@ -0,0 +1,55 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterProxySetting } from "../../cluster-settings/proxy-setting"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedProxyKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+ +
+ ); +} + +const ProxyKubernetesClusterSettings = withInjectables(NonInjectedProxyKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const proxyKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "proxy-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Proxy", + group: "Settings", + id: "proxy", + priority: 40, + components: { + View: ProxyKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default proxyKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/internal-kubernetes-cluster/terminal-settings.injectable.tsx b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/terminal-settings.injectable.tsx new file mode 100644 index 0000000000..da6ddb7aa1 --- /dev/null +++ b/src/renderer/components/+entity-settings/internal-kubernetes-cluster/terminal-settings.injectable.tsx @@ -0,0 +1,55 @@ +/** + * 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 { withInjectables } from "@ogre-tools/injectable-react"; +import React from "react"; +import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable"; +import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import { ClusterLocalTerminalSetting } from "../../cluster-settings/local-terminal-settings"; +import type { EntitySettingViewProps } from "../extension-registrator.injectable"; +import { entitySettingInjectionToken } from "../token"; + +interface Dependencies { + getClusterById: GetClusterById; +} + +function NonInjectedTerminalKubernetesClusterSettings({ entity, getClusterById }: EntitySettingViewProps & Dependencies) { + const cluster = getClusterById(entity.getId()); + + if (!cluster) { + return null; + } + + return ( +
+ +
+ ); +} + +const TerminalKubernetesClusterSettings = withInjectables(NonInjectedTerminalKubernetesClusterSettings, { + getProps: (di, props) => ({ + ...props, + getClusterById: di.inject(getClusterByIdInjectable), + }), +}); + +const terminalKubernetesClusterEntitySettingsInjectable = getInjectable({ + id: "terminal-kubernetes-cluster-entity-settings", + instantiate: () => ({ + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Terminal", + group: "Settings", + id: "terminal", + priority: 40, + components: { + View: TerminalKubernetesClusterSettings, + }, + }), + injectionToken: entitySettingInjectionToken, +}); + +export default terminalKubernetesClusterEntitySettingsInjectable; diff --git a/src/renderer/components/+entity-settings/entity-settings-route-component.injectable.ts b/src/renderer/components/+entity-settings/route-component.injectable.ts similarity index 87% rename from src/renderer/components/+entity-settings/entity-settings-route-component.injectable.ts rename to src/renderer/components/+entity-settings/route-component.injectable.ts index 5e3a2da43f..deedaca53a 100644 --- a/src/renderer/components/+entity-settings/entity-settings-route-component.injectable.ts +++ b/src/renderer/components/+entity-settings/route-component.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { EntitySettings } from "./entity-settings"; +import { EntitySettingsRouteComponent } from "./entity-settings"; import { routeSpecificComponentInjectionToken } from "../../routes/route-specific-component-injection-token"; import entitySettingsRouteInjectable from "../../../common/front-end-routing/routes/entity-settings/entity-settings-route.injectable"; @@ -12,7 +12,7 @@ const entitySettingsRouteComponentInjectable = getInjectable({ instantiate: (di) => ({ route: di.inject(entitySettingsRouteInjectable), - Component: EntitySettings, + Component: EntitySettingsRouteComponent, }), injectionToken: routeSpecificComponentInjectionToken, diff --git a/src/renderer/components/+entity-settings/entity-settings-route-parameters.injectable.ts b/src/renderer/components/+entity-settings/route-parameters.injectable.ts similarity index 100% rename from src/renderer/components/+entity-settings/entity-settings-route-parameters.injectable.ts rename to src/renderer/components/+entity-settings/route-parameters.injectable.ts diff --git a/src/renderer/components/+entity-settings/settings.injectable.ts b/src/renderer/components/+entity-settings/settings.injectable.ts new file mode 100644 index 0000000000..dd63065620 --- /dev/null +++ b/src/renderer/components/+entity-settings/settings.injectable.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx"; +import { computed } from "mobx"; +import { byOrderNumber } from "../../../common/utils/composable-responsibilities/orderable/orderable"; +import type { CatalogEntity } from "../../api/catalog-entity"; +import { entitySettingInjectionToken } from "./token"; + +const catalogEntitySettingItemsInjectable = getInjectable({ + id: "entity-settings", + instantiate: (di, entity) => { + const computedInjectMany = di.inject(computedInjectManyInjectable); + const items = computedInjectMany(entitySettingInjectionToken); + + return computed(() => ( + items.get() + .filter(item => ( + item.apiVersions.has(entity.apiVersion) + && item.kind === entity.kind + && (!item.source || item.source === entity.metadata.source) + )) + .sort(byOrderNumber) + )); + }, + lifecycle: lifecycleEnum.keyedSingleton({ + getInstanceKey: (di, entity: CatalogEntity) => `${entity.apiVersion}/${entity.kind}[${entity.metadata.source ?? ""}]`, + }), +}); + +export default catalogEntitySettingItemsInjectable; diff --git a/src/renderer/components/+entity-settings/token.ts b/src/renderer/components/+entity-settings/token.ts new file mode 100644 index 0000000000..187cb0c635 --- /dev/null +++ b/src/renderer/components/+entity-settings/token.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { RegisteredEntitySetting } from "./extension-registrator.injectable"; + +export const entitySettingInjectionToken = getInjectionToken({ + id: "entity-setting", +}); diff --git a/src/renderer/components/cluster-settings/components/__tests__/cluster-local-terminal-settings.test.tsx b/src/renderer/components/cluster-settings/__tests__/cluster-local-terminal-settings.test.tsx similarity index 88% rename from src/renderer/components/cluster-settings/components/__tests__/cluster-local-terminal-settings.test.tsx rename to src/renderer/components/cluster-settings/__tests__/cluster-local-terminal-settings.test.tsx index b4a78a5dc0..f583f2fb2a 100644 --- a/src/renderer/components/cluster-settings/components/__tests__/cluster-local-terminal-settings.test.tsx +++ b/src/renderer/components/cluster-settings/__tests__/cluster-local-terminal-settings.test.tsx @@ -5,15 +5,15 @@ import React from "react"; import { waitFor } from "@testing-library/react"; -import { ClusterLocalTerminalSetting } from "../cluster-local-terminal-settings"; +import { ClusterLocalTerminalSetting } from "../local-terminal-settings"; import userEvent from "@testing-library/user-event"; import type { Stats } from "fs"; -import type { Cluster } from "../../../../../common/cluster/cluster"; -import { getDiForUnitTesting } from "../../../../getDiForUnitTesting"; -import type { DiRender } from "../../../test-utils/renderFor"; -import { renderFor } from "../../../test-utils/renderFor"; -import showErrorNotificationInjectable from "../../../notifications/show-error-notification.injectable"; -import statInjectable from "../../../../../common/fs/stat/stat.injectable"; +import type { Cluster } from "../../../../common/cluster/cluster"; +import { getDiForUnitTesting } from "../../../getDiForUnitTesting"; +import type { DiRender } from "../../test-utils/renderFor"; +import { renderFor } from "../../test-utils/renderFor"; +import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable"; +import statInjectable from "../../../../common/fs/stat/stat.injectable"; describe("ClusterLocalTerminalSettings", () => { let render: DiRender; diff --git a/src/renderer/components/cluster-settings/components/cluster-accessible-namespaces.tsx b/src/renderer/components/cluster-settings/accessible-namespaces.tsx similarity index 87% rename from src/renderer/components/cluster-settings/components/cluster-accessible-namespaces.tsx rename to src/renderer/components/cluster-settings/accessible-namespaces.tsx index 8ef03aa6b1..479cc8f443 100644 --- a/src/renderer/components/cluster-settings/components/cluster-accessible-namespaces.tsx +++ b/src/renderer/components/cluster-settings/accessible-namespaces.tsx @@ -5,11 +5,11 @@ import React from "react"; import { observer } from "mobx-react"; -import type { Cluster } from "../../../../common/cluster/cluster"; -import { SubTitle } from "../../layout/sub-title"; -import { EditableList } from "../../editable-list"; +import type { Cluster } from "../../../common/cluster/cluster"; +import { SubTitle } from "../layout/sub-title"; +import { EditableList } from "../editable-list"; import { observable, makeObservable } from "mobx"; -import { systemName } from "../../input/input_validators"; +import { systemName } from "../input/input_validators"; export interface ClusterAccessibleNamespacesProps { cluster: Cluster; diff --git a/src/renderer/components/cluster-settings/cluster-settings.tsx b/src/renderer/components/cluster-settings/cluster-settings.tsx deleted file mode 100644 index e89a600095..0000000000 --- a/src/renderer/components/cluster-settings/cluster-settings.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import React from "react"; -import type { KubernetesCluster } from "../../../common/catalog-entities"; -import { ClusterStore } from "../../../common/cluster-store/cluster-store"; -import type { EntitySettingViewProps } from "../../../extensions/registries"; -import type { CatalogEntity } from "../../api/catalog-entity"; -import * as components from "./components"; - -function getClusterForEntity(entity: CatalogEntity) { - return ClusterStore.getInstance().getById(entity.getId()); -} - -export function GeneralSettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if (!cluster) { - return null; - } - - return ( -
-
-
-
- -
-
- -
-
-
-
- -
-
- ); -} - -export function ProxySettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if (!cluster) { - return null; - } - - return ( -
- -
- ); -} - -export function TerminalSettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if (!cluster) { - return null; - } - - return ( -
- -
- ); -} - -export function NamespacesSettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if (!cluster) { - return null; - } - - return ( -
- -
- ); -} - -export function MetricsSettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if (!cluster) { - return null; - } - - return ( -
-
- -
-
-
- - -
-
- ); -} - -export function NodeShellSettings({ entity }: EntitySettingViewProps) { - const cluster = getClusterForEntity(entity); - - if(!cluster) { - return null; - } - - return ( -
- -
- ); -} diff --git a/src/renderer/components/cluster-settings/components/index.ts b/src/renderer/components/cluster-settings/components/index.ts deleted file mode 100644 index 8c878bc415..0000000000 --- a/src/renderer/components/cluster-settings/components/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -export * from "./cluster-accessible-namespaces"; -export * from "./cluster-local-terminal-settings"; -export * from "./cluster-kubeconfig"; -export * from "./cluster-metrics-setting"; -export * from "./cluster-name-setting"; -export * from "./cluster-prometheus-setting"; -export * from "./cluster-proxy-setting"; -export * from "./cluster-show-metrics"; -export * from "./cluster-icon-settings"; -export * from "./cluster-node-shell-setting"; diff --git a/src/renderer/components/cluster-settings/components/cluster-icon-settings.tsx b/src/renderer/components/cluster-settings/icon-settings.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-icon-settings.tsx rename to src/renderer/components/cluster-settings/icon-settings.tsx diff --git a/src/renderer/components/cluster-settings/index.ts b/src/renderer/components/cluster-settings/index.ts deleted file mode 100644 index 3699309256..0000000000 --- a/src/renderer/components/cluster-settings/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -export * from "./cluster-settings"; diff --git a/src/renderer/components/cluster-settings/components/cluster-kubeconfig.tsx b/src/renderer/components/cluster-settings/kubeconfig.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-kubeconfig.tsx rename to src/renderer/components/cluster-settings/kubeconfig.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-local-terminal-settings.tsx b/src/renderer/components/cluster-settings/local-terminal-settings.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-local-terminal-settings.tsx rename to src/renderer/components/cluster-settings/local-terminal-settings.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx b/src/renderer/components/cluster-settings/metrics-setting.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx rename to src/renderer/components/cluster-settings/metrics-setting.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-name-setting.tsx b/src/renderer/components/cluster-settings/name-setting.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-name-setting.tsx rename to src/renderer/components/cluster-settings/name-setting.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-node-shell-setting.tsx b/src/renderer/components/cluster-settings/node-shell-setting.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-node-shell-setting.tsx rename to src/renderer/components/cluster-settings/node-shell-setting.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx b/src/renderer/components/cluster-settings/prometheus-setting.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx rename to src/renderer/components/cluster-settings/prometheus-setting.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx b/src/renderer/components/cluster-settings/proxy-setting.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-proxy-setting.tsx rename to src/renderer/components/cluster-settings/proxy-setting.tsx diff --git a/src/renderer/components/cluster-settings/components/cluster-show-metrics.tsx b/src/renderer/components/cluster-settings/show-metrics.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/cluster-show-metrics.tsx rename to src/renderer/components/cluster-settings/show-metrics.tsx diff --git a/src/renderer/components/command-palette/registered-commands/get-entity-setting-commands.injectable.ts b/src/renderer/components/command-palette/registered-commands/get-entity-setting-commands.injectable.ts deleted file mode 100644 index c2ea86d29c..0000000000 --- a/src/renderer/components/command-palette/registered-commands/get-entity-setting-commands.injectable.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 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 type { RegisteredEntitySetting } from "../../../../extensions/registries"; -import { EntitySettingRegistry } from "../../../../extensions/registries"; - -export type GetEntitySettingCommands = (kind: string, apiVersion: string, source?: string) => RegisteredEntitySetting[]; - -const getEntitySettingCommandsInjectable = getInjectable({ - id: "get-entity-setting-commands", - instantiate: (): GetEntitySettingCommands => { - const reg = EntitySettingRegistry.getInstance(); - - return (kind, apiVersion, source) => reg.getItemsForKind(kind, apiVersion, source); - }, - causesSideEffects: true, -}); - -export default getEntitySettingCommandsInjectable; diff --git a/src/renderer/components/command-palette/registered-commands/internal-commands.injectable.tsx b/src/renderer/components/command-palette/registered-commands/internal-commands.injectable.tsx index 27bbc4aab7..7026d8882b 100644 --- a/src/renderer/components/command-palette/registered-commands/internal-commands.injectable.tsx +++ b/src/renderer/components/command-palette/registered-commands/internal-commands.injectable.tsx @@ -4,7 +4,6 @@ */ import React from "react"; -import type { RegisteredEntitySetting } from "../../../../extensions/registries"; import { HotbarAddCommand } from "../../hotbar/hotbar-add-command"; import { HotbarRemoveCommand } from "../../hotbar/hotbar-remove-command"; import { HotbarSwitchCommand } from "../../hotbar/hotbar-switch-command"; @@ -37,10 +36,11 @@ import navigateToJobsInjectable from "../../../../common/front-end-routing/route import navigateToCronJobsInjectable from "../../../../common/front-end-routing/routes/cluster/workloads/cron-jobs/navigate-to-cron-jobs.injectable"; import navigateToCustomResourcesInjectable from "../../../../common/front-end-routing/routes/cluster/custom-resources/custom-resources/navigate-to-custom-resources.injectable"; import navigateToEntitySettingsInjectable from "../../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable"; -import getEntitySettingCommandsInjectable from "./get-entity-setting-commands.injectable"; // TODO: Importing from features is not OK. Make commands to comply with Open Closed Principle to allow moving implementation under a feature import navigateToPreferencesInjectable from "../../../../features/preferences/common/navigate-to-preferences.injectable"; +import type { HasCatalogEntitySettingItems } from "../../+entity-settings/has-settings.injectable"; +import hasCatalogEntitySettingItemsInjectable from "../../+entity-settings/has-settings.injectable"; export function isKubernetesClusterActive(context: CommandContext): boolean { return context.entity?.kind === "KubernetesCluster"; @@ -48,9 +48,8 @@ export function isKubernetesClusterActive(context: CommandContext): boolean { interface Dependencies { openCommandDialog: (component: React.ReactElement) => void; - getEntitySettingItems: (kind: string, apiVersion: string, source?: string) => RegisteredEntitySetting[]; + hasCatalogEntitySettingItems: HasCatalogEntitySettingItems; createTerminalTab: () => DockTabCreate; - navigateToPreferences: () => void; navigateToHelmCharts: () => void; navigateToHelmReleases: () => void; @@ -214,8 +213,7 @@ function getInternalCommands(dependencies: Dependencies): CommandRegistration[] title: ({ entity }) => `${entity.kind}/${entity.getName()}: View Settings`, action: ({ entity }) => dependencies.navigateToEntitySettings(entity.getId()), isActive: ({ entity }) => ( - entity - && dependencies.getEntitySettingItems(entity.kind, entity.apiVersion, entity.metadata.source).length > 0 + entity && dependencies.hasCatalogEntitySettingItems(entity) ), }, { @@ -257,7 +255,7 @@ const internalCommandsInjectable = getInjectable({ instantiate: (di) => getInternalCommands({ openCommandDialog: di.inject(commandOverlayInjectable).open, - getEntitySettingItems: di.inject(getEntitySettingCommandsInjectable), + hasCatalogEntitySettingItems: di.inject(hasCatalogEntitySettingItemsInjectable), createTerminalTab: di.inject(createTerminalTabInjectable), navigateToPreferences: di.inject(navigateToPreferencesInjectable), navigateToHelmCharts: di.inject(navigateToHelmChartsInjectable), diff --git a/src/renderer/components/tabs/tabs.tsx b/src/renderer/components/tabs/tabs.tsx index cfbcf8d5ea..7b08b63159 100644 --- a/src/renderer/components/tabs/tabs.tsx +++ b/src/renderer/components/tabs/tabs.tsx @@ -9,23 +9,23 @@ import React from "react"; import { autoBind, cssNames } from "../../utils"; import { Icon } from "../icon"; -const TabsContext = React.createContext({}); +const TabsContext = React.createContext>({}); -interface TabsContextValue { +interface TabsContextValue { autoFocus?: boolean; withBorder?: boolean; value?: D; onChange?(value: D): void; } -export interface TabsProps extends TabsContextValue, Omit, "onChange"> { +export interface TabsProps extends TabsContextValue, Omit, "onChange"> { className?: string; center?: boolean; wrap?: boolean; scrollable?: boolean; } -export class Tabs extends React.PureComponent { +export class Tabs extends React.PureComponent> { public elem: HTMLDivElement | null = null; render() { @@ -49,22 +49,22 @@ export class Tabs extends React.PureComponent { } } -export interface TabProps extends DOMAttributes { +export interface TabProps extends DOMAttributes { id?: string; className?: string; active?: boolean; disabled?: boolean; icon?: React.ReactNode | string; // material-ui name or custom icon label?: React.ReactNode; - value?: D; + value: D; } -export class Tab extends React.PureComponent { +export class Tab extends React.PureComponent> { static contextType = TabsContext; - declare context: TabsContextValue; + declare context: TabsContextValue; public ref = React.createRef(); - constructor(props: TabProps) { + constructor(props: TabProps) { super(props); autoBind(this); } diff --git a/src/renderer/initializers/entity-settings-registry.ts b/src/renderer/initializers/entity-settings-registry.ts deleted file mode 100644 index 867368fafa..0000000000 --- a/src/renderer/initializers/entity-settings-registry.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import { EntitySettingRegistry } from "../../extensions/registries"; -import * as clusterSettings from "../components/cluster-settings"; - -export function initEntitySettingsRegistry() { - EntitySettingRegistry.getInstance() - .add([ - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - source: "local", - title: "General", - group: "Settings", - components: { - View: clusterSettings.GeneralSettings, - }, - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Proxy", - group: "Settings", - components: { - View: clusterSettings.ProxySettings, - }, - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Terminal", - group: "Settings", - components: { - View: clusterSettings.TerminalSettings, - }, - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Namespaces", - group: "Settings", - components: { - View: clusterSettings.NamespacesSettings, - }, - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Metrics", - group: "Settings", - components: { - View: clusterSettings.MetricsSettings, - }, - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Node Shell", - group: "Settings", - components: { - View: clusterSettings.NodeShellSettings, - }, - }, - ]); -} diff --git a/src/renderer/initializers/index.ts b/src/renderer/initializers/index.ts index 7653a6147a..6fb131e507 100644 --- a/src/renderer/initializers/index.ts +++ b/src/renderer/initializers/index.ts @@ -5,7 +5,6 @@ export * from "./catalog-entity-detail-registry"; export * from "./catalog"; -export * from "./entity-settings-registry"; export * from "./ipc"; export * from "./registries"; export * from "./catalog-category-registry"; diff --git a/src/renderer/initializers/registries.ts b/src/renderer/initializers/registries.ts index 5db6be77f2..6d9b7a075e 100644 --- a/src/renderer/initializers/registries.ts +++ b/src/renderer/initializers/registries.ts @@ -7,5 +7,4 @@ import * as registries from "../../extensions/registries"; export function initRegistries() { registries.CatalogEntityDetailRegistry.createInstance(); - registries.EntitySettingRegistry.createInstance(); } diff --git a/tsconfig.json b/tsconfig.json index b97369efc7..df6db147c3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "noImplicitAny": true, "noUnusedLocals": true, "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "isolatedModules": true,