diff --git a/src/common/base-store.ts b/src/common/base-store.ts index 43911aff4d..f18efd3d6a 100644 --- a/src/common/base-store.ts +++ b/src/common/base-store.ts @@ -43,6 +43,8 @@ export abstract class BaseStore extends Singleton { protected storeConfig?: Config; protected syncDisposers: Disposer[] = []; + readonly displayName: string = this.constructor.name; + protected constructor(protected params: BaseStoreParams) { super(); makeObservable(this); @@ -56,6 +58,10 @@ export abstract class BaseStore extends Singleton { * This must be called after the last child's constructor is finished (or just before it finishes) */ load() { + if (!isTestEnv) { + logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADING from ${this.path} ...`); + } + this.storeConfig = new Config({ ...this.params, projectName: "lens", @@ -66,13 +72,13 @@ export abstract class BaseStore extends Singleton { const res: any = this.fromStore(this.storeConfig.store); if (res instanceof Promise || (typeof res === "object" && res && typeof res.then === "function")) { - console.error(`${this.constructor.name} extends BaseStore's fromStore method returns a Promise or promise-like object. This is an error and must be fixed.`); + console.error(`${this.displayName} extends BaseStore's fromStore method returns a Promise or promise-like object. This is an error and must be fixed.`); } this.enableSync(); if (!isTestEnv) { - logger.info(`[${kebabCase(this.constructor.name).toUpperCase()}]: LOADED from ${this.path}`); + logger.info(`[${kebabCase(this.displayName).toUpperCase()}]: LOADED from ${this.path}`); } } diff --git a/src/common/cluster-store.ts b/src/common/cluster-store.ts index d5dfdadfd1..a3dbc97645 100644 --- a/src/common/cluster-store.ts +++ b/src/common/cluster-store.ts @@ -37,6 +37,7 @@ export interface ClusterStoreModel { const initialStates = "cluster:states"; export class ClusterStore extends BaseStore { + readonly displayName = "ClusterStore"; clusters = observable.map(); protected disposer = disposer(); diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts index 72705bf7bf..cce10760ca 100644 --- a/src/common/hotbar-store.ts +++ b/src/common/hotbar-store.ts @@ -35,6 +35,7 @@ export interface HotbarStoreModel { } export class HotbarStore extends BaseStore { + readonly displayName = "HotbarStore"; @observable hotbars: Hotbar[] = []; @observable private _activeHotbarId: string; diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index ffe9b2f289..3de94113d6 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -39,6 +39,7 @@ export interface UserStoreModel { } export class UserStore extends BaseStore /* implements UserStoreFlatModel (when strict null is enabled) */ { + readonly displayName = "UserStore"; constructor() { super({ configName: "lens-user-store", diff --git a/src/common/weblink-store.ts b/src/common/weblink-store.ts index 59940c2def..89c16c54ea 100644 --- a/src/common/weblink-store.ts +++ b/src/common/weblink-store.ts @@ -43,6 +43,7 @@ export interface WeblinkStoreModel { } export class WeblinkStore extends BaseStore { + readonly displayName = "WeblinkStore"; @observable weblinks: WeblinkData[] = []; constructor() { diff --git a/src/extensions/extension-store.ts b/src/extensions/extension-store.ts index 6b4e9c5489..e7e0f4a227 100644 --- a/src/extensions/extension-store.ts +++ b/src/extensions/extension-store.ts @@ -24,6 +24,7 @@ import * as path from "path"; import type { LensExtension } from "./lens-extension"; export abstract class ExtensionStore extends BaseStore { + readonly displayName = "ExtensionStore"; protected extension: LensExtension; loadExtension(extension: LensExtension) { diff --git a/src/extensions/extensions-store.ts b/src/extensions/extensions-store.ts index 681735bfbb..a69587e95d 100644 --- a/src/extensions/extensions-store.ts +++ b/src/extensions/extensions-store.ts @@ -34,6 +34,7 @@ export interface LensExtensionState { } export class ExtensionsStore extends BaseStore { + readonly displayName = "ExtensionsStore"; constructor() { super({ configName: "lens-extensions", diff --git a/src/main/extension-filesystem.ts b/src/main/extension-filesystem.ts index 97c8bf06a3..cc49a0b706 100644 --- a/src/main/extension-filesystem.ts +++ b/src/main/extension-filesystem.ts @@ -34,6 +34,7 @@ interface FSProvisionModel { } export class FilesystemProvisionerStore extends BaseStore { + readonly displayName = "FilesystemProvisionerStore"; registeredExtensions = observable.map(); constructor() { diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index ab19e5a64a..90e8c7fa95 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -40,6 +40,7 @@ import { ExtensionInstallationStateStore } from "./components/+extensions/extens import { DefaultProps } from "./mui-base-theme"; import configurePackages from "../common/configure-packages"; import * as initializers from "./initializers"; +import logger from "../common/logger"; import { HotbarStore } from "../common/hotbar-store"; import { WeblinkStore } from "../common/weblink-store"; import { ExtensionsStore } from "../extensions/extensions-store"; @@ -69,37 +70,59 @@ async function attachChromeDebugger() { } type AppComponent = React.ComponentType & { - init?(rootElem: HTMLElement): Promise; + init(rootElem: HTMLElement): Promise; }; export async function bootstrap(comp: () => Promise) { - await AppPaths.init(); const rootElem = document.getElementById("app"); + const logPrefix = `[BOOTSTRAP-${process.isMainFrame ? "ROOT" : "CLUSTER"}-FRAME]:`; + await AppPaths.init(); UserStore.createInstance(); await attachChromeDebugger(); rootElem.classList.toggle("is-mac", isMac); + logger.info(`${logPrefix} initializing Registries`); initializers.initRegistries(); + + logger.info(`${logPrefix} initializing CommandRegistry`); initializers.initCommandRegistry(); + + logger.info(`${logPrefix} initializing EntitySettingsRegistry`); initializers.initEntitySettingsRegistry(); + + logger.info(`${logPrefix} initializing KubeObjectMenuRegistry`); initializers.initKubeObjectMenuRegistry(); - initializers.intiKubeObjectDetailRegistry(); + + logger.info(`${logPrefix} initializing KubeObjectDetailRegistry`); + initializers.initKubeObjectDetailRegistry(); + + logger.info(`${logPrefix} initializing WelcomeMenuRegistry`); initializers.initWelcomeMenuRegistry(); + + logger.info(`${logPrefix} initializing WorkloadsOverviewDetailRegist`); initializers.initWorkloadsOverviewDetailRegistry(); + + logger.info(`${logPrefix} initializing CatalogEntityDetailRegistry`); initializers.initCatalogEntityDetailRegistry(); + + logger.info(`${logPrefix} initializing CatalogCategoryRegistryEntrie`); initializers.initCatalogCategoryRegistryEntries(); + + logger.info(`${logPrefix} initializing Catalog`); initializers.initCatalog(); + + logger.info(`${logPrefix} initializing IpcRendererListeners`); initializers.initIpcRendererListeners(); ExtensionLoader.createInstance().init(); ExtensionDiscovery.createInstance().init(); // ClusterStore depends on: UserStore - const cs = ClusterStore.createInstance(); + const clusterStore = ClusterStore.createInstance(); - await cs.loadInitialOnRenderer(); + await clusterStore.loadInitialOnRenderer(); // HotbarStore depends on: ClusterStore HotbarStore.createInstance(); @@ -117,7 +140,7 @@ export async function bootstrap(comp: () => Promise) { HelmRepoManager.createInstance(); // initialize the manager // Register additional store listeners - cs.registerIpcListener(); + clusterStore.registerIpcListener(); // init app's dependencies if any const App = await comp(); @@ -133,8 +156,8 @@ export async function bootstrap(comp: () => Promise) { // run bootstrap( async () => process.isMainFrame - ? (await import("./lens-app")).LensApp - : (await import("./components/app")).App, + ? (await import("./root-frame")).RootFrame + : (await import("./cluster-frame")).ClusterFrame, ); diff --git a/src/renderer/components/app.tsx b/src/renderer/cluster-frame.tsx similarity index 60% rename from src/renderer/components/app.tsx rename to src/renderer/cluster-frame.tsx index 4de3cf85c2..0786ca18a5 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/cluster-frame.tsx @@ -22,61 +22,63 @@ import React from "react"; import { observable, makeObservable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import { Redirect, Route, Router, Switch } from "react-router"; -import { history } from "../navigation"; -import { NotFound } from "./+404"; -import { UserManagement } from "./+user-management/user-management"; -import { ConfirmDialog } from "./confirm-dialog"; -import { ClusterOverview } from "./+cluster/cluster-overview"; -import { Events } from "./+events/events"; -import { DeploymentScaleDialog } from "./+workloads-deployments/deployment-scale-dialog"; -import { CronJobTriggerDialog } from "./+workloads-cronjobs/cronjob-trigger-dialog"; -import { CustomResources } from "./+custom-resources/custom-resources"; -import { isAllowedResource } from "../../common/utils/allowed-resource"; -import logger from "../../main/logger"; +import { history } from "./navigation"; +import { NotFound } from "./components/+404"; +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 logger from "../main/logger"; import { webFrame } from "electron"; -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 { 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 { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog"; -import { kubeWatchApi } from "../../common/k8s-api/kube-watch-api"; -import { ReplicaSetScaleDialog } from "./+workloads-replicasets/replicaset-scale-dialog"; -import { CommandContainer } from "./command-palette/command-container"; -import { KubeObjectStore } from "../../common/k8s-api/kube-object.store"; -import { clusterContext } from "./context"; -import * as routes from "../../common/routes"; -import { TabLayout, TabLayoutRoute } from "./layout/tab-layout"; -import { ErrorBoundary } from "./error-boundary"; -import { MainLayout } from "./layout/main-layout"; -import { Notifications } from "./notifications"; -import { KubeObjectDetails } from "./kube-object-details"; -import { KubeConfigDialog } from "./kubeconfig-dialog"; -import { Terminal } from "./dock/terminal"; -import { namespaceStore } from "./+namespaces/namespace.store"; -import { Sidebar } from "./layout/sidebar"; -import { Dock } from "./dock"; -import { Apps } from "./+apps"; -import { Namespaces } from "./+namespaces"; -import { Network } from "./+network"; -import { Nodes } from "./+nodes"; -import { Workloads } from "./+workloads"; -import { Config } from "./+config"; -import { Storage } from "./+storage"; -import { catalogEntityRegistry } from "../api/catalog-entity-registry"; -import { getHostedClusterId } from "../utils"; -import { ClusterStore } from "../../common/cluster-store"; -import type { ClusterId } from "../../common/cluster-types"; -import { watchHistoryState } from "../remote-helpers/history-updater"; +import { clusterSetFrameIdHandler } from "../common/cluster-ipc"; +import { ClusterPageMenuRegistration, ClusterPageMenuRegistry } from "../extensions/registries"; +import { StatefulSetScaleDialog } from "./components/+workloads-statefulsets/statefulset-scale-dialog"; +import { kubeWatchApi } from "../common/k8s-api/kube-watch-api"; +import { ReplicaSetScaleDialog } from "./components/+workloads-replicasets/replicaset-scale-dialog"; +import { CommandContainer } from "./components/command-palette/command-container"; +import { KubeObjectStore } from "../common/k8s-api/kube-object.store"; +import { clusterContext } from "./components/context"; +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 { Terminal } from "./components/dock/terminal"; +import { namespaceStore } from "./components/+namespaces/namespace.store"; +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 { catalogEntityRegistry } from "./api/catalog-entity-registry"; +import { getHostedClusterId } from "./utils"; +import { ClusterStore } from "../common/cluster-store"; +import type { ClusterId } from "../common/cluster-types"; +import { watchHistoryState } from "./remote-helpers/history-updater"; import { unmountComponentAtNode } from "react-dom"; -import { PortForwardDialog } from "../port-forward"; -import { DeleteClusterDialog } from "./delete-cluster-dialog"; +import { PortForwardDialog } from "./port-forward"; +import { DeleteClusterDialog } from "./components/delete-cluster-dialog"; @observer -export class App extends React.Component { +export class ClusterFrame extends React.Component { static clusterId: ClusterId; + static readonly logPrefix = "[CLUSTER-FRAME]:"; + static displayName = "ClusterFrame"; constructor(props: {}) { super(props); @@ -87,17 +89,14 @@ export class App extends React.Component { catalogEntityRegistry.init(); const frameId = webFrame.routingId; - App.clusterId = getHostedClusterId(); + ClusterFrame.clusterId = getHostedClusterId(); - logger.info(`[APP]: Init dashboard, clusterId=${App.clusterId}, frameId=${frameId}`); + logger.info(`${ClusterFrame.logPrefix} Init dashboard, clusterId=${ClusterFrame.clusterId}, frameId=${frameId}`); await Terminal.preloadFonts(); - await requestMain(clusterSetFrameIdHandler, App.clusterId); + await requestMain(clusterSetFrameIdHandler, ClusterFrame.clusterId); + await ClusterStore.getInstance().getById(ClusterFrame.clusterId).whenReady; // cluster.activate() is done at this point - const cluster = ClusterStore.getInstance().getById(App.clusterId); - - await cluster.whenReady; // cluster.activate() is done at this point - - catalogEntityRegistry.activeEntity = App.clusterId; + catalogEntityRegistry.activeEntity = ClusterFrame.clusterId; ExtensionLoader.getInstance().loadOnClusterRenderer(); setTimeout(() => { @@ -105,7 +104,7 @@ export class App extends React.Component { name: "cluster", action: "open", params: { - clusterId: App.clusterId, + clusterId: ClusterFrame.clusterId, }, }); }); @@ -114,7 +113,7 @@ export class App extends React.Component { }); window.onbeforeunload = () => { - logger.info(`[APP]: Unload dashboard, clusterId=${App.clusterId}, frameId=${frameId}`); + logger.info(`${ClusterFrame.logPrefix} Unload dashboard, clusterId=${ClusterFrame.clusterId}, frameId=${frameId}`); unmountComponentAtNode(rootElem); }; @@ -225,7 +224,7 @@ export class App extends React.Component { - + ); diff --git a/src/renderer/initializers/kube-object-detail-registry.tsx b/src/renderer/initializers/kube-object-detail-registry.tsx index 86e8b2754f..00be5110ea 100644 --- a/src/renderer/initializers/kube-object-detail-registry.tsx +++ b/src/renderer/initializers/kube-object-detail-registry.tsx @@ -54,7 +54,7 @@ import { ReplicaSetDetails } from "../components/+workloads-replicasets"; import { StatefulSetDetails } from "../components/+workloads-statefulsets"; import type { KubeObjectDetailsProps } from "../components/kube-object-details"; -export function intiKubeObjectDetailRegistry() { +export function initKubeObjectDetailRegistry() { KubeObjectDetailRegistry.getInstance() .add([ { diff --git a/src/renderer/lens-app.tsx b/src/renderer/root-frame.tsx similarity index 92% rename from src/renderer/lens-app.tsx rename to src/renderer/root-frame.tsx index 17322e9a01..5fd3051b64 100644 --- a/src/renderer/lens-app.tsx +++ b/src/renderer/root-frame.tsx @@ -43,7 +43,10 @@ import { ClusterFrameHandler } from "./components/cluster-manager/lens-views"; injectSystemCAs(); @observer -export class LensApp extends React.Component { +export class RootFrame extends React.Component { + static readonly logPrefix = "[ROOT-FRAME]:"; + static displayName = "RootFrame"; + static async init(rootElem: HTMLElement) { catalogEntityRegistry.init(); ExtensionLoader.getInstance().loadOnClusterManagerRenderer(); @@ -55,11 +58,10 @@ export class LensApp extends React.Component { registerIpcListeners(); - window.onbeforeunload = () => { - logger.info("[App]: Unload app"); - + window.addEventListener("beforeunload", () => { + logger.info(`${RootFrame.logPrefix} Unload app`); unmountComponentAtNode(rootElem); - }; + }); } constructor(props: {}) {