`;
-exports[`welcome - navigation using application menu when navigating to welcome using application menu renders 1`] = `
+exports[`welcome - navigation using application menu when navigated somewhere else renders 1`] = `
+
+
+
+`;
+
+exports[`welcome - navigation using application menu when navigated somewhere else when navigated to welcome using application menu renders 1`] = `
-
-
- home
-
-
-
-
- arrow_back
-
-
-
-
- arrow_forward
-
-
-
-
-
-
-
-
- No new updates available
-
+
+ home
+
+
+
+
+ arrow_back
+
+
+
+
+ arrow_forward
+
+
-
-
-
-
-
+
+
+
-
- Welcome to OpenLens 5!
-
-
- To get you started we have auto-detected your clusters in your
-
- kubeconfig file and added them to the catalog, your centralized
-
- view for managing all your cloud-native resources.
-
-
- If you have any questions or feedback, please join our
-
- Lens Community slack channel
-
- .
-
-
-
+
+
+
-
-
+ Welcome to OpenLens 5!
+
+
+ To get you started we have auto-detected your clusters in your
+
+ kubeconfig file and added them to the catalog, your centralized
+
+ view for managing all your cloud-native resources.
+
+
+ If you have any questions or feedback, please join our
+
- view_list
-
-
-
+ .
+
+
- Browse Clusters in Catalog
-
-
-
- navigate_next
-
-
-
-
+
+
+ view_list
+
+
+
+ Browse Clusters in Catalog
+
+
+
+ navigate_next
+
+
+
+
+
+
+
+
+
+
+
+
+ arrow_left
+
+
+
+
+
+ arrow_right
+
+
+
+
+
+
+
+
+ No new updates available
+
+
+
+
{
expect(rendered.container).toMatchSnapshot();
});
- it("does not show welcome page yet", () => {
- const actual = rendered.queryByTestId("welcome-page");
+ it("shows welcome page being front page", () => {
+ const actual = rendered.getByTestId("welcome-page");
- expect(actual).toBeNull();
+ expect(actual).not.toBeNull();
});
- describe("when navigating to welcome using application menu", () => {
+ describe("when navigated somewhere else", () => {
beforeEach(() => {
- applicationBuilder.applicationMenu.click("help.welcome");
+ applicationBuilder.applicationMenu.click("root.preferences");
});
it("renders", () => {
- expect(rendered.container).toMatchSnapshot();
+ expect(rendered.baseElement).toMatchSnapshot();
});
- it("shows welcome page", () => {
- const actual = rendered.getByTestId("welcome-page");
+ it("does not show welcome page", () => {
+ const actual = rendered.queryByTestId("welcome-page");
- expect(actual).not.toBeNull();
+ expect(actual).toBeNull();
+ });
+
+ describe("when navigated to welcome using application menu", () => {
+ beforeEach(() => {
+ applicationBuilder.applicationMenu.click("help.welcome");
+ });
+
+ it("renders", () => {
+ expect(rendered.container).toMatchSnapshot();
+ });
+
+ it("shows welcome page", () => {
+ const actual = rendered.getByTestId("welcome-page");
+
+ expect(actual).not.toBeNull();
+ });
});
});
});
diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts
index c09142d83d..e6e59328ce 100644
--- a/src/main/getDiForUnitTesting.ts
+++ b/src/main/getDiForUnitTesting.ts
@@ -4,7 +4,7 @@
*/
import glob from "glob";
-import { kebabCase, memoize, noop } from "lodash/fp";
+import { kebabCase, memoize, noop, chunk } from "lodash/fp";
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
import { createContainer } from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
@@ -99,6 +99,7 @@ import updateHelmReleaseInjectable from "./helm/helm-service/update-helm-release
import waitUntilBundledExtensionsAreLoadedInjectable from "./start-main-application/lens-window/application-window/wait-until-bundled-extensions-are-loaded.injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import electronInjectable from "./utils/resolve-system-proxy/electron.injectable";
+import type { HotbarStore } from "../common/hotbars/store";
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
const {
@@ -111,15 +112,13 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
setLegacyGlobalDiForExtensionApi(di, Environments.main);
- for (const filePath of getInjectableFilePaths()) {
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- const injectableInstance = require(filePath).default;
+ const filePaths = getInjectableFilePaths();
- di.register({
- ...injectableInstance,
- aliases: [injectableInstance, ...(injectableInstance.aliases || [])],
- });
- }
+ const injectables = filePaths.map(filePath => require(filePath).default);
+
+ chunk(100)(injectables).forEach(chunkInjectables => {
+ di.register(...chunkInjectables);
+ });
di.preventSideEffects();
@@ -127,7 +126,13 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
di.override(electronInjectable, () => ({}));
di.override(waitUntilBundledExtensionsAreLoadedInjectable, () => async () => {});
di.override(getRandomIdInjectable, () => () => "some-irrelevant-random-id");
- di.override(hotbarStoreInjectable, () => ({ load: () => {} }));
+
+ di.override(hotbarStoreInjectable, () => ({
+ load: () => {},
+ getActive: () => ({ name: "some-hotbar", items: [] }),
+ getDisplayIndex: () => "0",
+ }) as unknown as HotbarStore);
+
di.override(userStoreInjectable, () => ({ startMainReactions: () => {}, extensionRegistryUrl: { customUrl: "some-custom-url" }}) as UserStore);
di.override(extensionsStoreInjectable, () => ({ isEnabled: (opts) => (void opts, false) }) as ExtensionsStore);
di.override(clusterStoreInjectable, () => ({ provideInitialFromMain: () => {}, getById: (id) => (void id, {}) as Cluster }) as ClusterStore);
diff --git a/src/renderer/components/+workloads-cronjobs/cron-job-trigger-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/+workloads-cronjobs/cron-job-trigger-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..0ab5c66241
--- /dev/null
+++ b/src/renderer/components/+workloads-cronjobs/cron-job-trigger-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const cronJobTriggerDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "cron-job-trigger-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "cron-job-trigger-dialog",
+ shouldRender: computed(() => true),
+ Component: CronJobTriggerDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default cronJobTriggerDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/+workloads-deployments/scale/deployment-scale-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/+workloads-deployments/scale/deployment-scale-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..712b5d4321
--- /dev/null
+++ b/src/renderer/components/+workloads-deployments/scale/deployment-scale-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { DeploymentScaleDialog } from "./dialog";
+import { clusterFrameChildComponentInjectionToken } from "../../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const deploymentScaleDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "deployment-scale-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "deployment-scale-dialog",
+ shouldRender: computed(() => true),
+ Component: DeploymentScaleDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default deploymentScaleDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/+workloads-replicasets/scale-dialog/replicaset-scale-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/+workloads-replicasets/scale-dialog/replicaset-scale-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..0dd5790944
--- /dev/null
+++ b/src/renderer/components/+workloads-replicasets/scale-dialog/replicaset-scale-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { clusterFrameChildComponentInjectionToken } from "../../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+import { ReplicaSetScaleDialog } from "./dialog";
+
+const replicasetScaleDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "replicaset-scale-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "replicaset-scale-dialog",
+ shouldRender: computed(() => true),
+ Component: ReplicaSetScaleDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default replicasetScaleDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/+workloads-statefulsets/scale/statefulset-scale-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/+workloads-statefulsets/scale/statefulset-scale-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..ee23dde011
--- /dev/null
+++ b/src/renderer/components/+workloads-statefulsets/scale/statefulset-scale-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { StatefulSetScaleDialog } from "./dialog";
+import { clusterFrameChildComponentInjectionToken } from "../../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const statefulsetScaleDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "statefulset-scale-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "statefulset-scale-dialog",
+ shouldRender: computed(() => true),
+ Component: StatefulSetScaleDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default statefulsetScaleDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/cluster-manager/cluster-manager-root-frame-child-component.injectable.tsx b/src/renderer/components/cluster-manager/cluster-manager-root-frame-child-component.injectable.tsx
new file mode 100644
index 0000000000..9db066e1ad
--- /dev/null
+++ b/src/renderer/components/cluster-manager/cluster-manager-root-frame-child-component.injectable.tsx
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import React from "react";
+import { getInjectable } from "@ogre-tools/injectable";
+import { rootFrameChildComponentInjectionToken } from "../../frames/root-frame/root-frame-child-component-injection-token";
+import { ClusterManager } from "./cluster-manager";
+import { computed } from "mobx";
+import { ErrorBoundary } from "../error-boundary";
+
+const clusterManagerRootFrameChildComponentInjectable = getInjectable({
+ id: "cluster-manager-root-frame-child-component",
+
+ instantiate: () => ({
+ id: "cluster-manager",
+
+ shouldRender: computed(() => true),
+
+ Component: () => (
+
+
+
+ ),
+ }),
+
+ injectionToken: rootFrameChildComponentInjectionToken,
+});
+
+export default clusterManagerRootFrameChildComponentInjectable;
diff --git a/src/renderer/components/command-palette/command-container-cluster-frame-child-component.injectable.ts b/src/renderer/components/command-palette/command-container-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..09b1ce6c53
--- /dev/null
+++ b/src/renderer/components/command-palette/command-container-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { CommandContainer } from "./command-container";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const commandContainerClusterFrameChildComponentInjectable = getInjectable({
+ id: "command-container-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "command-container",
+ shouldRender: computed(() => true),
+ Component: CommandContainer,
+ }),
+
+ causesSideEffects: true,
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+});
+
+export default commandContainerClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/command-palette/command-container-root-frame-child-component.injectable.ts b/src/renderer/components/command-palette/command-container-root-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..f6c5105cc3
--- /dev/null
+++ b/src/renderer/components/command-palette/command-container-root-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { rootFrameChildComponentInjectionToken } from "../../frames/root-frame/root-frame-child-component-injection-token";
+import { computed } from "mobx";
+import { CommandContainer } from "./command-container";
+
+const commandContainerRootFrameChildComponentInjectable = getInjectable({
+ id: "command-container-root-frame-child-component",
+
+ instantiate: () => ({
+ id: "command-container",
+ shouldRender: computed(() => true),
+ Component: CommandContainer,
+ }),
+
+ causesSideEffects: true,
+
+ injectionToken: rootFrameChildComponentInjectionToken,
+});
+
+export default commandContainerRootFrameChildComponentInjectable;
diff --git a/src/renderer/components/confirm-dialog/confirm-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/confirm-dialog/confirm-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..196d18b27f
--- /dev/null
+++ b/src/renderer/components/confirm-dialog/confirm-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { ConfirmDialog } from "./confirm-dialog";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const confirmDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "confirm-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "confirm-dialog",
+ shouldRender: computed(() => true),
+ Component: ConfirmDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+});
+
+export default confirmDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/confirm-dialog/confirm-dialog-root-frame-child-component.injectable.ts b/src/renderer/components/confirm-dialog/confirm-dialog-root-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..0132040818
--- /dev/null
+++ b/src/renderer/components/confirm-dialog/confirm-dialog-root-frame-child-component.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { rootFrameChildComponentInjectionToken } from "../../frames/root-frame/root-frame-child-component-injection-token";
+import { computed } from "mobx";
+import { ConfirmDialog } from "./confirm-dialog";
+
+const confirmDialogRootFrameChildComponentInjectable = getInjectable({
+ id: "confirm-dialog-root-frame-child-component",
+
+ instantiate: () => ({
+ id: "confirm-dialog",
+ shouldRender: computed(() => true),
+ Component: ConfirmDialog,
+ }),
+
+ injectionToken: rootFrameChildComponentInjectionToken,
+});
+
+export default confirmDialogRootFrameChildComponentInjectable;
diff --git a/src/renderer/components/delete-cluster-dialog/__tests__/delete-cluster-dialog.test.tsx b/src/renderer/components/delete-cluster-dialog/__tests__/delete-cluster-dialog.test.tsx
index 09bf3a0700..8978e00b5b 100644
--- a/src/renderer/components/delete-cluster-dialog/__tests__/delete-cluster-dialog.test.tsx
+++ b/src/renderer/components/delete-cluster-dialog/__tests__/delete-cluster-dialog.test.tsx
@@ -7,9 +7,7 @@ import { KubeConfig } from "@kubernetes/client-node";
import { fireEvent } from "@testing-library/react";
import type { RenderResult } from "@testing-library/react";
import mockFs from "mock-fs";
-import React from "react";
import * as selectEvent from "react-select-event";
-import { DeleteClusterDialog } from "../view";
import type { CreateCluster } from "../../../../common/cluster/create-cluster-injection-token";
import { createClusterInjectionToken } from "../../../../common/cluster/create-cluster-injection-token";
import createContextHandlerInjectable from "../../../../main/context-handler/create-context-handler.injectable";
@@ -19,12 +17,6 @@ import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-cre
import createKubeconfigManagerInjectable from "../../../../main/kubeconfig-manager/create-kubeconfig-manager.injectable";
import type { ApplicationBuilder } from "../../test-utils/get-application-builder";
import { getApplicationBuilder } from "../../test-utils/get-application-builder";
-import { frontEndRouteInjectionToken } from "../../../../common/front-end-routing/front-end-route-injection-token";
-import { getInjectable } from "@ogre-tools/injectable";
-import { computed } from "mobx";
-import { routeSpecificComponentInjectionToken } from "../../../routes/route-specific-component-injection-token";
-import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
-import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
import normalizedPlatformInjectable from "../../../../common/vars/normalized-platform.injectable";
import kubectlBinaryNameInjectable from "../../../../main/kubectl/binary-name.injectable";
import kubectlDownloadingNormalizedArchInjectable from "../../../../main/kubectl/normalized-arch.injectable";
@@ -111,22 +103,9 @@ describe("", () => {
mainDi.override(kubectlBinaryNameInjectable, () => "kubectl");
mainDi.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
mainDi.override(normalizedPlatformInjectable, () => "darwin");
-
- rendererDi.override(hotbarStoreInjectable, () => ({}));
rendererDi.override(storesAndApisCanBeCreatedInjectable, () => true);
});
- const { rendererDi } = applicationBuilder.dis;
-
- rendererDi.register(testRouteInjectable, testRouteComponentInjectable);
-
- applicationBuilder.beforeRender(({ rendererDi }) => {
- const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken);
- const testRoute = rendererDi.inject(testRouteInjectable);
-
- navigateToRoute(testRoute);
- });
-
mockFs();
applicationBuilder.beforeRender(({ rendererDi }) => {
@@ -321,26 +300,3 @@ describe("", () => {
});
});
});
-
-const testRouteInjectable = getInjectable({
- id: "some-test-route",
-
- instantiate: () => ({
- path: "/some-test-path",
- clusterFrame: false,
- isEnabled: computed(() => true),
- }),
-
- injectionToken: frontEndRouteInjectionToken,
-});
-
-const testRouteComponentInjectable = getInjectable({
- id: "some-test-component",
-
- instantiate: (di) => ({
- route: di.inject(testRouteInjectable),
- Component: () => ,
- }),
-
- injectionToken: routeSpecificComponentInjectionToken,
-});
diff --git a/src/renderer/components/delete-cluster-dialog/delete-cluster-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/delete-cluster-dialog/delete-cluster-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..ed91967d39
--- /dev/null
+++ b/src/renderer/components/delete-cluster-dialog/delete-cluster-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { DeleteClusterDialog } from "./view";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const deleteClusterDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "delete-cluster-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "delete-cluster-dialog",
+ shouldRender: computed(() => true),
+ Component: DeleteClusterDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default deleteClusterDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/dock/dock-tab.tsx b/src/renderer/components/dock/dock-tab.tsx
index 1e6dc64077..c988f1a696 100644
--- a/src/renderer/components/dock/dock-tab.tsx
+++ b/src/renderer/components/dock/dock-tab.tsx
@@ -14,10 +14,10 @@ import { Tab } from "../tabs";
import { Icon } from "../icon";
import { Menu, MenuItem } from "../menu";
import { observable } from "mobx";
-import { isMac } from "../../../common/vars";
import { withInjectables } from "@ogre-tools/injectable-react";
import dockStoreInjectable from "./dock/store.injectable";
import { Tooltip, TooltipPosition } from "../tooltip";
+import isMacInjectable from "../../../common/vars/is-mac.injectable";
export interface DockTabProps extends TabProps {
moreActions?: React.ReactNode;
@@ -25,6 +25,7 @@ export interface DockTabProps extends TabProps {
interface Dependencies {
dockStore: DockStore;
+ isMac: boolean;
}
@observer
@@ -73,7 +74,7 @@ class NonInjectedDockTab extends React.Component {
}
render() {
- const { className, moreActions, dockStore, active, ...tabProps } = this.props;
+ const { className, moreActions, dockStore, active, isMac, ...tabProps } = this.props;
if (!tabProps.value) {
return;
@@ -100,7 +101,7 @@ class NonInjectedDockTab extends React.Component {
@@ -124,6 +125,7 @@ class NonInjectedDockTab extends React.Component
{
export const DockTab = withInjectables(NonInjectedDockTab, {
getProps: (di, props) => ({
dockStore: di.inject(dockStoreInjectable),
+ isMac: di.inject(isMacInjectable),
...props,
}),
});
diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx
index 9e3b9e5488..05e11bf659 100644
--- a/src/renderer/components/hotbar/hotbar-menu.tsx
+++ b/src/renderer/components/hotbar/hotbar-menu.tsx
@@ -184,7 +184,9 @@ class NonInjectedHotbarMenu extends React.Component
- this.onDragStart()} onDragEnd={(result) => this.onDragEnd(result)}>
+ this.onDragStart()}
+ onDragEnd={(result) => this.onDragEnd(result)}>
{this.renderGrid()}
diff --git a/src/renderer/components/kube-object-details/kube-object-details-cluster-frame-child-component.injectable.ts b/src/renderer/components/kube-object-details/kube-object-details-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..4799ff3099
--- /dev/null
+++ b/src/renderer/components/kube-object-details/kube-object-details-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { KubeObjectDetails } from "./kube-object-details";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const kubeObjectDetailsClusterFrameChildComponentInjectable = getInjectable({
+ id: "kube-object-details-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "kube-object-details",
+ shouldRender: computed(() => true),
+ Component: KubeObjectDetails,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default kubeObjectDetailsClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable.ts b/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..796e13a063
--- /dev/null
+++ b/src/renderer/components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+import { KubeConfigDialog } from "./kubeconfig-dialog";
+
+const kubeconfigDialogClusterFrameChildComponentInjectable = getInjectable({
+ id: "kubeconfig-dialog-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "kubeconfig-dialog",
+ shouldRender: computed(() => true),
+ Component: KubeConfigDialog,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+
+ causesSideEffects: true,
+});
+
+export default kubeconfigDialogClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/notifications/notifications-cluster-frame-child-component.injectable.ts b/src/renderer/components/notifications/notifications-cluster-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..acd2e72b9e
--- /dev/null
+++ b/src/renderer/components/notifications/notifications-cluster-frame-child-component.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { computed } from "mobx";
+import { Notifications } from "./notifications";
+import { clusterFrameChildComponentInjectionToken } from "../../frames/cluster-frame/cluster-frame-child-component-injection-token";
+
+const notificationsClusterFrameChildComponentInjectable = getInjectable({
+ id: "notifications-cluster-frame-child-component",
+
+ instantiate: () => ({
+ id: "notifications",
+ shouldRender: computed(() => true),
+ Component: Notifications,
+ }),
+
+ injectionToken: clusterFrameChildComponentInjectionToken,
+});
+
+export default notificationsClusterFrameChildComponentInjectable;
diff --git a/src/renderer/components/notifications/notifications-root-frame-child-component.injectable.ts b/src/renderer/components/notifications/notifications-root-frame-child-component.injectable.ts
new file mode 100644
index 0000000000..eec5a1962a
--- /dev/null
+++ b/src/renderer/components/notifications/notifications-root-frame-child-component.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { rootFrameChildComponentInjectionToken } from "../../frames/root-frame/root-frame-child-component-injection-token";
+import { computed } from "mobx";
+import { Notifications } from "./notifications";
+
+const notificationsRootFrameChildComponentInjectable = getInjectable({
+ id: "notifications-root-frame-child-component",
+
+ instantiate: () => ({
+ id: "notifications",
+ shouldRender: computed(() => true),
+ Component: Notifications,
+ }),
+
+ injectionToken: rootFrameChildComponentInjectionToken,
+});
+
+export default notificationsRootFrameChildComponentInjectable;
diff --git a/src/renderer/components/test-utils/get-application-builder.tsx b/src/renderer/components/test-utils/get-application-builder.tsx
index 25101ae634..80a6627f50 100644
--- a/src/renderer/components/test-utils/get-application-builder.tsx
+++ b/src/renderer/components/test-utils/get-application-builder.tsx
@@ -7,21 +7,17 @@ import rendererExtensionsInjectable from "../../../extensions/renderer-extension
import currentlyInClusterFrameInjectable from "../../routes/currently-in-cluster-frame.injectable";
import type { IObservableArray, ObservableSet } from "mobx";
import { computed, observable, runInAction } from "mobx";
-import { renderFor } from "./renderFor";
import React from "react";
import { Router } from "react-router";
-import { Observer } from "mobx-react";
import subscribeStoresInjectable from "../../kube-watch-api/subscribe-stores.injectable";
import allowedResourcesInjectable from "../../cluster-frame-context/allowed-resources.injectable";
import type { RenderResult } from "@testing-library/react";
import { getByText, fireEvent } from "@testing-library/react";
import type { KubeResource } from "../../../common/rbac";
-import { Sidebar } from "../layout/sidebar";
import type { DiContainer } from "@ogre-tools/injectable";
import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable";
import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
-import currentRouteComponentInjectable from "../../routes/current-route-component.injectable";
import { pipeline } from "@ogre-tools/fp";
import { flatMap, compact, join, get, filter, map, matches, last } from "lodash/fp";
import preferenceNavigationItemsInjectable from "../+preferences/preferences-navigation/preference-navigation-items.injectable";
@@ -44,8 +40,6 @@ import historyInjectable from "../../navigation/history.injectable";
import type { MinimalTrayMenuItem } from "../../../main/tray/electron-tray/electron-tray.injectable";
import electronTrayInjectable from "../../../main/tray/electron-tray/electron-tray.injectable";
import applicationWindowInjectable from "../../../main/start-main-application/lens-window/application-window/application-window.injectable";
-import { Notifications } from "../notifications/notifications";
-import broadcastThatRootFrameIsRenderedInjectable from "../../frames/root-frame/broadcast-that-root-frame-is-rendered.injectable";
import { getDiForUnitTesting as getRendererDi } from "../../getDiForUnitTesting";
import { getDiForUnitTesting as getMainDi } from "../../../main/getDiForUnitTesting";
import { overrideChannels } from "../../../test-utils/channel-fakes/override-channels";
@@ -53,7 +47,6 @@ import trayIconPathsInjectable from "../../../main/tray/tray-icon-path.injectabl
import assert from "assert";
import { openMenu } from "react-select-event";
import userEvent from "@testing-library/user-event";
-import { StatusBar } from "../status-bar/status-bar";
import lensProxyPortInjectable from "../../../main/lens-proxy/lens-proxy-port.injectable";
import type { Route } from "../../../common/front-end-routing/front-end-route-injection-token";
import type { NavigateToRouteOptions } from "../../../common/front-end-routing/navigate-to-route-injection-token";
@@ -62,7 +55,10 @@ import type { LensMainExtension } from "../../../extensions/lens-main-extension"
import type { LensExtension } from "../../../extensions/lens-extension";
import extensionInjectable from "../../../extensions/extension-loader/extension/extension.injectable";
-import { TopBar } from "../layout/top-bar/top-bar";
+import { renderFor } from "./renderFor";
+import { RootFrame } from "../../frames/root-frame/root-frame";
+import { ClusterFrame } from "../../frames/cluster-frame/cluster-frame";
+import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable";
type Callback = (dis: DiContainers) => void | Promise;
@@ -125,10 +121,7 @@ interface DiContainers {
}
interface Environment {
- renderSidebar: () => React.ReactNode;
- renderTopBar: () => React.ReactNode;
- renderStatusBar: () => React.ReactNode;
- beforeRender: () => void;
+ RootComponent: React.ElementType;
onAllowKubeResource: () => void;
}
@@ -166,17 +159,7 @@ export const getApplicationBuilder = () => {
const environments = {
application: {
- renderSidebar: () => null,
-
- renderTopBar: () => ,
-
- renderStatusBar: () => ,
-
- beforeRender: () => {
- const nofifyThatRootFrameIsRendered = rendererDi.inject(broadcastThatRootFrameIsRenderedInjectable);
-
- nofifyThatRootFrameIsRendered();
- },
+ RootComponent: RootFrame,
onAllowKubeResource: () => {
throw new Error(
@@ -186,10 +169,7 @@ export const getApplicationBuilder = () => {
} as Environment,
clusterFrame: {
- renderSidebar: () => ,
- renderStatusBar: () => null,
- renderTopBar: () => null,
- beforeRender: () => {},
+ RootComponent: ClusterFrame,
onAllowKubeResource: () => {},
} as Environment,
};
@@ -401,6 +381,7 @@ export const getApplicationBuilder = () => {
const namespaceStoreStub = {
contextNamespaces: [],
+ items: [],
} as unknown as NamespaceStore;
const clusterFrameContextFake = new ClusterFrameContext(
@@ -413,6 +394,7 @@ export const getApplicationBuilder = () => {
rendererDi.override(namespaceStoreInjectable, () => namespaceStoreStub);
rendererDi.override(hostedClusterInjectable, () => clusterStub);
+ rendererDi.override(hostedClusterIdInjectable, () => "irrelevant-hosted-cluster-id");
rendererDi.override(clusterFrameContextInjectable, () => clusterFrameContextFake);
// Todo: get rid of global state.
@@ -474,35 +456,17 @@ export const getApplicationBuilder = () => {
await startFrame();
- const render = renderFor(rendererDi);
- const history = rendererDi.inject(historyInjectable);
- const currentRouteComponent = rendererDi.inject(currentRouteComponentInjectable);
-
for (const callback of beforeRenderCallbacks) {
await callback(dis);
}
- environment.beforeRender();
+ const history = rendererDi.inject(historyInjectable);
+
+ const render = renderFor(rendererDi);
rendered = render(
- {environment.renderSidebar()}
- {environment.renderTopBar()}
- {environment.renderStatusBar()}
-
-
- {() => {
- const Component = currentRouteComponent.get();
-
- if (!Component) {
- return null;
- }
-
- return ;
- }}
-
-
-
+
,
);
diff --git a/src/renderer/frames/cluster-frame/__snapshots__/cluster-frame.test.tsx.snap b/src/renderer/frames/cluster-frame/__snapshots__/cluster-frame.test.tsx.snap
index f4ddc5a0b7..6be63e21d3 100644
--- a/src/renderer/frames/cluster-frame/__snapshots__/cluster-frame.test.tsx.snap
+++ b/src/renderer/frames/cluster-frame/__snapshots__/cluster-frame.test.tsx.snap
@@ -2,6 +2,9 @@
exports[` given cluster with list nodes and namespaces permissions given no matching component given current url is starting url renders 1`] = `
+
given cluster with list nodes and namespaces permissio