mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Make EntitySettingRegistry fully injectable
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
8897bfc26b
commit
e4e0c30da2
42 files changed
+725
-457
No files matched your search
@@ -19,3 +19,7 @@ export const orderByOrderNumber = <T extends MaybeOrderable>(maybeOrderables: T[
|
||||
: Number.MAX_SAFE_INTEGER,
|
||||
maybeOrderables,
|
||||
);
|
||||
|
||||
export const byOrderNumber = <T extends Orderable>(left: T, right: T) => (
|
||||
left.orderNumber - right.orderNumber
|
||||
);
|
||||
@@ -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),
|
||||
];
|
||||
|
||||
|
||||
@@ -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<LensRendererExtensionDependencies> {
|
||||
globalPages: registries.PageRegistration[] = [];
|
||||
@@ -38,7 +39,7 @@ export class LensRendererExtension extends LensExtension<LensRendererExtensionDe
|
||||
kubeObjectStatusTexts: KubeObjectStatusRegistration[] = [];
|
||||
appPreferences: AppPreferenceRegistration[] = [];
|
||||
appPreferenceTabs: AppPreferenceTabRegistration[] = [];
|
||||
entitySettings: registries.EntitySettingRegistration[] = [];
|
||||
entitySettings: EntitySettingRegistration[] = [];
|
||||
statusBarItems: StatusBarRegistration[] = [];
|
||||
kubeObjectDetailItems: KubeObjectDetailRegistration[] = [];
|
||||
kubeObjectMenuItems: KubeObjectMenuRegistration[] = [];
|
||||
|
||||
@@ -1,54 +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 type { CatalogEntity } from "../../common/catalog";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
|
||||
export interface EntitySettingViewProps {
|
||||
entity: CatalogEntity;
|
||||
}
|
||||
|
||||
export interface EntitySettingComponents {
|
||||
View: React.ComponentType<EntitySettingViewProps>;
|
||||
}
|
||||
|
||||
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<EntitySettingRegistration, RegisteredEntitySetting> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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<string>;
|
||||
entityRegistry: CatalogEntityRegistry;
|
||||
observableHistory: ObservableHistory<unknown>;
|
||||
entity: IComputedValue<CatalogEntity | undefined>;
|
||||
}
|
||||
|
||||
@observer
|
||||
class NonInjectedEntitySettings extends React.Component<Dependencies> {
|
||||
@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 <CatalogEntitySettings entity={entity} />;
|
||||
});
|
||||
|
||||
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 (
|
||||
<>
|
||||
<div className={styles.avatarAndName}>
|
||||
<Avatar
|
||||
title={entity.getName()}
|
||||
colorHash={`${entity.getName()}-${entity.metadata.source}`}
|
||||
src={entity.spec.icon?.src}
|
||||
className={styles.settingsAvatar}
|
||||
size={40}
|
||||
/>
|
||||
<div className={styles.entityName}>
|
||||
{entity.getName()}
|
||||
</div>
|
||||
</div>
|
||||
<Tabs
|
||||
className="flex column"
|
||||
scrollable={false}
|
||||
onChange={this.onTabChange}
|
||||
value={this.activeTab}
|
||||
>
|
||||
{ groups.map((group, groupIndex) => (
|
||||
<React.Fragment key={`group-${groupIndex}`}>
|
||||
<hr/>
|
||||
<div className="header">{group[0]}</div>
|
||||
{ group[1].map((setting, index) => (
|
||||
<Tab
|
||||
key={index}
|
||||
value={setting.id}
|
||||
label={setting.title}
|
||||
data-testid={`${setting.id}-tab`}
|
||||
/>
|
||||
))}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { activeSetting, entity } = this;
|
||||
|
||||
if (!entity) {
|
||||
logger.error("[ENTITY-SETTINGS]: entity not found", this.entityId);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingLayout
|
||||
navigation={this.renderNavigation(entity)}
|
||||
contentGaps={false}
|
||||
>
|
||||
{
|
||||
activeSetting && (
|
||||
<section>
|
||||
<h2 data-testid={`${activeSetting.id}-header`}>{activeSetting.title}</h2>
|
||||
<section>
|
||||
<activeSetting.components.View entity={entity} key={activeSetting.title} />
|
||||
</section>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</SettingLayout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const EntitySettings = withInjectables<Dependencies>(NonInjectedEntitySettings, {
|
||||
export const EntitySettingsRouteComponent = withInjectables<Dependencies>(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 = () => (
|
||||
<>
|
||||
<div className={styles.avatarAndName}>
|
||||
<Avatar
|
||||
title={entity.getName()}
|
||||
colorHash={`${entity.getName()}-${entity.metadata.source}`}
|
||||
src={entity.spec.icon?.src}
|
||||
className={styles.settingsAvatar}
|
||||
size={40}
|
||||
/>
|
||||
<div className={styles.entityName}>
|
||||
{entity.getName()}
|
||||
</div>
|
||||
</div>
|
||||
<Tabs
|
||||
className="flex column"
|
||||
scrollable={ false }
|
||||
onChange={activeEntitySettingsTab.set}
|
||||
value={tabId}
|
||||
>
|
||||
{
|
||||
groups.map(({ tabs, title }) => (
|
||||
<React.Fragment key={title}>
|
||||
<hr />
|
||||
<div className="header">{title}</div>
|
||||
{
|
||||
tabs.map((setting) => (
|
||||
<Tab
|
||||
key={setting.id}
|
||||
value={setting.id}
|
||||
label={setting.title}
|
||||
data-testid={`${setting.id}-tab`}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</React.Fragment>
|
||||
))
|
||||
}
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<SettingLayout
|
||||
navigation={renderNavigation()}
|
||||
contentGaps={false}
|
||||
>
|
||||
{
|
||||
(tabId && setting) && (
|
||||
<section>
|
||||
<h2 data-testid={`${tabId}-header`}>{setting.title}</h2>
|
||||
<section>
|
||||
<setting.components.View entity={entity} />
|
||||
</section>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</SettingLayout>
|
||||
);
|
||||
});
|
||||
|
||||
const CatalogEntitySettings = withInjectables<CatalogEntitySettingsDeps, CatalogEntitySettingsProps>(NonInjectedCatalogEntitySettings, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
activeEntitySettingsTab: di.inject(activeEntitySettingsTabInjectable, props.entity),
|
||||
}),
|
||||
});
|
||||
@@ -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<EntitySettingViewProps>;
|
||||
}
|
||||
|
||||
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<string>;
|
||||
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,
|
||||
});
|
||||
@@ -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;
|
||||
+71
@@ -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 (
|
||||
<section>
|
||||
<section>
|
||||
<div className="flex">
|
||||
<div className="flex-grow pr-8">
|
||||
<ClusterNameSetting cluster={cluster} entity={entity as KubernetesCluster} />
|
||||
</div>
|
||||
<div>
|
||||
<ClusterIconSetting cluster={cluster} entity={entity as KubernetesCluster} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="small">
|
||||
<ClusterKubeconfig cluster={cluster} />
|
||||
</section>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const GeneralKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+64
@@ -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 (
|
||||
<section>
|
||||
<section>
|
||||
<ClusterPrometheusSetting cluster={cluster} />
|
||||
</section>
|
||||
<hr/>
|
||||
<section>
|
||||
<ClusterMetricsSetting cluster={cluster} />
|
||||
<ShowMetricsSetting cluster={cluster} />
|
||||
</section>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const MetricsKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+55
@@ -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 (
|
||||
<section>
|
||||
<ClusterAccessibleNamespaces cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const NamespaceKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+55
@@ -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 (
|
||||
<section>
|
||||
<ClusterNodeShellSetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const NodeShellKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+55
@@ -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 (
|
||||
<section>
|
||||
<ClusterProxySetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const ProxyKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+55
@@ -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 (
|
||||
<section>
|
||||
<ClusterLocalTerminalSetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const TerminalKubernetesClusterSettings = withInjectables<Dependencies, EntitySettingViewProps>(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;
|
||||
+2
-2
@@ -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,
|
||||
File renamed without changes.
@@ -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;
|
||||
@@ -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<RegisteredEntitySetting>({
|
||||
id: "entity-setting",
|
||||
});
|
||||
+7
-7
@@ -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;
|
||||
+4
-4
@@ -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;
|
||||
@@ -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 (
|
||||
<section>
|
||||
<section>
|
||||
<div className="flex">
|
||||
<div className="flex-grow pr-8">
|
||||
<components.ClusterNameSetting cluster={cluster} entity={entity as KubernetesCluster} />
|
||||
</div>
|
||||
<div>
|
||||
<components.ClusterIconSetting cluster={cluster} entity={entity as KubernetesCluster} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="small">
|
||||
<components.ClusterKubeconfig cluster={cluster} />
|
||||
</section>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function ProxySettings({ entity }: EntitySettingViewProps) {
|
||||
const cluster = getClusterForEntity(entity);
|
||||
|
||||
if (!cluster) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<components.ClusterProxySetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function TerminalSettings({ entity }: EntitySettingViewProps) {
|
||||
const cluster = getClusterForEntity(entity);
|
||||
|
||||
if (!cluster) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<components.ClusterLocalTerminalSetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function NamespacesSettings({ entity }: EntitySettingViewProps) {
|
||||
const cluster = getClusterForEntity(entity);
|
||||
|
||||
if (!cluster) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<components.ClusterAccessibleNamespaces cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function MetricsSettings({ entity }: EntitySettingViewProps) {
|
||||
const cluster = getClusterForEntity(entity);
|
||||
|
||||
if (!cluster) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<section>
|
||||
<components.ClusterPrometheusSetting cluster={cluster} />
|
||||
</section>
|
||||
<hr/>
|
||||
<section>
|
||||
<components.ClusterMetricsSetting cluster={cluster} />
|
||||
<components.ShowMetricsSetting cluster={cluster} />
|
||||
</section>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function NodeShellSettings({ entity }: EntitySettingViewProps) {
|
||||
const cluster = getClusterForEntity(entity);
|
||||
|
||||
if(!cluster) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<components.ClusterNodeShellSetting cluster={cluster} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -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";
|
||||
File renamed without changes.
@@ -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";
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-21
@@ -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;
|
||||
+5
-7
@@ -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),
|
||||
|
||||
@@ -9,23 +9,23 @@ import React from "react";
|
||||
import { autoBind, cssNames } from "../../utils";
|
||||
import { Icon } from "../icon";
|
||||
|
||||
const TabsContext = React.createContext<TabsContextValue>({});
|
||||
const TabsContext = React.createContext<TabsContextValue<unknown>>({});
|
||||
|
||||
interface TabsContextValue<D = any> {
|
||||
interface TabsContextValue<D> {
|
||||
autoFocus?: boolean;
|
||||
withBorder?: boolean;
|
||||
value?: D;
|
||||
onChange?(value: D): void;
|
||||
}
|
||||
|
||||
export interface TabsProps<D = any> extends TabsContextValue<D>, Omit<DOMAttributes<HTMLElement>, "onChange"> {
|
||||
export interface TabsProps<D> extends TabsContextValue<D>, Omit<DOMAttributes<HTMLElement>, "onChange"> {
|
||||
className?: string;
|
||||
center?: boolean;
|
||||
wrap?: boolean;
|
||||
scrollable?: boolean;
|
||||
}
|
||||
|
||||
export class Tabs extends React.PureComponent<TabsProps> {
|
||||
export class Tabs<D> extends React.PureComponent<TabsProps<D>> {
|
||||
public elem: HTMLDivElement | null = null;
|
||||
|
||||
render() {
|
||||
@@ -49,22 +49,22 @@ export class Tabs extends React.PureComponent<TabsProps> {
|
||||
}
|
||||
}
|
||||
|
||||
export interface TabProps<D = any> extends DOMAttributes<HTMLElement> {
|
||||
export interface TabProps<D> extends DOMAttributes<HTMLElement> {
|
||||
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<TabProps> {
|
||||
export class Tab<D> extends React.PureComponent<TabProps<D>> {
|
||||
static contextType = TabsContext;
|
||||
declare context: TabsContextValue;
|
||||
declare context: TabsContextValue<D>;
|
||||
public ref = React.createRef<HTMLDivElement>();
|
||||
|
||||
constructor(props: TabProps) {
|
||||
constructor(props: TabProps<D>) {
|
||||
super(props);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -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";
|
||||
@@ -7,5 +7,4 @@ import * as registries from "../../extensions/registries";
|
||||
|
||||
export function initRegistries() {
|
||||
registries.CatalogEntityDetailRegistry.createInstance();
|
||||
registries.EntitySettingRegistry.createInstance();
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"isolatedModules": true,
|
||||
|
||||
Reference in new issue
Block a user