/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import React from "react"; import { observable, makeObservable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import { Redirect, Route, Router, Switch } from "react-router"; import { UserManagement } from "../../components/+user-management/user-management"; import { ConfirmDialog } from "../../components/confirm-dialog"; import { ClusterOverview } from "../../components/+cluster/cluster-overview"; import { Events } from "../../components/+events/events"; import { DeploymentScaleDialog } from "../../components/+workloads-deployments/deployment-scale-dialog"; import { CronJobTriggerDialog } from "../../components/+workloads-cronjobs/cronjob-trigger-dialog"; import { CustomResources } from "../../components/+custom-resources/custom-resources"; import { isAllowedResource } from "../../../common/utils/allowed-resource"; import { ClusterPageRegistry, getExtensionPageUrl } from "../../../extensions/registries/page-registry"; import { ClusterPageMenuRegistration, ClusterPageMenuRegistry } from "../../../extensions/registries"; import { StatefulSetScaleDialog } from "../../components/+workloads-statefulsets/statefulset-scale-dialog"; import { ReplicaSetScaleDialog } from "../../components/+workloads-replicasets/replicaset-scale-dialog"; import { CommandContainer } from "../../components/command-palette/command-container"; import * as routes from "../../../common/routes"; import { TabLayout, TabLayoutRoute } from "../../components/layout/tab-layout"; import { ErrorBoundary } from "../../components/error-boundary"; import { MainLayout } from "../../components/layout/main-layout"; import { Notifications } from "../../components/notifications"; import { KubeObjectDetails } from "../../components/kube-object-details"; import { KubeConfigDialog } from "../../components/kubeconfig-dialog"; import { Sidebar } from "../../components/layout/sidebar"; import { Dock } from "../../components/dock"; import { Apps } from "../../components/+apps"; import { Namespaces } from "../../components/+namespaces"; import { Network } from "../../components/+network"; import { Nodes } from "../../components/+nodes"; import { Workloads } from "../../components/+workloads"; import { Config } from "../../components/+config"; import { Storage } from "../../components/+storage"; import { watchHistoryState } from "../../remote-helpers/history-updater"; import { PortForwardDialog } from "../../port-forward"; import { DeleteClusterDialog } from "../../components/delete-cluster-dialog"; import type { NamespaceStore } from "../../components/+namespaces/namespace-store/namespace.store"; import { withInjectables } from "@ogre-tools/injectable-react"; import namespaceStoreInjectable from "../../components/+namespaces/namespace-store/namespace-store.injectable"; import type { ClusterId } from "../../../common/cluster-types"; import hostedClusterInjectable from "../../../common/cluster-store/hosted-cluster/hosted-cluster.injectable"; import type { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; import type { KubeObject } from "../../../common/k8s-api/kube-object"; import type { Disposer } from "../../../common/utils"; import kubeWatchApiInjectable from "../../kube-watch-api/kube-watch-api.injectable"; import historyInjectable from "../../navigation/history.injectable"; import type { History } from "history"; interface Dependencies { history: History, namespaceStore: NamespaceStore hostedClusterId: ClusterId subscribeStores: (stores: KubeObjectStore[]) => Disposer } @observer class NonInjectedClusterFrame extends React.Component { static displayName = "ClusterFrame"; constructor(props: Dependencies) { super(props); makeObservable(this); } componentDidMount() { disposeOnUnmount(this, [ this.props.subscribeStores([ this.props.namespaceStore, ]), watchHistoryState(), ]); } @observable startUrl = isAllowedResource(["events", "nodes", "pods"]) ? routes.clusterURL() : routes.workloadsURL(); getTabLayoutRoutes(menuItem: ClusterPageMenuRegistration) { const routes: TabLayoutRoute[] = []; if (!menuItem.id) { return routes; } ClusterPageMenuRegistry.getInstance().getSubItems(menuItem).forEach((subMenu) => { const page = ClusterPageRegistry.getInstance().getByPageTarget(subMenu.target); if (page) { routes.push({ routePath: page.url, url: getExtensionPageUrl(subMenu.target), title: subMenu.title, component: page.components.Page, }); } }); return routes; } renderExtensionTabLayoutRoutes() { return ClusterPageMenuRegistry.getInstance().getRootItems().map((menu, index) => { const tabRoutes = this.getTabLayoutRoutes(menu); if (tabRoutes.length > 0) { const pageComponent = () => ; return tab.routePath)}/>; } else { const page = ClusterPageRegistry.getInstance().getByPageTarget(menu.target); if (page) { return ; } } return null; }); } renderExtensionRoutes() { return ClusterPageRegistry.getInstance().getItems().map((page, index) => { const menu = ClusterPageMenuRegistry.getInstance().getByPage(page); if (!menu) { return ; } return null; }); } render() { return ( } footer={}> {this.renderExtensionTabLayoutRoutes()} {this.renderExtensionRoutes()} { Notifications.error(`Unknown location ${location.pathname}, redirecting to main page.`); return ; }} /> ); } } export const ClusterFrame = withInjectables(NonInjectedClusterFrame, { getProps: di => ({ history: di.inject(historyInjectable), namespaceStore: di.inject(namespaceStoreInjectable), hostedClusterId: di.inject(hostedClusterInjectable).id, subscribeStores: di.inject(kubeWatchApiInjectable).subscribeStores, }), });