diff --git a/src/common/protocol-handler/router.ts b/src/common/protocol-handler/router.ts index ee0d4b3799..7967d0bda3 100644 --- a/src/common/protocol-handler/router.ts +++ b/src/common/protocol-handler/router.ts @@ -29,7 +29,7 @@ import { RoutingError, RoutingErrorType } from "./error"; import { ExtensionsStore } from "../../extensions/extensions-store"; import { ExtensionLoader } from "../../extensions/extension-loader"; import type { LensExtension } from "../../extensions/lens-extension"; -import type { RouteHandler, RouteParams } from "../../extensions/registries/protocol-handler-registry"; +import type { RouteHandler, RouteParams } from "../../extensions/registries/protocol-handler"; // IPC channel for protocol actions. Main broadcasts the open-url events to this channel. export const ProtocolHandlerIpcPrefix = "protocol-handler"; diff --git a/src/extensions/common-api/registrations.ts b/src/extensions/common-api/registrations.ts index e2e8d1ed11..dadde70ceb 100644 --- a/src/extensions/common-api/registrations.ts +++ b/src/extensions/common-api/registrations.ts @@ -26,4 +26,4 @@ export type { KubeObjectStatusRegistration } from "../registries/kube-object-sta export type { PageRegistration, RegisteredPage, PageParams, PageComponentProps, PageComponents, PageTarget } from "../registries/page-registry"; export type { PageMenuRegistration, ClusterPageMenuRegistration, PageMenuComponents } from "../registries/page-menu-registry"; export type { StatusBarRegistration } from "../registries/status-bar-registry"; -export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler-registry"; +export type { ProtocolHandlerRegistration, RouteParams as ProtocolRouteParams, RouteHandler as ProtocolRouteHandler } from "../registries/protocol-handler"; diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index af85d11e7f..20830630fb 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -221,11 +221,13 @@ export class ExtensionLoader extends Singleton { } loadOnMain() { + registries.MenuRegistry.createInstance(); + logger.debug(`${logModule}: load on main`); this.autoInitExtensions(async (extension: LensMainExtension) => { // Each .add returns a function to remove the item const removeItems = [ - registries.menuRegistry.add(extension.appMenus) + registries.MenuRegistry.getInstance().add(extension.appMenus) ]; this.events.on("remove", (removedExtension: LensRendererExtension) => { @@ -244,13 +246,13 @@ export class ExtensionLoader extends Singleton { logger.debug(`${logModule}: load on main renderer (cluster manager)`); this.autoInitExtensions(async (extension: LensRendererExtension) => { const removeItems = [ - registries.globalPageRegistry.add(extension.globalPages, extension), - registries.appPreferenceRegistry.add(extension.appPreferences), - registries.entitySettingRegistry.add(extension.entitySettings), - registries.statusBarRegistry.add(extension.statusBarItems), - registries.commandRegistry.add(extension.commands), - registries.welcomeMenuRegistry.add(extension.welcomeMenus), - registries.catalogEntityDetailRegistry.add(extension.catalogEntityDetailItems), + registries.GlobalPageRegistry.getInstance().add(extension.globalPages, extension), + registries.AppPreferenceRegistry.getInstance().add(extension.appPreferences), + registries.EntitySettingRegistry.getInstance().add(extension.entitySettings), + registries.StatusBarRegistry.getInstance().add(extension.statusBarItems), + registries.CommandRegistry.getInstance().add(extension.commands), + registries.WelcomeMenuRegistry.getInstance().add(extension.welcomeMenus), + registries.CatalogEntityDetailRegistry.getInstance().add(extension.catalogEntityDetailItems), ]; this.events.on("remove", (removedExtension: LensRendererExtension) => { @@ -275,13 +277,13 @@ export class ExtensionLoader extends Singleton { } const removeItems = [ - registries.clusterPageRegistry.add(extension.clusterPages, extension), - registries.clusterPageMenuRegistry.add(extension.clusterPageMenus, extension), - registries.kubeObjectMenuRegistry.add(extension.kubeObjectMenuItems), - registries.kubeObjectDetailRegistry.add(extension.kubeObjectDetailItems), - registries.kubeObjectStatusRegistry.add(extension.kubeObjectStatusTexts), - registries.workloadsOverviewDetailRegistry.add(extension.kubeWorkloadsOverviewItems), - registries.commandRegistry.add(extension.commands), + registries.ClusterPageRegistry.getInstance().add(extension.clusterPages, extension), + registries.ClusterPageMenuRegistry.getInstance().add(extension.clusterPageMenus, extension), + registries.KubeObjectMenuRegistry.getInstance().add(extension.kubeObjectMenuItems), + registries.KubeObjectDetailRegistry.getInstance().add(extension.kubeObjectDetailItems), + registries.KubeObjectStatusRegistry.getInstance().add(extension.kubeObjectStatusTexts), + registries.WorkloadsOverviewDetailRegistry.getInstance().add(extension.kubeWorkloadsOverviewItems), + registries.CommandRegistry.getInstance().add(extension.commands), ]; this.events.on("remove", (removedExtension: LensRendererExtension) => { diff --git a/src/extensions/registries/__tests__/page-registry.test.ts b/src/extensions/registries/__tests__/page-registry.test.ts index 497d92e723..ed9bf983cd 100644 --- a/src/extensions/registries/__tests__/page-registry.test.ts +++ b/src/extensions/registries/__tests__/page-registry.test.ts @@ -19,7 +19,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { getExtensionPageUrl, globalPageRegistry, PageParams } from "../page-registry"; +import { ClusterPageRegistry, getExtensionPageUrl, GlobalPageRegistry, PageParams } from "../page-registry"; import { LensExtension } from "../../lens-extension"; import React from "react"; import { Console } from "console"; @@ -43,7 +43,8 @@ describe("getPageUrl", () => { isEnabled: true, isCompatible: true }); - globalPageRegistry.add({ + ClusterPageRegistry.createInstance(); + GlobalPageRegistry.createInstance().add({ id: "page-with-params", components: { Page: () => React.createElement("Page with params") @@ -55,6 +56,11 @@ describe("getPageUrl", () => { }, ext); }); + afterEach(() => { + GlobalPageRegistry.resetInstance(); + ClusterPageRegistry.resetInstance(); + }); + it("returns a page url for extension", () => { expect(getExtensionPageUrl({ extensionId: ext.name })).toBe("/extension/foo-bar"); }); @@ -111,7 +117,8 @@ describe("globalPageRegistry", () => { isEnabled: true, isCompatible: true }); - globalPageRegistry.add([ + ClusterPageRegistry.createInstance(); + GlobalPageRegistry.createInstance().add([ { id: "test-page", components: { @@ -132,9 +139,14 @@ describe("globalPageRegistry", () => { ], ext); }); + afterEach(() => { + GlobalPageRegistry.resetInstance(); + ClusterPageRegistry.resetInstance(); + }); + describe("getByPageTarget", () => { it("matching to first registered page without id", () => { - const page = globalPageRegistry.getByPageTarget({ extensionId: ext.name }); + const page = GlobalPageRegistry.getInstance().getByPageTarget({ extensionId: ext.name }); expect(page.id).toEqual(undefined); expect(page.extensionId).toEqual(ext.name); @@ -142,7 +154,7 @@ describe("globalPageRegistry", () => { }); it("returns matching page", () => { - const page = globalPageRegistry.getByPageTarget({ + const page = GlobalPageRegistry.getInstance().getByPageTarget({ pageId: "test-page", extensionId: ext.name }); @@ -151,7 +163,7 @@ describe("globalPageRegistry", () => { }); it("returns null if target not found", () => { - const page = globalPageRegistry.getByPageTarget({ + const page = GlobalPageRegistry.getInstance().getByPageTarget({ pageId: "wrong-page", extensionId: ext.name }); diff --git a/src/extensions/registries/app-preference-registry.ts b/src/extensions/registries/app-preference-registry.ts index 4df13edc63..fb20034d52 100644 --- a/src/extensions/registries/app-preference-registry.ts +++ b/src/extensions/registries/app-preference-registry.ts @@ -46,5 +46,3 @@ export class AppPreferenceRegistry extends BaseRegistry { +export class BaseRegistry extends Singleton { private items = observable.map([], {deep: false}); constructor() { + super(); makeObservable(this); } diff --git a/src/extensions/registries/catalog-entity-detail-registry.ts b/src/extensions/registries/catalog-entity-detail-registry.ts index 0ed00b7a8b..b4b9fb0dd2 100644 --- a/src/extensions/registries/catalog-entity-detail-registry.ts +++ b/src/extensions/registries/catalog-entity-detail-registry.ts @@ -42,5 +42,3 @@ export class CatalogEntityDetailRegistry extends BaseRegistry (b.priority ?? 50) - (a.priority ?? 50)); } } - -export const catalogEntityDetailRegistry = new CatalogEntityDetailRegistry(); diff --git a/src/extensions/registries/command-registry.ts b/src/extensions/registries/command-registry.ts index 8f91dace10..5c38e32c71 100644 --- a/src/extensions/registries/command-registry.ts +++ b/src/extensions/registries/command-registry.ts @@ -50,5 +50,3 @@ export class CommandRegistry extends BaseRegistry { return super.add(filteredItems, extension); } } - -export const commandRegistry = new CommandRegistry(); diff --git a/src/extensions/registries/entity-setting-registry.ts b/src/extensions/registries/entity-setting-registry.ts index 80b20196c3..54d85ef57f 100644 --- a/src/extensions/registries/entity-setting-registry.ts +++ b/src/extensions/registries/entity-setting-registry.ts @@ -68,5 +68,3 @@ export class EntitySettingRegistry extends BaseRegistry (b.priority ?? 50) - (a.priority ?? 50)); } } - -export const entitySettingRegistry = new EntitySettingRegistry(); diff --git a/src/extensions/registries/index.ts b/src/extensions/registries/index.ts index b9ba986521..1f65d8f280 100644 --- a/src/extensions/registries/index.ts +++ b/src/extensions/registries/index.ts @@ -32,6 +32,6 @@ export * from "./kube-object-status-registry"; export * from "./command-registry"; export * from "./entity-setting-registry"; export * from "./welcome-menu-registry"; -export * from "./protocol-handler-registry"; export * from "./catalog-entity-detail-registry"; export * from "./workloads-overview-detail-registry"; +export * from "./protocol-handler"; diff --git a/src/extensions/registries/kube-object-detail-registry.ts b/src/extensions/registries/kube-object-detail-registry.ts index 7cc17bbc7e..844f5fc0ee 100644 --- a/src/extensions/registries/kube-object-detail-registry.ts +++ b/src/extensions/registries/kube-object-detail-registry.ts @@ -20,10 +20,12 @@ */ import type React from "react"; +import type { KubeObjectDetailsProps } from "../renderer-api/components"; +import type { KubeObject } from "../renderer-api/k8s-api"; import { BaseRegistry } from "./base-registry"; export interface KubeObjectDetailComponents { - Details: React.ComponentType; + Details: React.ComponentType>; } export interface KubeObjectDetailRegistration { @@ -42,5 +44,3 @@ export class KubeObjectDetailRegistry extends BaseRegistry (b.priority ?? 50) - (a.priority ?? 50)); } } - -export const kubeObjectDetailRegistry = new KubeObjectDetailRegistry(); diff --git a/src/extensions/registries/kube-object-menu-registry.ts b/src/extensions/registries/kube-object-menu-registry.ts index 414d55db59..fbbc872d2b 100644 --- a/src/extensions/registries/kube-object-menu-registry.ts +++ b/src/extensions/registries/kube-object-menu-registry.ts @@ -39,5 +39,3 @@ export class KubeObjectMenuRegistry extends BaseRegistry { } - -export const menuRegistry = new MenuRegistry(); diff --git a/src/extensions/registries/page-menu-registry.ts b/src/extensions/registries/page-menu-registry.ts index 49003717f6..73997fb461 100644 --- a/src/extensions/registries/page-menu-registry.ts +++ b/src/extensions/registries/page-menu-registry.ts @@ -75,5 +75,3 @@ export class ClusterPageMenuRegistry extends PageMenuRegistry { @@ -91,7 +91,7 @@ export function getExtensionPageUrl(target: PageTarget): string { return pageUrl.href.replace(pageUrl.origin, ""); } -export class PageRegistry extends BaseRegistry { +class PageRegistry extends BaseRegistry { protected getRegisteredItem(page: PageRegistration, ext: LensExtension): RegisteredPage { const { id: pageId } = page; const extensionId = ext.name; @@ -157,5 +157,5 @@ export class PageRegistry extends BaseRegistry } } -export const globalPageRegistry = new PageRegistry(); -export const clusterPageRegistry = new PageRegistry(); +export class ClusterPageRegistry extends PageRegistry {} +export class GlobalPageRegistry extends PageRegistry {} diff --git a/src/extensions/registries/protocol-handler-registry.ts b/src/extensions/registries/protocol-handler.ts similarity index 100% rename from src/extensions/registries/protocol-handler-registry.ts rename to src/extensions/registries/protocol-handler.ts diff --git a/src/extensions/registries/status-bar-registry.ts b/src/extensions/registries/status-bar-registry.ts index 0814f9cc7a..2afdee76a6 100644 --- a/src/extensions/registries/status-bar-registry.ts +++ b/src/extensions/registries/status-bar-registry.ts @@ -41,5 +41,3 @@ export interface StatusBarRegistration extends StatusBarRegistrationV2 { export class StatusBarRegistry extends BaseRegistry { } - -export const statusBarRegistry = new StatusBarRegistry(); diff --git a/src/extensions/registries/welcome-menu-registry.ts b/src/extensions/registries/welcome-menu-registry.ts index 077f1d3aea..7092028459 100644 --- a/src/extensions/registries/welcome-menu-registry.ts +++ b/src/extensions/registries/welcome-menu-registry.ts @@ -28,5 +28,3 @@ export interface WelcomeMenuRegistration { } export class WelcomeMenuRegistry extends BaseRegistry {} - -export const welcomeMenuRegistry = new WelcomeMenuRegistry(); diff --git a/src/extensions/registries/workloads-overview-detail-registry.ts b/src/extensions/registries/workloads-overview-detail-registry.ts index 8ad2a10e19..b148a21f7c 100644 --- a/src/extensions/registries/workloads-overview-detail-registry.ts +++ b/src/extensions/registries/workloads-overview-detail-registry.ts @@ -38,5 +38,3 @@ export class WorkloadsOverviewDetailRegistry extends BaseRegistry (b.priority ?? 50) - (a.priority ?? 50)); } } - -export const workloadsOverviewDetailRegistry = new WorkloadsOverviewDetailRegistry(); diff --git a/src/main/index.ts b/src/main/index.ts index 3abbfecd17..9a628a3bab 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -56,7 +56,8 @@ import { HelmRepoManager } from "./helm/helm-repo-manager"; import { KubeconfigSyncManager } from "./catalog-sources"; import { handleWsUpgrade } from "./proxy/ws-upgrade"; import configurePackages from "../common/configure-packages"; -import { PrometheusProviderRegistry, registerDefaultPrometheusProviders } from "./prometheus"; +import { PrometheusProviderRegistry } from "./prometheus"; +import { initRegistries, initPrometheusProviderRegistry } from "./initializers"; const workingDir = path.join(app.getPath("appData"), appName); const cleanup = disposer(); @@ -124,7 +125,7 @@ app.on("ready", async () => { registerFileProtocol("static", __static); PrometheusProviderRegistry.createInstance(); - registerDefaultPrometheusProviders(); + initPrometheusProviderRegistry(); const userStore = UserStore.createInstance(); const clusterStore = ClusterStore.createInstance(); @@ -173,6 +174,7 @@ app.on("ready", async () => { app.exit(); } + initRegistries(); const extensionDiscovery = ExtensionDiscovery.createInstance(); ExtensionLoader.createInstance().init(); diff --git a/src/renderer/components/+apps/apps.command.ts b/src/main/initializers/index.ts similarity index 68% rename from src/renderer/components/+apps/apps.command.ts rename to src/main/initializers/index.ts index eca0529bc4..a0835ab834 100644 --- a/src/renderer/components/+apps/apps.command.ts +++ b/src/main/initializers/index.ts @@ -19,20 +19,5 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import { helmChartsURL, releaseURL } from "../../../common/routes"; - -commandRegistry.add({ - id: "cluster.viewHelmCharts", - title: "Cluster: View Helm Charts", - scope: "entity", - action: () => navigate(helmChartsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewHelmReleases", - title: "Cluster: View Helm Releases", - scope: "entity", - action: () => navigate(releaseURL()) -}); +export * from "./registries"; +export * from "./metrics-providers"; diff --git a/src/renderer/components/+network/network.command.ts b/src/main/initializers/metrics-providers.ts similarity index 57% rename from src/renderer/components/+network/network.command.ts rename to src/main/initializers/metrics-providers.ts index 4171348a1b..3d952f1859 100644 --- a/src/renderer/components/+network/network.command.ts +++ b/src/main/initializers/metrics-providers.ts @@ -19,34 +19,17 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import * as routes from "../../../common/routes"; +import { PrometheusProviderRegistry } from "../prometheus"; +import { PrometheusHelm } from "../prometheus/helm"; +import { PrometheusLens } from "../prometheus/lens"; +import { PrometheusOperator } from "../prometheus/operator"; +import { PrometheusStacklight } from "../prometheus/stacklight"; -commandRegistry.add({ - id: "cluster.viewServices", - title: "Cluster: View Services", - scope: "entity", - action: () => navigate(routes.servicesURL()) -}); - -commandRegistry.add({ - id: "cluster.viewEndpoints", - title: "Cluster: View Endpoints", - scope: "entity", - action: () => navigate(routes.endpointURL()) -}); - -commandRegistry.add({ - id: "cluster.viewIngresses", - title: "Cluster: View Ingresses", - scope: "entity", - action: () => navigate(routes.ingressURL()) -}); - -commandRegistry.add({ - id: "cluster.viewNetworkPolicies", - title: "Cluster: View NetworkPolicies", - scope: "entity", - action: () => navigate(routes.networkPoliciesURL()) -}); +export function initPrometheusProviderRegistry() { + PrometheusProviderRegistry + .getInstance() + .registerProvider(new PrometheusLens()) + .registerProvider(new PrometheusHelm()) + .registerProvider(new PrometheusOperator()) + .registerProvider(new PrometheusStacklight()); +} diff --git a/src/renderer/components/+nodes/node.command.ts b/src/main/initializers/registries.ts similarity index 77% rename from src/renderer/components/+nodes/node.command.ts rename to src/main/initializers/registries.ts index 314381b5a4..28fcdff1a1 100644 --- a/src/renderer/components/+nodes/node.command.ts +++ b/src/main/initializers/registries.ts @@ -19,13 +19,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import { nodesURL } from "../../../common/routes"; +import * as registries from "../../extensions/registries"; -commandRegistry.add({ - id: "cluster.viewNodes", - title: "Cluster: View Nodes", - scope: "entity", - action: () => navigate(nodesURL()) -}); +export function initRegistries() { + registries.MenuRegistry.createInstance(); +} diff --git a/src/main/menu.ts b/src/main/menu.ts index 7d80ce162e..5b60541baa 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -23,7 +23,7 @@ import { app, BrowserWindow, dialog, ipcMain, IpcMainEvent, Menu, MenuItem, Menu import { autorun } from "mobx"; import type { WindowManager } from "./window-manager"; import { appName, isMac, isWindows, isTestEnv, docsUrl, supportUrl, productName } from "../common/vars"; -import { menuRegistry } from "../extensions/registries/menu-registry"; +import { MenuRegistry } from "../extensions/registries/menu-registry"; import logger from "./logger"; import { exitApp } from "./exit-app"; import { broadcastMessage } from "../common/ipc"; @@ -255,7 +255,7 @@ export function buildMenu(windowManager: WindowManager) { }; // Modify menu from extensions-api - menuRegistry.getItems().forEach(({ parentId, ...menuItem }) => { + MenuRegistry.getInstance().getItems().forEach(({ parentId, ...menuItem }) => { try { const topMenu = appMenu[parentId as MenuTopId].submenu as MenuItemConstructorOptions[]; diff --git a/src/main/prometheus/index.ts b/src/main/prometheus/index.ts index c24024d8b8..5fc029d625 100644 --- a/src/main/prometheus/index.ts +++ b/src/main/prometheus/index.ts @@ -19,19 +19,4 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { PrometheusHelm } from "./helm"; -import { PrometheusLens } from "./lens"; -import { PrometheusOperator } from "./operator"; -import { PrometheusProviderRegistry } from "./provider-registry"; -import { PrometheusStacklight } from "./stacklight"; - export * from "./provider-registry"; - -export function registerDefaultPrometheusProviders() { - PrometheusProviderRegistry - .getInstance() - .registerProvider(new PrometheusLens()) - .registerProvider(new PrometheusHelm()) - .registerProvider(new PrometheusOperator()) - .registerProvider(new PrometheusStacklight()); -} diff --git a/src/renderer/api/kube-object-detail-registry.ts b/src/renderer/api/kube-object-detail-registry.ts index 0afc7907da..1693fd56f1 100644 --- a/src/renderer/api/kube-object-detail-registry.ts +++ b/src/renderer/api/kube-object-detail-registry.ts @@ -19,4 +19,4 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -export { kubeObjectDetailRegistry } from "../../extensions/registries/kube-object-detail-registry"; +export { KubeObjectDetailRegistry } from "../../extensions/registries/kube-object-detail-registry"; diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index d7f3896a90..8c7fe38d4c 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -45,6 +45,7 @@ import { HelmRepoManager } from "../main/helm/helm-repo-manager"; import { ExtensionInstallationStateStore } from "./components/+extensions/extension-install.store"; import { DefaultProps } from "./mui-base-theme"; import configurePackages from "../common/configure-packages"; +import * as initializers from "./initializers"; configurePackages(); @@ -69,6 +70,14 @@ export async function bootstrap(App: AppComponent) { await attachChromeDebugger(); rootElem.classList.toggle("is-mac", isMac); + initializers.initRegistries(); + initializers.initCommandRegistry(); + initializers.initEntitySettingsRegistry(); + initializers.initKubeObjectMenuRegistry(); + initializers.intiKubeObjectDetailRegistry(); + initializers.initWelcomeMenuRegistry(); + initializers.initWorkloadsOverviewDetailRegistry(); + ExtensionLoader.createInstance().init(); ExtensionDiscovery.createInstance().init(); diff --git a/src/renderer/components/+apps/index.ts b/src/renderer/components/+apps/index.ts index f0fa78df03..4c8d6dfea0 100644 --- a/src/renderer/components/+apps/index.ts +++ b/src/renderer/components/+apps/index.ts @@ -20,4 +20,3 @@ */ export * from "./apps"; -export * from "./apps.command"; diff --git a/src/renderer/components/+catalog/catalog-entity-details.tsx b/src/renderer/components/+catalog/catalog-entity-details.tsx index 8837920de4..73a15c9f48 100644 --- a/src/renderer/components/+catalog/catalog-entity-details.tsx +++ b/src/renderer/components/+catalog/catalog-entity-details.tsx @@ -28,7 +28,7 @@ import type { CatalogCategory } from "../../../common/catalog"; import { Icon } from "../icon"; import { KubeObject } from "../../api/kube-object"; import { CatalogEntityDrawerMenu } from "./catalog-entity-drawer-menu"; -import { catalogEntityDetailRegistry } from "../../../extensions/registries"; +import { CatalogEntityDetailRegistry } from "../../../extensions/registries"; import { HotbarIcon } from "../hotbar/hotbar-icon"; interface Props { @@ -63,7 +63,7 @@ export class CatalogEntityDetails extends Component { renderContent() { const { entity } = this.props; const labels = KubeObject.stringifyLabels(entity.metadata.labels); - const detailItems = catalogEntityDetailRegistry.getItemsForKind(entity.kind, entity.apiVersion); + const detailItems = CatalogEntityDetailRegistry.getInstance().getItemsForKind(entity.kind, entity.apiVersion); const details = detailItems.map((item, index) => { return ; }); diff --git a/src/renderer/components/+config-autoscalers/hpa-details.tsx b/src/renderer/components/+config-autoscalers/hpa-details.tsx index 5b9cf76f97..1a6db54e78 100644 --- a/src/renderer/components/+config-autoscalers/hpa-details.tsx +++ b/src/renderer/components/+config-autoscalers/hpa-details.tsx @@ -29,11 +29,9 @@ import { Badge } from "../badge"; import { KubeObjectDetailsProps, getDetailsUrl } from "../kube-object"; import { cssNames } from "../../utils"; import { HorizontalPodAutoscaler, HpaMetricType, IHpaMetric } from "../../api/endpoints/hpa.api"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { lookupApiLink } from "../../api/kube-api"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -150,20 +148,3 @@ export class HpaDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "HorizontalPodAutoscaler", - apiVersions: ["autoscaling/v2beta1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "HorizontalPodAutoscaler", - apiVersions: ["autoscaling/v2beta1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config-limit-ranges/limit-range-details.tsx b/src/renderer/components/+config-limit-ranges/limit-range-details.tsx index d4c9d18f28..8531029313 100644 --- a/src/renderer/components/+config-limit-ranges/limit-range-details.tsx +++ b/src/renderer/components/+config-limit-ranges/limit-range-details.tsx @@ -25,7 +25,6 @@ import React from "react"; import { observer } from "mobx-react"; import type { KubeObjectDetailsProps } from "../kube-object"; import { LimitPart, LimitRange, LimitRangeItem, Resource } from "../../api/endpoints/limit-range.api"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { DrawerItem } from "../drawer/drawer-item"; import { Badge } from "../badge"; @@ -108,11 +107,3 @@ export class LimitRangeDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "LimitRange", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config-maps/config-map-details.tsx b/src/renderer/components/+config-maps/config-map-details.tsx index 928353ac6b..4858868186 100644 --- a/src/renderer/components/+config-maps/config-map-details.tsx +++ b/src/renderer/components/+config-maps/config-map-details.tsx @@ -28,12 +28,10 @@ import { DrawerTitle } from "../drawer"; import { Notifications } from "../notifications"; import { Input } from "../input"; import { Button } from "../button"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { configMapsStore } from "./config-maps.store"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { ConfigMap } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -123,20 +121,3 @@ export class ConfigMapDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ConfigMap", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "ConfigMap", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets-details.tsx b/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets-details.tsx index ddb95aa628..ad4bc41dc1 100644 --- a/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets-details.tsx +++ b/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets-details.tsx @@ -28,7 +28,6 @@ import { Badge } from "../badge"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { PodDisruptionBudget } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -74,11 +73,3 @@ export class PodDisruptionBudgetDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "PodDisruptionBudget", - apiVersions: ["policy/v1beta1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config-resource-quotas/resource-quota-details.tsx b/src/renderer/components/+config-resource-quotas/resource-quota-details.tsx index 662a8e26ec..cf7c505dcf 100644 --- a/src/renderer/components/+config-resource-quotas/resource-quota-details.tsx +++ b/src/renderer/components/+config-resource-quotas/resource-quota-details.tsx @@ -30,7 +30,6 @@ import type { ResourceQuota } from "../../api/endpoints/resource-quota.api"; import { LineProgress } from "../line-progress"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -117,11 +116,3 @@ export class ResourceQuotaDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ResourceQuota", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config-secrets/secret-details.tsx b/src/renderer/components/+config-secrets/secret-details.tsx index ae8fc17dee..672ba86203 100644 --- a/src/renderer/components/+config-secrets/secret-details.tsx +++ b/src/renderer/components/+config-secrets/secret-details.tsx @@ -35,7 +35,6 @@ import { secretsStore } from "./secrets.store"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { Secret } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -143,11 +142,3 @@ export class SecretDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Secret", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+config/config.command.ts b/src/renderer/components/+config/config.command.ts deleted file mode 100644 index 4e660fadea..0000000000 --- a/src/renderer/components/+config/config.command.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2021 OpenLens Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import * as routes from "../../../common/routes"; - -commandRegistry.add({ - id: "cluster.viewConfigMaps", - title: "Cluster: View ConfigMaps", - scope: "entity", - action: () => navigate(routes.configMapsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewSecrets", - title: "Cluster: View Secrets", - scope: "entity", - action: () => navigate(routes.secretsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewResourceQuotas", - title: "Cluster: View ResourceQuotas", - scope: "entity", - action: () => navigate(routes.resourceQuotaURL()) -}); - -commandRegistry.add({ - id: "cluster.viewLimitRanges", - title: "Cluster: View LimitRanges", - scope: "entity", - action: () => navigate(routes.limitRangeURL()) -}); - -commandRegistry.add({ - id: "cluster.viewHorizontalPodAutoscalers", - title: "Cluster: View HorizontalPodAutoscalers (HPA)", - scope: "entity", - action: () => navigate(routes.hpaURL()) -}); - -commandRegistry.add({ - id: "cluster.viewPodDisruptionBudget", - title: "Cluster: View PodDisruptionBudgets", - scope: "entity", - action: () => navigate(routes.pdbURL()) -}); diff --git a/src/renderer/components/+config/index.ts b/src/renderer/components/+config/index.ts index 0d30c3f64a..521bf1d3a1 100644 --- a/src/renderer/components/+config/index.ts +++ b/src/renderer/components/+config/index.ts @@ -20,4 +20,3 @@ */ export * from "./config"; -export * from "./config.command"; diff --git a/src/renderer/components/+custom-resources/crd-details.tsx b/src/renderer/components/+custom-resources/crd-details.tsx index cdffec10d8..146c299884 100644 --- a/src/renderer/components/+custom-resources/crd-details.tsx +++ b/src/renderer/components/+custom-resources/crd-details.tsx @@ -33,7 +33,6 @@ import type { KubeObjectDetailsProps } from "../kube-object"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { Input } from "../input"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -156,11 +155,3 @@ export class CRDDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "CustomResourceDefinition", - apiVersions: ["apiextensions.k8s.io/v1", "apiextensions.k8s.io/v1beta1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+entity-settings/entity-settings.tsx b/src/renderer/components/+entity-settings/entity-settings.tsx index 5216915d89..d37fdef953 100644 --- a/src/renderer/components/+entity-settings/entity-settings.tsx +++ b/src/renderer/components/+entity-settings/entity-settings.tsx @@ -30,7 +30,7 @@ import { navigation } from "../../navigation"; import { Tabs, Tab } from "../tabs"; import type { CatalogEntity } from "../../api/catalog-entity"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; -import { entitySettingRegistry } from "../../../extensions/registries"; +import { EntitySettingRegistry } from "../../../extensions/registries"; import type { EntitySettingsRouteParams } from "../../../common/routes"; import { groupBy } from "lodash"; @@ -57,7 +57,7 @@ export class EntitySettings extends React.Component { get menuItems() { if (!this.entity) return []; - return entitySettingRegistry.getItemsForKind(this.entity.kind, this.entity.apiVersion, this.entity.metadata.source); + return EntitySettingRegistry.getInstance().getItemsForKind(this.entity.kind, this.entity.apiVersion, this.entity.metadata.source); } async componentDidMount() { diff --git a/src/renderer/components/+events/event-details.tsx b/src/renderer/components/+events/event-details.tsx index ec50373964..639c4b9dcf 100644 --- a/src/renderer/components/+events/event-details.tsx +++ b/src/renderer/components/+events/event-details.tsx @@ -31,7 +31,6 @@ import type { KubeEvent } from "../../api/endpoints/events.api"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { lookupApiLink } from "../../api/kube-api"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { LocaleDate } from "../locale-date"; interface Props extends KubeObjectDetailsProps { @@ -95,11 +94,3 @@ export class EventDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Event", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+namespaces/namespace-details.tsx b/src/renderer/components/+namespaces/namespace-details.tsx index 76ccb5addb..95103f553b 100644 --- a/src/renderer/components/+namespaces/namespace-details.tsx +++ b/src/renderer/components/+namespaces/namespace-details.tsx @@ -32,7 +32,6 @@ import { Link } from "react-router-dom"; import { Spinner } from "../spinner"; import { resourceQuotaStore } from "../+config-resource-quotas/resource-quotas.store"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { limitRangeStore } from "../+config-limit-ranges/limit-ranges.store"; interface Props extends KubeObjectDetailsProps { @@ -100,11 +99,3 @@ export class NamespaceDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Namespace", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+network-endpoints/endpoint-details.tsx b/src/renderer/components/+network-endpoints/endpoint-details.tsx index d8cc20f529..8554a4b2f7 100644 --- a/src/renderer/components/+network-endpoints/endpoint-details.tsx +++ b/src/renderer/components/+network-endpoints/endpoint-details.tsx @@ -24,12 +24,10 @@ import "./endpoint-details.scss"; import React from "react"; import { observer } from "mobx-react"; import { DrawerTitle } from "../drawer"; -import { KubeEventDetails } from "../+events/kube-event-details"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { Endpoint } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { EndpointSubsetList } from "./endpoint-subset-list"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -54,19 +52,3 @@ export class EndpointDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Endpoints", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "Endpoints", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+network-ingresses/ingress-details.tsx b/src/renderer/components/+network-ingresses/ingress-details.tsx index a615da27e3..8e3c836b34 100644 --- a/src/renderer/components/+network-ingresses/ingress-details.tsx +++ b/src/renderer/components/+network-ingresses/ingress-details.tsx @@ -27,13 +27,11 @@ import { reaction } from "mobx"; import { DrawerItem, DrawerTitle } from "../drawer"; import type { ILoadBalancerIngress, Ingress } from "../../api/endpoints"; import { Table, TableCell, TableHead, TableRow } from "../table"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { ingressStore } from "./ingress.store"; import { ResourceMetrics } from "../resource-metrics"; import type { KubeObjectDetailsProps } from "../kube-object"; import { IngressCharts } from "./ingress-charts"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getBackendServiceNamePort } from "../../api/endpoints/ingress.api"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -167,19 +165,3 @@ export class IngressDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Ingress", - apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "Ingress", - apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+network-policies/network-policy-details.tsx b/src/renderer/components/+network-policies/network-policy-details.tsx index 289d139fb5..7ac8f2f7bf 100644 --- a/src/renderer/components/+network-policies/network-policy-details.tsx +++ b/src/renderer/components/+network-policies/network-policy-details.tsx @@ -27,11 +27,9 @@ import { DrawerItem, DrawerTitle } from "../drawer"; import type { IPolicyEgress, IPolicyIngress, IPolicyIpBlock, IPolicySelector, NetworkPolicy } from "../../api/endpoints/network-policy.api"; import { Badge } from "../badge"; import { SubTitle } from "../layout/sub-title"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { observer } from "mobx-react"; import type { KubeObjectDetailsProps } from "../kube-object"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -172,20 +170,3 @@ export class NetworkPolicyDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "NetworkPolicy", - apiVersions: ["networking.k8s.io/v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "NetworkPolicy", - apiVersions: ["networking.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+network-services/service-details.tsx b/src/renderer/components/+network-services/service-details.tsx index 924e7c4288..6450850076 100644 --- a/src/renderer/components/+network-services/service-details.tsx +++ b/src/renderer/components/+network-services/service-details.tsx @@ -25,14 +25,12 @@ import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; import { DrawerItem, DrawerTitle } from "../drawer"; import { Badge } from "../badge"; -import { KubeEventDetails } from "../+events/kube-event-details"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { Service } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { ServicePortComponent } from "./service-port-component"; import { endpointStore } from "../+network-endpoints/endpoints.store"; import { ServiceDetailsEndpoint } from "./service-details-endpoint"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { kubeWatchApi } from "../../api/kube-watch-api"; interface Props extends KubeObjectDetailsProps { @@ -121,20 +119,3 @@ export class ServiceDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Service", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "Service", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+network/index.ts b/src/renderer/components/+network/index.ts index bfb7c13b58..3d501faf9b 100644 --- a/src/renderer/components/+network/index.ts +++ b/src/renderer/components/+network/index.ts @@ -20,4 +20,3 @@ */ export * from "./network"; -export * from "./network.command"; diff --git a/src/renderer/components/+nodes/index.ts b/src/renderer/components/+nodes/index.ts index eb9f3cd2c1..dbcdba9422 100644 --- a/src/renderer/components/+nodes/index.ts +++ b/src/renderer/components/+nodes/index.ts @@ -21,4 +21,3 @@ export * from "./nodes"; export * from "./node-details"; -export * from "./node.command"; diff --git a/src/renderer/components/+nodes/node-details.tsx b/src/renderer/components/+nodes/node-details.tsx index 67cb76de2e..a12109235b 100644 --- a/src/renderer/components/+nodes/node-details.tsx +++ b/src/renderer/components/+nodes/node-details.tsx @@ -36,8 +36,6 @@ import { NodeCharts } from "./node-charts"; import { reaction } from "mobx"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { KubeEventDetails } from "../+events/kube-event-details"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; import { NodeDetailsResources } from "./node-details-resources"; @@ -173,20 +171,3 @@ export class NodeDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Node", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "Node", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+pod-security-policies/pod-security-policy-details.tsx b/src/renderer/components/+pod-security-policies/pod-security-policy-details.tsx index eacc4f7696..abdefe9228 100644 --- a/src/renderer/components/+pod-security-policies/pod-security-policy-details.tsx +++ b/src/renderer/components/+pod-security-policies/pod-security-policy-details.tsx @@ -29,7 +29,6 @@ import type { PodSecurityPolicy } from "../../api/endpoints"; import { Badge } from "../badge"; import { Table, TableCell, TableHead, TableRow } from "../table"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -231,11 +230,3 @@ export class PodSecurityPolicyDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "PodSecurityPolicy", - apiVersions: ["policy/v1beta1"], - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 82b2b8eaed..0a85c6369d 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -27,7 +27,7 @@ import { computed, observable, reaction, makeObservable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import { isWindows } from "../../../common/vars"; -import { appPreferenceRegistry, RegisteredAppPreference } from "../../../extensions/registries/app-preference-registry"; +import { AppPreferenceRegistry, RegisteredAppPreference } from "../../../extensions/registries/app-preference-registry"; import { UserStore } from "../../../common/user-store"; import { ThemeStore } from "../../theme.store"; import { Input } from "../input"; @@ -93,7 +93,7 @@ export class Preferences extends React.Component { }; renderNavigation() { - const extensions = appPreferenceRegistry.getItems().filter(e => !e.showInPreferencesTab); + const extensions = AppPreferenceRegistry.getInstance().getItems().filter(e => !e.showInPreferencesTab); return ( @@ -125,7 +125,7 @@ export class Preferences extends React.Component { } render() { - const extensions = appPreferenceRegistry.getItems(); + const extensions = AppPreferenceRegistry.getInstance().getItems(); const telemetryExtensions = extensions.filter(e => e.showInPreferencesTab == Pages.Telemetry); const defaultShell = process.env.SHELL || process.env.PTYSHELL diff --git a/src/renderer/components/+storage-classes/storage-class-details.tsx b/src/renderer/components/+storage-classes/storage-class-details.tsx index e99501b963..0d2b9e0600 100644 --- a/src/renderer/components/+storage-classes/storage-class-details.tsx +++ b/src/renderer/components/+storage-classes/storage-class-details.tsx @@ -25,12 +25,10 @@ import React from "react"; import startCase from "lodash/startCase"; import { DrawerItem, DrawerTitle } from "../drawer"; import { Badge } from "../badge"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { observer } from "mobx-react"; import type { KubeObjectDetailsProps } from "../kube-object"; import type { StorageClass } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { storageClassStore } from "./storage-class.store"; import { VolumeDetailsList } from "../+storage-volumes/volume-details-list"; import { volumesStore } from "../+storage-volumes/volumes.store"; @@ -89,20 +87,3 @@ export class StorageClassDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "StorageClass", - apiVersions: ["storage.k8s.io/v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "StorageClass", - apiVersions: ["storage.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+storage-volume-claims/volume-claim-details.tsx b/src/renderer/components/+storage-volume-claims/volume-claim-details.tsx index d7d474365d..3066aafea8 100644 --- a/src/renderer/components/+storage-volume-claims/volume-claim-details.tsx +++ b/src/renderer/components/+storage-volume-claims/volume-claim-details.tsx @@ -28,13 +28,11 @@ import { DrawerItem, DrawerTitle } from "../drawer"; import { Badge } from "../badge"; import { podsStore } from "../+workloads-pods/pods.store"; import { Link } from "react-router-dom"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { volumeClaimStore } from "./volume-claim.store"; import { ResourceMetrics } from "../resource-metrics"; import { VolumeClaimDiskChart } from "./volume-claim-disk-chart"; import { getDetailsUrl, KubeObjectDetailsProps, KubeObjectMeta } from "../kube-object"; import type { PersistentVolumeClaim } from "../../api/endpoints"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -116,20 +114,3 @@ export class PersistentVolumeClaimDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "PersistentVolumeClaim", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "PersistentVolumeClaim", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+storage-volumes/volume-details.tsx b/src/renderer/components/+storage-volumes/volume-details.tsx index ff718b4352..66354db988 100644 --- a/src/renderer/components/+storage-volumes/volume-details.tsx +++ b/src/renderer/components/+storage-volumes/volume-details.tsx @@ -27,11 +27,9 @@ import { Link } from "react-router-dom"; import { observer } from "mobx-react"; import { DrawerItem, DrawerTitle } from "../drawer"; import { Badge } from "../badge"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { PersistentVolume, pvcApi } from "../../api/endpoints"; import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -121,20 +119,3 @@ export class PersistentVolumeDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "PersistentVolume", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "PersistentVolume", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+cluster-role-bindings/details.tsx b/src/renderer/components/+user-management/+cluster-role-bindings/details.tsx index ac5b2cb933..08087324cc 100644 --- a/src/renderer/components/+user-management/+cluster-role-bindings/details.tsx +++ b/src/renderer/components/+user-management/+cluster-role-bindings/details.tsx @@ -25,9 +25,7 @@ import { reaction } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import React from "react"; -import { KubeEventDetails } from "../../+events/kube-event-details"; import type { ClusterRoleBinding, ClusterRoleBindingSubject } from "../../../api/endpoints"; -import { kubeObjectDetailRegistry } from "../../../api/kube-object-detail-registry"; import { autoBind, ObservableHashSet, prevDefault } from "../../../utils"; import { AddRemoveButtons } from "../../add-remove-buttons"; import { ConfirmDialog } from "../../confirm-dialog"; @@ -139,19 +137,3 @@ export class ClusterRoleBindingDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ClusterRoleBinding", - apiVersions: ["rbac.authorization.k8s.io/v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "ClusterRoleBinding", - apiVersions: ["rbac.authorization.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+cluster-roles/details.tsx b/src/renderer/components/+user-management/+cluster-roles/details.tsx index 52bee8dc8e..2add64b57c 100644 --- a/src/renderer/components/+user-management/+cluster-roles/details.tsx +++ b/src/renderer/components/+user-management/+cluster-roles/details.tsx @@ -24,8 +24,6 @@ import "./details.scss"; import { observer } from "mobx-react"; import React from "react"; -import { KubeEventDetails } from "../../+events/kube-event-details"; -import { kubeObjectDetailRegistry } from "../../../api/kube-object-detail-registry"; import { DrawerTitle } from "../../drawer"; import type { KubeObjectDetailsProps } from "../../kube-object"; import { KubeObjectMeta } from "../../kube-object/kube-object-meta"; @@ -86,19 +84,3 @@ export class ClusterRoleDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ClusterRole", - apiVersions: ["rbac.authorization.k8s.io/v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "ClusterRole", - apiVersions: ["rbac.authorization.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+role-bindings/details.tsx b/src/renderer/components/+user-management/+role-bindings/details.tsx index 39080d56b5..aee0f6c2af 100644 --- a/src/renderer/components/+user-management/+role-bindings/details.tsx +++ b/src/renderer/components/+user-management/+role-bindings/details.tsx @@ -24,9 +24,7 @@ import "./details.scss"; import { reaction } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import React from "react"; -import { KubeEventDetails } from "../../+events/kube-event-details"; import type { RoleBinding, RoleBindingSubject } from "../../../api/endpoints"; -import { kubeObjectDetailRegistry } from "../../../api/kube-object-detail-registry"; import { prevDefault, boundMethod } from "../../../utils"; import { AddRemoveButtons } from "../../add-remove-buttons"; import { ConfirmDialog } from "../../confirm-dialog"; @@ -137,19 +135,3 @@ export class RoleBindingDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "RoleBinding", - apiVersions: ["rbac.authorization.k8s.io/v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "RoleBinding", - apiVersions: ["rbac.authorization.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+roles/details.tsx b/src/renderer/components/+user-management/+roles/details.tsx index 2cc078f96a..2b6f822ed0 100644 --- a/src/renderer/components/+user-management/+roles/details.tsx +++ b/src/renderer/components/+user-management/+roles/details.tsx @@ -24,9 +24,7 @@ import "./details.scss"; import { observer } from "mobx-react"; import React from "react"; -import { KubeEventDetails } from "../../+events/kube-event-details"; import type { Role } from "../../../api/endpoints"; -import { kubeObjectDetailRegistry } from "../../../api/kube-object-detail-registry"; import { DrawerTitle } from "../../drawer"; import type { KubeObjectDetailsProps } from "../../kube-object"; import { KubeObjectMeta } from "../../kube-object/kube-object-meta"; @@ -85,19 +83,3 @@ export class RoleDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Role", - apiVersions: ["rbac.authorization.k8s.io/v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "Role", - apiVersions: ["rbac.authorization.k8s.io/v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+service-accounts/details.tsx b/src/renderer/components/+user-management/+service-accounts/details.tsx index 7b9a590138..578cde2ab4 100644 --- a/src/renderer/components/+user-management/+service-accounts/details.tsx +++ b/src/renderer/components/+user-management/+service-accounts/details.tsx @@ -27,9 +27,7 @@ import React from "react"; import { Link } from "react-router-dom"; import { secretsStore } from "../../+config-secrets/secrets.store"; -import { KubeEventDetails } from "../../+events/kube-event-details"; import { Secret, ServiceAccount } from "../../../api/endpoints"; -import { kubeObjectDetailRegistry } from "../../../api/kube-object-detail-registry"; import { DrawerItem, DrawerTitle } from "../../drawer"; import { Icon } from "../../icon"; import { getDetailsUrl, KubeObjectDetailsProps } from "../../kube-object"; @@ -164,19 +162,3 @@ export class ServiceAccountsDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ServiceAccount", - apiVersions: ["v1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "ServiceAccount", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+user-management/+service-accounts/view.tsx b/src/renderer/components/+user-management/+service-accounts/view.tsx index 37ded42ae5..282ae3ec63 100644 --- a/src/renderer/components/+user-management/+service-accounts/view.tsx +++ b/src/renderer/components/+user-management/+service-accounts/view.tsx @@ -24,7 +24,6 @@ import "./view.scss"; import { observer } from "mobx-react"; import React from "react"; import type { RouteComponentProps } from "react-router"; -import { kubeObjectMenuRegistry } from "../../../../extensions/registries/kube-object-menu-registry"; import type { ServiceAccount } from "../../../api/endpoints/service-accounts.api"; import { Icon } from "../../icon"; import { KubeObjectListLayout } from "../../kube-object"; @@ -89,21 +88,13 @@ export class ServiceAccounts extends React.Component { } } -function ServiceAccountMenu(props: KubeObjectMenuProps) { +export function ServiceAccountMenu(props: KubeObjectMenuProps) { const { object, toolbar } = props; return ( openServiceAccountKubeConfig(object)}> - + Kubeconfig ); } - -kubeObjectMenuRegistry.add({ - kind: "ServiceAccount", - apiVersions: ["v1"], - components: { - MenuItem: ServiceAccountMenu - } -}); diff --git a/src/renderer/components/+welcome/welcome.tsx b/src/renderer/components/+welcome/welcome.tsx index 6157798942..ed3d9b5dc4 100644 --- a/src/renderer/components/+welcome/welcome.tsx +++ b/src/renderer/components/+welcome/welcome.tsx @@ -24,33 +24,10 @@ import React from "react"; import { observer } from "mobx-react"; import { Icon } from "../icon"; import { productName, slackUrl } from "../../../common/vars"; -import { welcomeMenuRegistry } from "../../../extensions/registries"; -import { navigate } from "../../navigation"; -import { catalogURL, preferencesURL } from "../../../common/routes"; +import { WelcomeMenuRegistry } from "../../../extensions/registries"; @observer export class Welcome extends React.Component { - - componentDidMount() { - if (welcomeMenuRegistry.getItems().find((item) => item.title === "Browse Your Catalog")) { - return; - } - - welcomeMenuRegistry.add({ - title: "Browse Your Catalog", - icon: "view_list", - click: () => navigate(catalogURL()) - }); - - if (welcomeMenuRegistry.getItems().length === 1) { - welcomeMenuRegistry.add({ - title: "Configure Preferences", - icon: "settings", - click: () => navigate(preferencesURL()) - }); - } - } - render() { return (
@@ -65,7 +42,7 @@ export class Welcome extends React.Component {

    - { welcomeMenuRegistry.getItems().map((item, index) => ( + {WelcomeMenuRegistry.getInstance().getItems().map((item, index) => (
  • item.click()}> {typeof item.title === "string" ? item.title : item.title()}
  • diff --git a/src/renderer/components/+workloads-cronjobs/cronjob-details.tsx b/src/renderer/components/+workloads-cronjobs/cronjob-details.tsx index e86f4f5c8e..12f919b4e6 100644 --- a/src/renderer/components/+workloads-cronjobs/cronjob-details.tsx +++ b/src/renderer/components/+workloads-cronjobs/cronjob-details.tsx @@ -28,12 +28,10 @@ import { DrawerItem, DrawerTitle } from "../drawer"; import { Badge } from "../badge/badge"; import { jobStore } from "../+workloads-jobs/job.store"; import { Link } from "react-router-dom"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { cronJobStore } from "./cronjob.store"; import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object"; import type { CronJob, Job } from "../../api/endpoints"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -105,19 +103,3 @@ export class CronJobDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "CronJob", - apiVersions: ["batch/v1beta1"], - components: { - Details: (props) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "CronJob", - apiVersions: ["batch/v1beta1"], - priority: 5, - components: { - Details: (props) => - } -}); diff --git a/src/renderer/components/+workloads-cronjobs/cronjobs.tsx b/src/renderer/components/+workloads-cronjobs/cronjobs.tsx index 64690422d0..df976a187b 100644 --- a/src/renderer/components/+workloads-cronjobs/cronjobs.tsx +++ b/src/renderer/components/+workloads-cronjobs/cronjobs.tsx @@ -33,7 +33,6 @@ import { eventStore } from "../+events/event.store"; import type { KubeObjectMenuProps } from "../kube-object/kube-object-menu"; import { KubeObjectListLayout } from "../kube-object"; import { CronJobTriggerDialog } from "./cronjob-trigger-dialog"; -import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { ConfirmDialog } from "../confirm-dialog/confirm-dialog"; import { Notifications } from "../notifications/notifications"; @@ -152,11 +151,3 @@ export function CronJobMenu(props: KubeObjectMenuProps) { ); } - -kubeObjectMenuRegistry.add({ - kind: "CronJob", - apiVersions: ["batch/v1beta1"], - components: { - MenuItem: CronJobMenu - } -}); diff --git a/src/renderer/components/+workloads-daemonsets/daemonset-details.tsx b/src/renderer/components/+workloads-daemonsets/daemonset-details.tsx index 8df3af9bd6..199385a1f4 100644 --- a/src/renderer/components/+workloads-daemonsets/daemonset-details.tsx +++ b/src/renderer/components/+workloads-daemonsets/daemonset-details.tsx @@ -28,7 +28,6 @@ import { Badge } from "../badge"; import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses"; import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations"; import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { daemonSetStore } from "./daemonsets.store"; import { podsStore } from "../+workloads-pods/pods.store"; import type { KubeObjectDetailsProps } from "../kube-object"; @@ -38,7 +37,6 @@ import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts"; import { reaction } from "mobx"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -118,19 +116,3 @@ export class DaemonSetDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "DaemonSet", - apiVersions: ["apps/v1"], - components: { - Details: (props: any) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "DaemonSet", - apiVersions: ["apps/v1"], - priority: 5, - components: { - Details: (props: any) => - } -}); diff --git a/src/renderer/components/+workloads-deployments/deployment-details.tsx b/src/renderer/components/+workloads-deployments/deployment-details.tsx index b1b98939b7..acd514749f 100644 --- a/src/renderer/components/+workloads-deployments/deployment-details.tsx +++ b/src/renderer/components/+workloads-deployments/deployment-details.tsx @@ -30,7 +30,6 @@ import type { Deployment } from "../../api/endpoints"; import { cssNames } from "../../utils"; import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations"; import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { podsStore } from "../+workloads-pods/pods.store"; import type { KubeObjectDetailsProps } from "../kube-object"; import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics"; @@ -39,7 +38,6 @@ import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts"; import { reaction } from "mobx"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { replicaSetStore } from "../+workloads-replicasets/replicasets.store"; import { DeploymentReplicaSets } from "./deployment-replicasets"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; @@ -141,19 +139,3 @@ export class DeploymentDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Deployment", - apiVersions: ["apps/v1"], - components: { - Details: (props: any) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "Deployment", - apiVersions: ["apps/v1"], - priority: 5, - components: { - Details: (props: any) => - } -}); diff --git a/src/renderer/components/+workloads-deployments/deployments.tsx b/src/renderer/components/+workloads-deployments/deployments.tsx index 6bca45c864..d57d5135b2 100644 --- a/src/renderer/components/+workloads-deployments/deployments.tsx +++ b/src/renderer/components/+workloads-deployments/deployments.tsx @@ -39,7 +39,6 @@ import { KubeObjectListLayout } from "../kube-object"; import { cssNames } from "../../utils"; import kebabCase from "lodash/kebabCase"; import orderBy from "lodash/orderBy"; -import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { Notifications } from "../notifications"; import type { DeploymentsRouteParams } from "../../../common/routes"; @@ -153,11 +152,3 @@ export function DeploymentMenu(props: KubeObjectMenuProps) { ); } - -kubeObjectMenuRegistry.add({ - kind: "Deployment", - apiVersions: ["apps/v1"], - components: { - MenuItem: DeploymentMenu - } -}); diff --git a/src/renderer/components/+workloads-jobs/job-details.tsx b/src/renderer/components/+workloads-jobs/job-details.tsx index 6fcbff96e7..02cd5b41d4 100644 --- a/src/renderer/components/+workloads-jobs/job-details.tsx +++ b/src/renderer/components/+workloads-jobs/job-details.tsx @@ -30,7 +30,6 @@ import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses"; import { Link } from "react-router-dom"; import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations"; import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { podsStore } from "../+workloads-pods/pods.store"; import { jobStore } from "./job.store"; import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object"; @@ -38,7 +37,6 @@ import type { Job } from "../../api/endpoints"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { lookupApiLink } from "../../api/kube-api"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; interface Props extends KubeObjectDetailsProps { } @@ -125,19 +123,3 @@ export class JobDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Job", - apiVersions: ["batch/v1"], - components: { - Details: (props: any) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "Job", - apiVersions: ["batch/v1"], - priority: 5, - components: { - Details: (props: any) => - } -}); diff --git a/src/renderer/components/+workloads-overview/overview.tsx b/src/renderer/components/+workloads-overview/overview.tsx index e892539778..ec025f0d80 100644 --- a/src/renderer/components/+workloads-overview/overview.tsx +++ b/src/renderer/components/+workloads-overview/overview.tsx @@ -23,7 +23,6 @@ import "./overview.scss"; import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; -import { OverviewStatuses } from "./overview-statuses"; import type { RouteComponentProps } from "react-router"; import { eventStore } from "../+events/event.store"; import { podsStore } from "../+workloads-pods/pods.store"; @@ -33,11 +32,9 @@ import { statefulSetStore } from "../+workloads-statefulsets/statefulset.store"; import { replicaSetStore } from "../+workloads-replicasets/replicasets.store"; import { jobStore } from "../+workloads-jobs/job.store"; import { cronJobStore } from "../+workloads-cronjobs/cronjob.store"; -import { Events } from "../+events"; -import { isAllowedResource } from "../../../common/rbac"; import { kubeWatchApi } from "../../api/kube-watch-api"; import { clusterContext } from "../context"; -import { workloadsOverviewDetailRegistry } from "../../../extensions/registries"; +import { WorkloadsOverviewDetailRegistry } from "../../../extensions/registries"; import type { WorkloadsOverviewRouteParams } from "../../../common/routes"; interface Props extends RouteComponentProps { @@ -58,7 +55,7 @@ export class WorkloadsOverview extends React.Component { } render() { - const items = workloadsOverviewDetailRegistry.getItems().map((item, index) => { + const items = WorkloadsOverviewDetailRegistry.getInstance().getItems().map((item, index) => { return ( ); @@ -71,21 +68,3 @@ export class WorkloadsOverview extends React.Component { ); } } - -workloadsOverviewDetailRegistry.add([ - { - components: { - Details: (props: any) => , - } - }, - { - priority: 5, - components: { - Details: () => { - return ( - isAllowedResource("events") && - ); - } - } - } -]); diff --git a/src/renderer/components/+workloads-pods/pod-details.tsx b/src/renderer/components/+workloads-pods/pod-details.tsx index 884fc43e3e..2a7516b816 100644 --- a/src/renderer/components/+workloads-pods/pod-details.tsx +++ b/src/renderer/components/+workloads-pods/pod-details.tsx @@ -34,7 +34,6 @@ import { PodDetailsContainer } from "./pod-details-container"; import { PodDetailsAffinities } from "./pod-details-affinities"; import { PodDetailsTolerations } from "./pod-details-tolerations"; import { Icon } from "../icon"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { PodDetailsSecrets } from "./pod-details-secrets"; import { ResourceMetrics } from "../resource-metrics"; import { podsStore } from "./pods.store"; @@ -42,7 +41,6 @@ import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object"; import { getItemMetrics } from "../../api/endpoints/metrics.api"; import { PodCharts, podMetricTabs } from "./pod-charts"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -261,20 +259,3 @@ export class PodDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "Pod", - apiVersions: ["v1"], - components: { - Details: (props: KubeObjectDetailsProps) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "Pod", - apiVersions: ["v1"], - priority: 5, - components: { - Details: (props: KubeObjectDetailsProps) => - } -}); diff --git a/src/renderer/components/+workloads-replicasets/replicaset-details.tsx b/src/renderer/components/+workloads-replicasets/replicaset-details.tsx index 9af8511984..7818be6765 100644 --- a/src/renderer/components/+workloads-replicasets/replicaset-details.tsx +++ b/src/renderer/components/+workloads-replicasets/replicaset-details.tsx @@ -28,7 +28,6 @@ import { replicaSetStore } from "./replicasets.store"; import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses"; import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations"; import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { disposeOnUnmount, observer } from "mobx-react"; import { podsStore } from "../+workloads-pods/pods.store"; import type { KubeObjectDetailsProps } from "../kube-object"; @@ -37,7 +36,6 @@ import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics"; import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -118,19 +116,3 @@ export class ReplicaSetDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "ReplicaSet", - apiVersions: ["apps/v1"], - components: { - Details: (props: any) => - } -}); -kubeObjectDetailRegistry.add({ - kind: "ReplicaSet", - apiVersions: ["apps/v1"], - priority: 5, - components: { - Details: (props: any) => - } -}); diff --git a/src/renderer/components/+workloads-replicasets/replicasets.tsx b/src/renderer/components/+workloads-replicasets/replicasets.tsx index 30aebb6efa..b14915e85f 100644 --- a/src/renderer/components/+workloads-replicasets/replicasets.tsx +++ b/src/renderer/components/+workloads-replicasets/replicasets.tsx @@ -31,7 +31,6 @@ import type { RouteComponentProps } from "react-router"; import { KubeObjectListLayout } from "../kube-object/kube-object-list-layout"; import { MenuItem } from "../menu/menu"; import { Icon } from "../icon/icon"; -import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog"; import type { ReplicaSetsRouteParams } from "../../../common/routes"; @@ -105,11 +104,3 @@ export function ReplicaSetMenu(props: KubeObjectMenuProps) { ); } - -kubeObjectMenuRegistry.add({ - kind: "ReplicaSet", - apiVersions: ["apps/v1"], - components: { - MenuItem: ReplicaSetMenu - } -}); diff --git a/src/renderer/components/+workloads-statefulsets/statefulset-details.tsx b/src/renderer/components/+workloads-statefulsets/statefulset-details.tsx index 1d4d7727d1..dafe8c16b6 100644 --- a/src/renderer/components/+workloads-statefulsets/statefulset-details.tsx +++ b/src/renderer/components/+workloads-statefulsets/statefulset-details.tsx @@ -29,7 +29,6 @@ import { DrawerItem } from "../drawer"; import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses"; import { PodDetailsTolerations } from "../+workloads-pods/pod-details-tolerations"; import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"; -import { KubeEventDetails } from "../+events/kube-event-details"; import { podsStore } from "../+workloads-pods/pods.store"; import { statefulSetStore } from "./statefulset.store"; import type { KubeObjectDetailsProps } from "../kube-object"; @@ -38,7 +37,6 @@ import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics"; import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts"; import { PodDetailsList } from "../+workloads-pods/pod-details-list"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; import { ClusterMetricsResourceType } from "../../../main/cluster"; @@ -116,20 +114,3 @@ export class StatefulSetDetails extends React.Component { ); } } - -kubeObjectDetailRegistry.add({ - kind: "StatefulSet", - apiVersions: ["apps/v1"], - components: { - Details: (props: any) => - } -}); - -kubeObjectDetailRegistry.add({ - kind: "StatefulSet", - apiVersions: ["apps/v1"], - priority: 5, - components: { - Details: (props: any) => - } -}); diff --git a/src/renderer/components/+workloads-statefulsets/statefulsets.tsx b/src/renderer/components/+workloads-statefulsets/statefulsets.tsx index 3340c30381..0431191d7d 100644 --- a/src/renderer/components/+workloads-statefulsets/statefulsets.tsx +++ b/src/renderer/components/+workloads-statefulsets/statefulsets.tsx @@ -35,7 +35,6 @@ import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { StatefulSetScaleDialog } from "./statefulset-scale-dialog"; import { MenuItem } from "../menu/menu"; import { Icon } from "../icon/icon"; -import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; import type { StatefulSetsRouteParams } from "../../../common/routes"; enum columnId { @@ -110,11 +109,3 @@ export function StatefulSetMenu(props: KubeObjectMenuProps) { ); } - -kubeObjectMenuRegistry.add({ - kind: "StatefulSet", - apiVersions: ["apps/v1"], - components: { - MenuItem: StatefulSetMenu - } -}); diff --git a/src/renderer/components/+workloads/index.ts b/src/renderer/components/+workloads/index.ts index 4e0e932a51..ab4e8fa18c 100644 --- a/src/renderer/components/+workloads/index.ts +++ b/src/renderer/components/+workloads/index.ts @@ -21,4 +21,3 @@ export * from "./workloads"; export * from "./workloads.stores"; -export * from "./workloads.command"; diff --git a/src/renderer/components/+workloads/workloads.command.ts b/src/renderer/components/+workloads/workloads.command.ts deleted file mode 100644 index 2cc8895714..0000000000 --- a/src/renderer/components/+workloads/workloads.command.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2021 OpenLens Authors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import * as routes from "../../../common/routes"; - -commandRegistry.add({ - id: "cluster.viewPods", - title: "Cluster: View Pods", - scope: "entity", - action: () => navigate(routes.podsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewDeployments", - title: "Cluster: View Deployments", - scope: "entity", - action: () => navigate(routes.deploymentsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewDaemonSets", - title: "Cluster: View DaemonSets", - scope: "entity", - action: () => navigate(routes.daemonSetsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewStatefulSets", - title: "Cluster: View StatefulSets", - scope: "entity", - action: () => navigate(routes.statefulSetsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewJobs", - title: "Cluster: View Jobs", - scope: "entity", - action: () => navigate(routes.jobsURL()) -}); - -commandRegistry.add({ - id: "cluster.viewCronJobs", - title: "Cluster: View CronJobs", - scope: "entity", - action: () => navigate(routes.cronJobsURL()) -}); diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 0f9ca747c1..1e1c14fd4c 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -35,13 +35,13 @@ import { isAllowedResource } from "../../common/rbac"; import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store"; import logger from "../../main/logger"; import { webFrame } from "electron"; -import { clusterPageRegistry, getExtensionPageUrl } from "../../extensions/registries/page-registry"; +import { ClusterPageRegistry, getExtensionPageUrl } from "../../extensions/registries/page-registry"; import { ExtensionLoader } from "../../extensions/extension-loader"; import { appEventBus } from "../../common/event-bus"; import { requestMain } from "../../common/ipc"; import whatInput from "what-input"; import { clusterSetFrameIdHandler } from "../../common/cluster-ipc"; -import { ClusterPageMenuRegistration, clusterPageMenuRegistry } from "../../extensions/registries"; +import { ClusterPageMenuRegistration, ClusterPageMenuRegistry } from "../../extensions/registries"; import { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog"; import { eventStore } from "./+events/event.store"; import { nodesStore } from "./+nodes/nodes.store"; @@ -122,8 +122,8 @@ export class App extends React.Component { if (!menuItem.id) { return routes; } - clusterPageMenuRegistry.getSubItems(menuItem).forEach((subMenu) => { - const page = clusterPageRegistry.getByPageTarget(subMenu.target); + ClusterPageMenuRegistry.getInstance().getSubItems(menuItem).forEach((subMenu) => { + const page = ClusterPageRegistry.getInstance().getByPageTarget(subMenu.target); if (page) { routes.push({ @@ -139,7 +139,7 @@ export class App extends React.Component { } renderExtensionTabLayoutRoutes() { - return clusterPageMenuRegistry.getRootItems().map((menu, index) => { + return ClusterPageMenuRegistry.getInstance().getRootItems().map((menu, index) => { const tabRoutes = this.getTabLayoutRoutes(menu); if (tabRoutes.length > 0) { @@ -147,7 +147,7 @@ export class App extends React.Component { return tab.routePath)}/>; } else { - const page = clusterPageRegistry.getByPageTarget(menu.target); + const page = ClusterPageRegistry.getInstance().getByPageTarget(menu.target); if (page) { return ; @@ -159,8 +159,8 @@ export class App extends React.Component { } renderExtensionRoutes() { - return clusterPageRegistry.getItems().map((page, index) => { - const menu = clusterPageMenuRegistry.getByPage(page); + return ClusterPageRegistry.getInstance().getItems().map((page, index) => { + const menu = ClusterPageMenuRegistry.getInstance().getByPage(page); if (!menu) { return ; diff --git a/src/renderer/components/cluster-manager/bottom-bar.test.tsx b/src/renderer/components/cluster-manager/bottom-bar.test.tsx index eceb02697a..bf6c11245e 100644 --- a/src/renderer/components/cluster-manager/bottom-bar.test.tsx +++ b/src/renderer/components/cluster-manager/bottom-bar.test.tsx @@ -30,10 +30,17 @@ jest.mock("electron", () => ({ })); import { BottomBar } from "./bottom-bar"; -jest.mock("../../../extensions/registries"); -import { statusBarRegistry } from "../../../extensions/registries"; +import { StatusBarRegistry } from "../../../extensions/registries"; describe("", () => { + beforeEach(() => { + StatusBarRegistry.createInstance(); + }); + + afterEach(() => { + StatusBarRegistry.resetInstance(); + }); + it("renders w/o errors", () => { const { container } = render(); @@ -41,19 +48,19 @@ describe("", () => { }); it("renders w/o errors when .getItems() returns unexpected (not type complient) data", async () => { - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => undefined); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => undefined); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => "hello"); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => "hello"); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => 6); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => 6); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => null); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => null); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => []); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => []); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => [{}]); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [{}]); expect(() => render()).not.toThrow(); - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => { return {};}); + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => { return {};}); expect(() => render()).not.toThrow(); }); @@ -61,7 +68,7 @@ describe("", () => { const testId = "testId"; const text = "heee"; - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => [ + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [ { item: {text} } ]); const { getByTestId } = render(); @@ -73,7 +80,7 @@ describe("", () => { const testId = "testId"; const text = "heee"; - statusBarRegistry.getItems = jest.fn().mockImplementationOnce(() => [ + StatusBarRegistry.getInstance().getItems = jest.fn().mockImplementationOnce(() => [ { item: () => {text} } ]); const { getByTestId } = render(); diff --git a/src/renderer/components/cluster-manager/bottom-bar.tsx b/src/renderer/components/cluster-manager/bottom-bar.tsx index 19c2379824..8e37128198 100644 --- a/src/renderer/components/cluster-manager/bottom-bar.tsx +++ b/src/renderer/components/cluster-manager/bottom-bar.tsx @@ -23,7 +23,7 @@ import "./bottom-bar.scss"; import React from "react"; import { observer } from "mobx-react"; -import { StatusBarRegistration, statusBarRegistry } from "../../../extensions/registries"; +import { StatusBarRegistration, StatusBarRegistry } from "../../../extensions/registries"; import { navigate } from "../../navigation"; import { Icon } from "../icon"; import { catalogURL } from "../../../common/routes"; @@ -41,7 +41,7 @@ export class BottomBar extends React.Component { } renderRegisteredItems() { - const items = statusBarRegistry.getItems(); + const items = StatusBarRegistry.getInstance().getItems(); if (!Array.isArray(items)) { return null; diff --git a/src/renderer/components/cluster-manager/cluster-manager.tsx b/src/renderer/components/cluster-manager/cluster-manager.tsx index 2fc4d1d2a9..4bd14e7805 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.tsx +++ b/src/renderer/components/cluster-manager/cluster-manager.tsx @@ -29,7 +29,7 @@ import { Catalog } from "../+catalog"; import { Preferences } from "../+preferences"; import { AddCluster } from "../+add-cluster"; import { ClusterView } from "./cluster-view"; -import { globalPageRegistry } from "../../../extensions/registries/page-registry"; +import { GlobalPageRegistry } from "../../../extensions/registries/page-registry"; import { Extensions } from "../+extensions"; import { HotbarMenu } from "../hotbar/hotbar-menu"; import { EntitySettings } from "../+entity-settings"; @@ -52,7 +52,7 @@ export class ClusterManager extends React.Component { { - globalPageRegistry.getItems() + GlobalPageRegistry.getInstance().getItems() .map(({ url, components: { Page } }) => ( )) diff --git a/src/renderer/components/cluster-settings/cluster-settings.tsx b/src/renderer/components/cluster-settings/cluster-settings.tsx index d8fd374136..32190df9bc 100644 --- a/src/renderer/components/cluster-settings/cluster-settings.tsx +++ b/src/renderer/components/cluster-settings/cluster-settings.tsx @@ -21,140 +21,93 @@ import React from "react"; import { ClusterStore } from "../../../common/cluster-store"; -import { ClusterProxySetting } from "./components/cluster-proxy-setting"; -import { ClusterNameSetting } from "./components/cluster-name-setting"; -import { ClusterHomeDirSetting } from "./components/cluster-home-dir-setting"; -import { ClusterAccessibleNamespaces } from "./components/cluster-accessible-namespaces"; -import { ClusterMetricsSetting } from "./components/cluster-metrics-setting"; -import { ShowMetricsSetting } from "./components/show-metrics"; -import { ClusterPrometheusSetting } from "./components/cluster-prometheus-setting"; -import { ClusterKubeconfig } from "./components/cluster-kubeconfig"; -import { entitySettingRegistry } from "../../../extensions/registries"; +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.metadata.uid); } -entitySettingRegistry.add([ - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - source: "local", - title: "General", - group: "Settings", - components: { - View: (props: { entity: CatalogEntity }) => { - const cluster = getClusterForEntity(props.entity); +export function GeneralSettings({ entity }: EntitySettingViewProps) { + const cluster = getClusterForEntity(entity); - if (!cluster) { - return null; - } - - return ( -
    -
    - -
    -
    - -
    -
    - ); - } - } - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Proxy", - group: "Settings", - components: { - View: (props: { entity: CatalogEntity }) => { - const cluster = getClusterForEntity(props.entity); - - if (!cluster) { - return null; - } - - return ( -
    - -
    - ); - } - } - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Terminal", - group: "Settings", - components: { - View: (props: { entity: CatalogEntity }) => { - const cluster = getClusterForEntity(props.entity); - - if (!cluster) { - return null; - } - - return ( -
    - -
    - ); - } - } - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Namespaces", - group: "Settings", - components: { - View: (props: { entity: CatalogEntity }) => { - const cluster = getClusterForEntity(props.entity); - - if (!cluster) { - return null; - } - - return ( -
    - -
    - ); - } - } - }, - { - apiVersions: ["entity.k8slens.dev/v1alpha1"], - kind: "KubernetesCluster", - title: "Metrics", - group: "Settings", - components: { - View: (props: { entity: CatalogEntity }) => { - const cluster = getClusterForEntity(props.entity); - - if (!cluster) { - return null; - } - - return ( -
    -
    - -
    -
    - -
    -
    - -
    -
    - ); - } - } + 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 ( +
    +
    + +
    +
    + +
    +
    + +
    +
    + ); +} diff --git a/src/renderer/components/cluster-settings/components/show-metrics.tsx b/src/renderer/components/cluster-settings/components/cluster-show-metrics.tsx similarity index 100% rename from src/renderer/components/cluster-settings/components/show-metrics.tsx rename to src/renderer/components/cluster-settings/components/cluster-show-metrics.tsx diff --git a/src/renderer/components/cluster-settings/components/index.ts b/src/renderer/components/cluster-settings/components/index.ts new file mode 100644 index 0000000000..66a64def62 --- /dev/null +++ b/src/renderer/components/cluster-settings/components/index.ts @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +export * from "./cluster-accessible-namespaces"; +export * from "./cluster-home-dir-setting"; +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"; diff --git a/src/renderer/components/cluster-settings/index.ts b/src/renderer/components/cluster-settings/index.ts index 752856c9ed..f69a8e86f5 100644 --- a/src/renderer/components/cluster-settings/index.ts +++ b/src/renderer/components/cluster-settings/index.ts @@ -20,4 +20,3 @@ */ export * from "./cluster-settings"; -export * from "./cluster-settings.command"; diff --git a/src/renderer/components/command-palette/command-container.tsx b/src/renderer/components/command-palette/command-container.tsx index 120c570c77..b41edd42bb 100644 --- a/src/renderer/components/command-palette/command-container.tsx +++ b/src/renderer/components/command-palette/command-container.tsx @@ -28,9 +28,9 @@ import { Dialog } from "../dialog"; import { EventEmitter } from "../../../common/event-emitter"; import { subscribeToBroadcast } from "../../../common/ipc"; import { CommandDialog } from "./command-dialog"; -import { CommandRegistration, commandRegistry } from "../../../extensions/registries/command-registry"; import type { ClusterId } from "../../../common/cluster-store"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; +import { CommandRegistration, CommandRegistry } from "../../../extensions/registries/command-registry"; export type CommandDialogEvent = { component: React.ReactElement @@ -74,7 +74,7 @@ export class CommandContainer extends React.Component { } private findCommandById(commandId: string) { - return commandRegistry.getItems().find((command) => command.id === commandId); + return CommandRegistry.getInstance().getItems().find((command) => command.id === commandId); } private runCommand(command: CommandRegistration) { diff --git a/src/renderer/components/command-palette/command-dialog.tsx b/src/renderer/components/command-palette/command-dialog.tsx index ce718ce961..7fc5c56dcf 100644 --- a/src/renderer/components/command-palette/command-dialog.tsx +++ b/src/renderer/components/command-palette/command-dialog.tsx @@ -24,7 +24,7 @@ import { Select } from "../select"; import { computed, makeObservable, observable } from "mobx"; import { observer } from "mobx-react"; import React from "react"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; +import { CommandRegistry } from "../../../extensions/registries/command-registry"; import { CommandOverlay } from "./command-container"; import { broadcastMessage } from "../../../common/ipc"; import { navigate } from "../../navigation"; @@ -46,33 +46,35 @@ export class CommandDialog extends React.Component { } @computed get options() { + const registry = CommandRegistry.getInstance(); + const context = { entity: this.activeEntity }; - return commandRegistry.getItems().filter((command) => { + return registry.getItems().filter((command) => { if (command.scope === "entity" && !this.activeEntity) { return false; } - if (!command.isActive) { - return true; - } - try { - return command.isActive(context); + return command.isActive?.(context) ?? true; } catch(e) { console.error(e); - - return false; } - }).map((command) => { - return { value: command.id, label: command.title }; - }).sort((a, b) => a.label > b.label ? 1 : -1); + + return false; + }) + .map((command) => ({ + value: command.id, + label: command.title, + })) + .sort((a, b) => a.label > b.label ? 1 : -1); } private onChange(value: string) { - const command = commandRegistry.getItems().find((cmd) => cmd.id === value); + const registry = CommandRegistry.getInstance(); + const command = registry.getItems().find((cmd) => cmd.id === value); if (!command) { return; diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index 21e167ac8c..c3c4ca520b 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -39,7 +39,6 @@ import { Logs } from "./logs"; import { TerminalWindow } from "./terminal-window"; import { createTerminalTab } from "./terminal.store"; import { UpgradeChart } from "./upgrade-chart"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; interface Props { className?: string; @@ -161,11 +160,3 @@ export class Dock extends React.Component { ); } } - -commandRegistry.add({ - id: "cluster.openTerminal", - title: "Cluster: Open terminal", - scope: "entity", - action: () => createTerminalTab(), - isActive: (context) => !!context.entity -}); diff --git a/src/renderer/components/hotbar/hotbar-cell.tsx b/src/renderer/components/hotbar/hotbar-cell.tsx index e22eed14f0..d9a91d3d55 100644 --- a/src/renderer/components/hotbar/hotbar-cell.tsx +++ b/src/renderer/components/hotbar/hotbar-cell.tsx @@ -19,7 +19,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import "./hotbar-menu.scss"; -import "./hotbar.commands"; import React, { HTMLAttributes, ReactNode, useState } from "react"; diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx index 68d93b1675..51f489a537 100644 --- a/src/renderer/components/hotbar/hotbar-menu.tsx +++ b/src/renderer/components/hotbar/hotbar-menu.tsx @@ -20,7 +20,6 @@ */ import "./hotbar-menu.scss"; -import "./hotbar.commands"; import React from "react"; import { observer } from "mobx-react"; diff --git a/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx b/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx index bf700b871c..ebde73f894 100644 --- a/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx +++ b/src/renderer/components/kube-object-status-icon/kube-object-status-icon.tsx @@ -25,7 +25,7 @@ import React from "react"; import { Icon } from "../icon"; import { cssNames, formatDuration } from "../../utils"; import { KubeObject, KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api"; -import { kubeObjectStatusRegistry } from "../../../extensions/registries"; +import { KubeObjectStatusRegistry } from "../../../extensions/registries"; function statusClassName(level: KubeObjectStatusLevel): string { switch (level) { @@ -105,7 +105,7 @@ export class KubeObjectStatusIcon extends React.Component { } render() { - const statuses = kubeObjectStatusRegistry.getItemsForObject(this.props.object); + const statuses = KubeObjectStatusRegistry.getInstance().getItemsForObject(this.props.object); if (statuses.length === 0) { return null; diff --git a/src/renderer/components/kube-object/kube-object-details.tsx b/src/renderer/components/kube-object/kube-object-details.tsx index 217c7c25c8..8098f77064 100644 --- a/src/renderer/components/kube-object/kube-object-details.tsx +++ b/src/renderer/components/kube-object/kube-object-details.tsx @@ -32,7 +32,8 @@ import { apiManager } from "../../api/api-manager"; import { crdStore } from "../+custom-resources/crd.store"; import { CrdResourceDetails } from "../+custom-resources"; import { KubeObjectMenu } from "./kube-object-menu"; -import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; +import type { CustomResourceDefinition } from "../../api/endpoints"; +import { KubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; /** * Used to store `object.selfLink` to show more info about resource in the details panel. @@ -139,20 +140,33 @@ export class KubeObjectDetails extends React.Component { render() { const { object, isLoading, loadingError, isCrdInstance } = this; const isOpen = !!(object || isLoading || loadingError); - let title = ""; - let details: React.ReactNode[]; - if (object) { - const { kind, getName } = object; + if (!object) { + return ( + } + onClose={hideDetails} + > + {isLoading && } + {loadingError &&
    {loadingError}
    } +
    + ); + } - title = `${kind}: ${getName()}`; - details = kubeObjectDetailRegistry.getItemsForKind(object.kind, object.apiVersion).map((item, index) => { - return ; - }); + const { kind, getName } = object; + const title = `${kind}: ${getName()}`; + const details = KubeObjectDetailRegistry + .getInstance() + .getItemsForKind(object.kind, object.apiVersion) + .map((item, index) => ( + + )); - if (isCrdInstance && details.length === 0) { - details.push(); - } + if (isCrdInstance && details.length === 0) { + details.push(); } return ( diff --git a/src/renderer/components/kube-object/kube-object-menu.tsx b/src/renderer/components/kube-object/kube-object-menu.tsx index b2404febeb..da576fcba0 100644 --- a/src/renderer/components/kube-object/kube-object-menu.tsx +++ b/src/renderer/components/kube-object/kube-object-menu.tsx @@ -26,7 +26,7 @@ import { editResourceTab } from "../dock/edit-resource.store"; import { MenuActions, MenuActionsProps } from "../menu/menu-actions"; import { hideDetails } from "./kube-object-details"; import { apiManager } from "../../api/api-manager"; -import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; +import { KubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry"; export interface KubeObjectMenuProps extends MenuActionsProps { object: T | null | undefined; @@ -88,7 +88,8 @@ export class KubeObjectMenu extends React.Component ( { return routes; } - clusterPageMenuRegistry.getSubItems(menu).forEach((subMenu) => { - const subPage = clusterPageRegistry.getByPageTarget(subMenu.target); + ClusterPageMenuRegistry.getInstance().getSubItems(menu).forEach((subMenu) => { + const subPage = ClusterPageRegistry.getInstance().getByPageTarget(subMenu.target); if (subPage) { const { extensionId, id: pageId } = subPage; @@ -127,8 +127,8 @@ export class Sidebar extends React.Component { } renderRegisteredMenus() { - return clusterPageMenuRegistry.getRootItems().map((menuItem, index) => { - const registeredPage = clusterPageRegistry.getByPageTarget(menuItem.target); + return ClusterPageMenuRegistry.getInstance().getRootItems().map((menuItem, index) => { + const registeredPage = ClusterPageRegistry.getInstance().getByPageTarget(menuItem.target); const tabRoutes = this.getTabLayoutRoutes(menuItem); const id = `registered-item-${index}`; let pageUrl: string; diff --git a/src/renderer/initializers/command-registry.tsx b/src/renderer/initializers/command-registry.tsx new file mode 100644 index 0000000000..a747037a57 --- /dev/null +++ b/src/renderer/initializers/command-registry.tsx @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import React from "react"; +import * as routes from "../../common/routes"; +import { CommandRegistry } from "../../extensions/registries"; +import { getActiveClusterEntity } from "../api/catalog-entity-registry"; +import { CommandOverlay } from "../components/command-palette"; +import { createTerminalTab } from "../components/dock/terminal.store"; +import { HotbarAddCommand } from "../components/hotbar/hotbar-add-command"; +import { HotbarRemoveCommand } from "../components/hotbar/hotbar-remove-command"; +import { HotbarSwitchCommand } from "../components/hotbar/hotbar-switch-command"; +import { navigate } from "../navigation"; + +export function initCommandRegistry() { + CommandRegistry.getInstance() + .add([ + { + id: "app.showPreferences", + title: "Preferences: Open", + scope: "global", + action: () => navigate(routes.preferencesURL()) + }, + { + id: "cluster.viewHelmCharts", + title: "Cluster: View Helm Charts", + scope: "entity", + action: () => navigate(routes.helmChartsURL()) + }, + { + id: "cluster.viewHelmReleases", + title: "Cluster: View Helm Releases", + scope: "entity", + action: () => navigate(routes.releaseURL()) + }, + { + id: "cluster.viewConfigMaps", + title: "Cluster: View ConfigMaps", + scope: "entity", + action: () => navigate(routes.configMapsURL()) + }, + { + id: "cluster.viewSecrets", + title: "Cluster: View Secrets", + scope: "entity", + action: () => navigate(routes.secretsURL()) + }, + { + id: "cluster.viewResourceQuotas", + title: "Cluster: View ResourceQuotas", + scope: "entity", + action: () => navigate(routes.resourceQuotaURL()) + }, + { + id: "cluster.viewLimitRanges", + title: "Cluster: View LimitRanges", + scope: "entity", + action: () => navigate(routes.limitRangeURL()) + }, + { + id: "cluster.viewHorizontalPodAutoscalers", + title: "Cluster: View HorizontalPodAutoscalers (HPA)", + scope: "entity", + action: () => navigate(routes.hpaURL()) + }, + { + id: "cluster.viewPodDisruptionBudget", + title: "Cluster: View PodDisruptionBudgets", + scope: "entity", + action: () => navigate(routes.pdbURL()) + }, + { + id: "cluster.viewServices", + title: "Cluster: View Services", + scope: "entity", + action: () => navigate(routes.servicesURL()) + }, + { + id: "cluster.viewEndpoints", + title: "Cluster: View Endpoints", + scope: "entity", + action: () => navigate(routes.endpointURL()) + }, + { + id: "cluster.viewIngresses", + title: "Cluster: View Ingresses", + scope: "entity", + action: () => navigate(routes.ingressURL()) + }, + { + id: "cluster.viewNetworkPolicies", + title: "Cluster: View NetworkPolicies", + scope: "entity", + action: () => navigate(routes.networkPoliciesURL()) + }, + { + id: "cluster.viewNodes", + title: "Cluster: View Nodes", + scope: "entity", + action: () => navigate(routes.nodesURL()) + }, + { + id: "cluster.viewPods", + title: "Cluster: View Pods", + scope: "entity", + action: () => navigate(routes.podsURL()) + }, + { + id: "cluster.viewDeployments", + title: "Cluster: View Deployments", + scope: "entity", + action: () => navigate(routes.deploymentsURL()) + }, + { + id: "cluster.viewDaemonSets", + title: "Cluster: View DaemonSets", + scope: "entity", + action: () => navigate(routes.daemonSetsURL()) + }, + { + id: "cluster.viewStatefulSets", + title: "Cluster: View StatefulSets", + scope: "entity", + action: () => navigate(routes.statefulSetsURL()) + }, + { + id: "cluster.viewJobs", + title: "Cluster: View Jobs", + scope: "entity", + action: () => navigate(routes.jobsURL()) + }, + { + id: "cluster.viewCronJobs", + title: "Cluster: View CronJobs", + scope: "entity", + action: () => navigate(routes.cronJobsURL()) + }, + { + id: "cluster.viewCurrentClusterSettings", + title: "Cluster: View Settings", + scope: "global", + action: () => navigate(routes.entitySettingsURL({ + params: { + entityId: getActiveClusterEntity()?.id, + } + })), + isActive: (context) => !!context.entity + }, + { + id: "cluster.openTerminal", + title: "Cluster: Open terminal", + scope: "entity", + action: () => createTerminalTab(), + isActive: (context) => !!context.entity + }, + { + id: "hotbar.switchHotbar", + title: "Hotbar: Switch ...", + scope: "global", + action: () => CommandOverlay.open() + }, + { + id: "hotbar.addHotbar", + title: "Hotbar: Add Hotbar ...", + scope: "global", + action: () => CommandOverlay.open() + }, + { + id: "hotbar.removeHotbar", + title: "Hotbar: Remove Hotbar ...", + scope: "global", + action: () => CommandOverlay.open() + }, + ]); +} diff --git a/src/renderer/initializers/entity-settings-registry.ts b/src/renderer/initializers/entity-settings-registry.ts new file mode 100644 index 0000000000..e7203ca97b --- /dev/null +++ b/src/renderer/initializers/entity-settings-registry.ts @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { 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", + components: { + View: clusterSettings.GeneralSettings, + } + }, + { + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Proxy", + components: { + View: clusterSettings.ProxySettings, + } + }, + { + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Terminal", + components: { + View: clusterSettings.TerminalSettings, + } + }, + { + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Namespaces", + components: { + View: clusterSettings.NamespacesSettings, + } + }, + { + apiVersions: ["entity.k8slens.dev/v1alpha1"], + kind: "KubernetesCluster", + title: "Metrics", + components: { + View: clusterSettings.MetricsSettings, + } + } + ]); +} diff --git a/src/renderer/initializers/index.ts b/src/renderer/initializers/index.ts new file mode 100644 index 0000000000..a5cbb49257 --- /dev/null +++ b/src/renderer/initializers/index.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +export * from "./command-registry"; +export * from "./entity-settings-registry"; +export * from "./kube-object-detail-registry"; +export * from "./kube-object-menu-registry"; +export * from "./registries"; +export * from "./welcome-menu-registry"; +export * from "./workloads-overview-detail-registry"; diff --git a/src/renderer/initializers/kube-object-detail-registry.tsx b/src/renderer/initializers/kube-object-detail-registry.tsx new file mode 100644 index 0000000000..56e88ac3d9 --- /dev/null +++ b/src/renderer/initializers/kube-object-detail-registry.tsx @@ -0,0 +1,449 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import React from "react"; +import type * as endpoints from "../api/endpoints"; +import type { KubeObject } from "../api/kube-object"; +import { KubeObjectDetailRegistry } from "../api/kube-object-detail-registry"; +import { HpaDetails } from "../components/+config-autoscalers"; +import { LimitRangeDetails } from "../components/+config-limit-ranges"; +import { ConfigMapDetails } from "../components/+config-maps"; +import { PodDisruptionBudgetDetails } from "../components/+config-pod-disruption-budgets"; +import { ResourceQuotaDetails } from "../components/+config-resource-quotas"; +import { SecretDetails } from "../components/+config-secrets"; +import { CRDDetails } from "../components/+custom-resources"; +import { EventDetails } from "../components/+events"; +import { KubeEventDetails } from "../components/+events/kube-event-details"; +import { NamespaceDetails } from "../components/+namespaces"; +import { EndpointDetails } from "../components/+network-endpoints"; +import { IngressDetails } from "../components/+network-ingresses"; +import { NetworkPolicyDetails } from "../components/+network-policies"; +import { ServiceDetails } from "../components/+network-services"; +import { NodeDetails } from "../components/+nodes"; +import { PodSecurityPolicyDetails } from "../components/+pod-security-policies"; +import { StorageClassDetails } from "../components/+storage-classes"; +import { PersistentVolumeClaimDetails } from "../components/+storage-volume-claims"; +import { PersistentVolumeDetails } from "../components/+storage-volumes"; +import { ClusterRoleDetails } from "../components/+user-management/+cluster-roles"; +import { ClusterRoleBindingDetails } from "../components/+user-management/+cluster-role-bindings"; +import { RoleDetails } from "../components/+user-management/+roles"; +import { RoleBindingDetails } from "../components/+user-management/+role-bindings"; +import { ServiceAccountsDetails } from "../components/+user-management/+service-accounts"; +import { CronJobDetails } from "../components/+workloads-cronjobs"; +import { DaemonSetDetails } from "../components/+workloads-daemonsets"; +import { DeploymentDetails } from "../components/+workloads-deployments"; +import { JobDetails } from "../components/+workloads-jobs"; +import { PodDetails } from "../components/+workloads-pods"; +import { ReplicaSetDetails } from "../components/+workloads-replicasets"; +import { StatefulSetDetails } from "../components/+workloads-statefulsets"; +import type { KubeObjectDetailsProps } from "../components/kube-object"; + +export function intiKubeObjectDetailRegistry() { + KubeObjectDetailRegistry.getInstance() + .add([ + { + kind: "HorizontalPodAutoscaler", + apiVersions: ["autoscaling/v2beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "HorizontalPodAutoscaler", + apiVersions: ["autoscaling/v2beta1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "LimitRange", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ConfigMap", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ConfigMap", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PodDisruptionBudget", + apiVersions: ["policy/v1beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ResourceQuota", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Secret", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "CustomResourceDefinition", + apiVersions: ["apiextensions.k8s.io/v1", "apiextensions.k8s.io/v1beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Event", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Namespace", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Endpoints", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Endpoints", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Ingress", + apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Ingress", + apiVersions: ["networking.k8s.io/v1", "extensions/v1beta1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "NetworkPolicy", + apiVersions: ["networking.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "NetworkPolicy", + apiVersions: ["networking.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Service", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Service", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Node", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Node", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PodSecurityPolicy", + apiVersions: ["policy/v1beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "StorageClass", + apiVersions: ["storage.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "StorageClass", + apiVersions: ["storage.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PersistentVolumeClaim", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PersistentVolumeClaim", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PersistentVolume", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "PersistentVolume", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Role", + apiVersions: ["rbac.authorization.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Role", + apiVersions: ["rbac.authorization.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ClusterRole", + apiVersions: ["rbac.authorization.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ClusterRole", + apiVersions: ["rbac.authorization.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "RoleBinding", + apiVersions: ["rbac.authorization.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "RoleBinding", + apiVersions: ["rbac.authorization.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ClusterRoleBinding", + apiVersions: ["rbac.authorization.k8s.io/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ClusterRoleBinding", + apiVersions: ["rbac.authorization.k8s.io/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ServiceAccount", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ServiceAccount", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "CronJob", + apiVersions: ["batch/v1beta1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "CronJob", + apiVersions: ["batch/v1beta1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "DaemonSet", + apiVersions: ["apps/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "DaemonSet", + apiVersions: ["apps/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Deployment", + apiVersions: ["apps/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Deployment", + apiVersions: ["apps/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Job", + apiVersions: ["batch/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Job", + apiVersions: ["batch/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Pod", + apiVersions: ["v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "Pod", + apiVersions: ["v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ReplicaSet", + apiVersions: ["apps/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "ReplicaSet", + apiVersions: ["apps/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "StatefulSet", + apiVersions: ["apps/v1"], + components: { + Details: (props: KubeObjectDetailsProps) => , + } + }, + { + kind: "StatefulSet", + apiVersions: ["apps/v1"], + priority: 5, + components: { + Details: (props: KubeObjectDetailsProps) => , + } + } + ]); +} diff --git a/src/renderer/initializers/kube-object-menu-registry.ts b/src/renderer/initializers/kube-object-menu-registry.ts new file mode 100644 index 0000000000..6c4ecb8e15 --- /dev/null +++ b/src/renderer/initializers/kube-object-menu-registry.ts @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { KubeObjectMenuRegistry } from "../../extensions/registries"; +import { ServiceAccountMenu } from "../components/+user-management/+service-accounts"; +import { CronJobMenu } from "../components/+workloads-cronjobs"; +import { DeploymentMenu } from "../components/+workloads-deployments"; +import { ReplicaSetMenu } from "../components/+workloads-replicasets"; +import { StatefulSetMenu } from "../components/+workloads-statefulsets"; + +export function initKubeObjectMenuRegistry() { + KubeObjectMenuRegistry.getInstance() + .add([ + { + kind: "ServiceAccount", + apiVersions: ["v1"], + components: { + MenuItem: ServiceAccountMenu, + } + }, + { + kind: "CronJob", + apiVersions: ["batch/v1beta1"], + components: { + MenuItem: CronJobMenu + } + }, + { + kind: "Deployment", + apiVersions: ["apps/v1"], + components: { + MenuItem: DeploymentMenu + } + }, + { + kind: "ReplicaSet", + apiVersions: ["apps/v1"], + components: { + MenuItem: ReplicaSetMenu + } + }, + { + kind: "StatefulSet", + apiVersions: ["apps/v1"], + components: { + MenuItem: StatefulSetMenu + } + } + ]); +} diff --git a/src/renderer/initializers/registries.ts b/src/renderer/initializers/registries.ts new file mode 100644 index 0000000000..80513a2461 --- /dev/null +++ b/src/renderer/initializers/registries.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import * as registries from "../../extensions/registries"; + +export function initRegistries() { + registries.AppPreferenceRegistry.createInstance(); + registries.CatalogEntityDetailRegistry.createInstance(); + registries.ClusterPageMenuRegistry.createInstance(); + registries.ClusterPageRegistry.createInstance(); + registries.CommandRegistry.createInstance(); + registries.EntitySettingRegistry.createInstance(); + registries.GlobalPageRegistry.createInstance(); + registries.KubeObjectDetailRegistry.createInstance(); + registries.KubeObjectMenuRegistry.createInstance(); + registries.KubeObjectStatusRegistry.createInstance(); + registries.PageMenuRegistry.createInstance(); + registries.StatusBarRegistry.createInstance(); + registries.WelcomeMenuRegistry.createInstance(); + registries.WorkloadsOverviewDetailRegistry.createInstance(); +} diff --git a/src/renderer/components/cluster-settings/cluster-settings.command.ts b/src/renderer/initializers/welcome-menu-registry.ts similarity index 67% rename from src/renderer/components/cluster-settings/cluster-settings.command.ts rename to src/renderer/initializers/welcome-menu-registry.ts index 90c0870eeb..887735b357 100644 --- a/src/renderer/components/cluster-settings/cluster-settings.command.ts +++ b/src/renderer/initializers/welcome-menu-registry.ts @@ -19,19 +19,22 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { navigate } from "../../navigation"; -import { commandRegistry } from "../../../extensions/registries/command-registry"; -import { getActiveClusterEntity } from "../../api/catalog-entity-registry"; -import { entitySettingsURL } from "../../../common/routes"; +import { catalogURL, preferencesURL } from "../../common/routes"; +import { WelcomeMenuRegistry } from "../../extensions/registries"; +import { navigate } from "../navigation"; -commandRegistry.add({ - id: "cluster.viewCurrentClusterSettings", - title: "Cluster: View Settings", - scope: "global", - action: () => navigate(entitySettingsURL({ - params: { - entityId: getActiveClusterEntity()?.id, - } - })), - isActive: (context) => !!context.entity -}); +export function initWelcomeMenuRegistry() { + WelcomeMenuRegistry.getInstance() + .add([ + { + title: "Browse Your Catalog", + icon: "view_list", + click: () => navigate(catalogURL()) + }, + { + title: "Configure Preferences", + icon: "settings", + click: () => navigate(preferencesURL()) + } + ]); +} diff --git a/src/renderer/components/hotbar/hotbar.commands.tsx b/src/renderer/initializers/workloads-overview-detail-registry.tsx similarity index 58% rename from src/renderer/components/hotbar/hotbar.commands.tsx rename to src/renderer/initializers/workloads-overview-detail-registry.tsx index 399970cd68..b374bb11af 100644 --- a/src/renderer/components/hotbar/hotbar.commands.tsx +++ b/src/renderer/initializers/workloads-overview-detail-registry.tsx @@ -20,29 +20,26 @@ */ import React from "react"; -import { commandRegistry } from "../../../extensions/registries"; -import { CommandOverlay } from "../command-palette"; -import { HotbarAddCommand } from "./hotbar-add-command"; -import { HotbarRemoveCommand } from "./hotbar-remove-command"; -import { HotbarSwitchCommand } from "./hotbar-switch-command"; +import { isAllowedResource } from "../../common/rbac"; +import { WorkloadsOverviewDetailRegistry } from "../../extensions/registries"; +import { Events } from "../components/+events"; +import { OverviewStatuses } from "../components/+workloads-overview/overview-statuses"; -commandRegistry.add({ - id: "hotbar.switchHotbar", - title: "Hotbar: Switch ...", - scope: "global", - action: () => CommandOverlay.open() -}); - -commandRegistry.add({ - id: "hotbar.addHotbar", - title: "Hotbar: Add Hotbar ...", - scope: "global", - action: () => CommandOverlay.open() -}); - -commandRegistry.add({ - id: "hotbar.removeHotbar", - title: "Hotbar: Remove Hotbar ...", - scope: "global", - action: () => CommandOverlay.open() -}); +export function initWorkloadsOverviewDetailRegistry() { + WorkloadsOverviewDetailRegistry.getInstance() + .add([ + { + components: { + Details: (props: any) => , + } + }, + { + priority: 5, + components: { + Details: () => ( + isAllowedResource("events") && + ) + } + } + ]); +} diff --git a/webpack.extensions.ts b/webpack.extensions.ts index e5a95660aa..90b20c3589 100644 --- a/webpack.extensions.ts +++ b/webpack.extensions.ts @@ -47,6 +47,7 @@ export default function generateExtensionTypes(): webpack.Configuration { optimization: { minimize: false, // speed up types compilation }, + stats: "errors-warnings", module: { rules: [ {