mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Get tests to pass
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
eb3b260cf5
commit
450ac378e1
@ -27,6 +27,7 @@ import assert from "assert";
|
|||||||
import type { Logger } from "../logger";
|
import type { Logger } from "../logger";
|
||||||
import type { ReadFileSync } from "../fs/read-file-sync.injectable";
|
import type { ReadFileSync } from "../fs/read-file-sync.injectable";
|
||||||
import type { EmitClusterConnectionUpdate } from "../../main/cluster/emit-connection-update.injectable";
|
import type { EmitClusterConnectionUpdate } from "../../main/cluster/emit-connection-update.injectable";
|
||||||
|
import type { CreateKubectl } from "../../main/kubectl/create-kubectl.injectable";
|
||||||
|
|
||||||
export interface ClusterDependencies {
|
export interface ClusterDependencies {
|
||||||
readonly directoryForKubeConfigs: string;
|
readonly directoryForKubeConfigs: string;
|
||||||
@ -34,7 +35,7 @@ export interface ClusterDependencies {
|
|||||||
readonly detectorRegistry: DetectorRegistry;
|
readonly detectorRegistry: DetectorRegistry;
|
||||||
createKubeconfigManager: (cluster: Cluster) => KubeconfigManager;
|
createKubeconfigManager: (cluster: Cluster) => KubeconfigManager;
|
||||||
createContextHandler: (cluster: Cluster) => ClusterContextHandler;
|
createContextHandler: (cluster: Cluster) => ClusterContextHandler;
|
||||||
createKubectl: (clusterVersion: string) => Kubectl;
|
createKubectl: CreateKubectl;
|
||||||
createAuthorizationReview: (config: KubeConfig) => CanI;
|
createAuthorizationReview: (config: KubeConfig) => CanI;
|
||||||
createListNamespaces: (config: KubeConfig) => ListNamespaces;
|
createListNamespaces: (config: KubeConfig) => ListNamespaces;
|
||||||
createVersionDetector: (cluster: Cluster) => VersionDetector;
|
createVersionDetector: (cluster: Cluster) => VersionDetector;
|
||||||
|
|||||||
22
src/common/cluster/get-by-id.injectable.ts
Normal file
22
src/common/cluster/get-by-id.injectable.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ClusterId } from "../cluster-types";
|
||||||
|
import type { Cluster } from "./cluster";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import clusterStoreInjectable from "../cluster-store/cluster-store.injectable";
|
||||||
|
|
||||||
|
export type GetClusterById = (id: ClusterId) => Cluster | undefined;
|
||||||
|
|
||||||
|
const getClusterByIdInjectable = getInjectable({
|
||||||
|
id: "get-cluster-by-id",
|
||||||
|
instantiate: (di): GetClusterById => {
|
||||||
|
const store = di.inject(clusterStoreInjectable);
|
||||||
|
|
||||||
|
return (id) => store.getById(id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default getClusterByIdInjectable;
|
||||||
25
src/common/cluster/set-visible-channel.injectable.ts
Normal file
25
src/common/cluster/set-visible-channel.injectable.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { ClusterId } from "../cluster-types";
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-injection-token";
|
||||||
|
|
||||||
|
export type SetVisibleClusterMessage = {
|
||||||
|
action: "set";
|
||||||
|
clusterId: ClusterId;
|
||||||
|
} | {
|
||||||
|
action: "clear";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SetVisibleClusterChannel = MessageChannel<SetVisibleClusterMessage>;
|
||||||
|
|
||||||
|
const setVisibleClusterChannelInjectable = getInjectable({
|
||||||
|
id: "set-visible-cluster-channel",
|
||||||
|
instantiate: (): SetVisibleClusterChannel => ({
|
||||||
|
id: "set-visible-cluster-channel",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setVisibleClusterChannelInjectable;
|
||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const clusterSetFrameIdHandler = "cluster:set-frame-id";
|
export const clusterSetFrameIdHandler = "cluster:set-frame-id";
|
||||||
export const clusterVisibilityHandler = "cluster:visibility";
|
|
||||||
export const clusterRefreshHandler = "cluster:refresh";
|
export const clusterRefreshHandler = "cluster:refresh";
|
||||||
export const clusterDisconnectHandler = "cluster:disconnect";
|
export const clusterDisconnectHandler = "cluster:disconnect";
|
||||||
export const clusterDeleteHandler = "cluster:delete";
|
export const clusterDeleteHandler = "cluster:delete";
|
||||||
|
|||||||
@ -67,3 +67,51 @@ exports[`cluster connection status when navigating to cluster connection renders
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`cluster connection status when navigating to cluster connection when a connection update has been broadcast for first cluster when navigating to a different cluster renders 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="StatusBar"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="leftSide"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="rightSide"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ClusterView flex column align-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="status flex column box center align-center justify-center box center"
|
||||||
|
data-testid="cluster-status"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex items-center column gaps"
|
||||||
|
>
|
||||||
|
<h2>
|
||||||
|
minikube-2
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="Spinner spinner"
|
||||||
|
/>
|
||||||
|
<pre
|
||||||
|
class="kube-auth-out"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Connecting
|
||||||
|
…
|
||||||
|
</p>
|
||||||
|
</pre>
|
||||||
|
<pre />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="Notifications flex column align-flex-end"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { RenderResult } from "@testing-library/react";
|
import type { RenderResult } from "@testing-library/react";
|
||||||
|
import type { ObservableMap } from "mobx";
|
||||||
|
import { observable } from "mobx";
|
||||||
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
|
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
|
||||||
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||||
import type { ClusterId } from "../../common/cluster-types";
|
import type { ClusterId } from "../../common/cluster-types";
|
||||||
@ -12,13 +14,20 @@ import type { NavigateToClusterView } from "../../common/front-end-routing/route
|
|||||||
import navigateToClusterViewInjectable from "../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
import navigateToClusterViewInjectable from "../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||||
import type { ReadFileSync } from "../../common/fs/read-file-sync.injectable";
|
import type { ReadFileSync } from "../../common/fs/read-file-sync.injectable";
|
||||||
import readFileSyncInjectable from "../../common/fs/read-file-sync.injectable";
|
import readFileSyncInjectable from "../../common/fs/read-file-sync.injectable";
|
||||||
|
import clusterManagerInjectable from "../../main/cluster-manager.injectable";
|
||||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import createClusterInjectable from "../../renderer/create-cluster/create-cluster.injectable";
|
import createClusterInjectable from "../../main/create-cluster/create-cluster.injectable";
|
||||||
|
import createContextHandlerInjectable from "../../main/context-handler/create-context-handler.injectable";
|
||||||
|
import createKubeconfigManagerInjectable from "../../main/kubeconfig-manager/create-kubeconfig-manager.injectable";
|
||||||
|
import createKubectlInjectable from "../../main/kubectl/create-kubectl.injectable";
|
||||||
|
import type { KubeconfigManager } from "../../main/kubeconfig-manager/kubeconfig-manager";
|
||||||
|
import type { Kubectl } from "../../main/kubectl/kubectl";
|
||||||
|
import type { ContextHandler } from "../../main/context-handler/context-handler";
|
||||||
|
|
||||||
describe("cluster connection status", () => {
|
describe("cluster connection status", () => {
|
||||||
let clusterStore: ClusterStore;
|
let clusterStore: ClusterStore;
|
||||||
let clusters: Map<ClusterId, Cluster>;
|
let clusters: ObservableMap<ClusterId, Cluster>;
|
||||||
let cluster: Cluster;
|
let cluster: Cluster;
|
||||||
let cluster2: Cluster;
|
let cluster2: Cluster;
|
||||||
let applicationBuilder: ApplicationBuilder;
|
let applicationBuilder: ApplicationBuilder;
|
||||||
@ -64,8 +73,14 @@ describe("cluster connection status", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
applicationBuilder.dis.rendererDi.override(readFileSyncInjectable, () => readFileSyncMock);
|
applicationBuilder.dis.rendererDi.override(readFileSyncInjectable, () => readFileSyncMock);
|
||||||
|
applicationBuilder.dis.mainDi.override(readFileSyncInjectable, () => readFileSyncMock);
|
||||||
|
applicationBuilder.dis.mainDi.override(clusterManagerInjectable, () => ({}));
|
||||||
|
applicationBuilder.dis.mainDi.override(createKubeconfigManagerInjectable, () => () => ({} as KubeconfigManager));
|
||||||
|
applicationBuilder.dis.mainDi.override(createKubectlInjectable, () => () => ({} as Kubectl));
|
||||||
|
applicationBuilder.dis.mainDi.override(createContextHandlerInjectable, () => () => ({} as ContextHandler));
|
||||||
|
|
||||||
applicationBuilder.beforeRender(() => {
|
applicationBuilder.beforeApplicationStart(() => {
|
||||||
|
clusters = observable.map();
|
||||||
clusterStore = ({
|
clusterStore = ({
|
||||||
clusters,
|
clusters,
|
||||||
get clustersList() {
|
get clustersList() {
|
||||||
@ -76,10 +91,12 @@ describe("cluster connection status", () => {
|
|||||||
|
|
||||||
applicationBuilder.dis.mainDi.override(clusterStoreInjectable, () => clusterStore);
|
applicationBuilder.dis.mainDi.override(clusterStoreInjectable, () => clusterStore);
|
||||||
applicationBuilder.dis.rendererDi.override(clusterStoreInjectable, () => clusterStore);
|
applicationBuilder.dis.rendererDi.override(clusterStoreInjectable, () => clusterStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
applicationBuilder.beforeRender(() => {
|
||||||
navigateToClusterView = applicationBuilder.dis.rendererDi.inject(navigateToClusterViewInjectable);
|
navigateToClusterView = applicationBuilder.dis.rendererDi.inject(navigateToClusterViewInjectable);
|
||||||
|
|
||||||
const createCluster = applicationBuilder.dis.rendererDi.inject(createClusterInjectable);
|
const createCluster = applicationBuilder.dis.mainDi.inject(createClusterInjectable);
|
||||||
|
|
||||||
cluster = createCluster({
|
cluster = createCluster({
|
||||||
contextName: "minikube",
|
contextName: "minikube",
|
||||||
@ -92,14 +109,14 @@ describe("cluster connection status", () => {
|
|||||||
|
|
||||||
cluster2 = createCluster({
|
cluster2 = createCluster({
|
||||||
contextName: "minikube-2",
|
contextName: "minikube-2",
|
||||||
id: "some-cluster-id",
|
id: "some-cluster-id-2",
|
||||||
kubeConfigPath: "/some/file/path",
|
kubeConfigPath: "/some/file/path",
|
||||||
}, {
|
}, {
|
||||||
clusterServerUrl: "https://localhost:1234",
|
clusterServerUrl: "https://localhost:1234",
|
||||||
});
|
});
|
||||||
cluster2.activate = jest.fn(); // override for test
|
cluster2.activate = jest.fn(); // override for test
|
||||||
|
|
||||||
clusters = new Map([
|
clusters.replace([
|
||||||
[cluster.id, cluster],
|
[cluster.id, cluster],
|
||||||
[cluster2.id, cluster2],
|
[cluster2.id, cluster2],
|
||||||
]);
|
]);
|
||||||
|
|||||||
36
src/main/cluster/set-visible-listener.injectable.ts
Normal file
36
src/main/cluster/set-visible-listener.injectable.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { SetVisibleClusterChannel } from "../../common/cluster/set-visible-channel.injectable";
|
||||||
|
import setVisibleClusterChannelInjectable from "../../common/cluster/set-visible-channel.injectable";
|
||||||
|
import { messageChannelListenerInjectionToken } from "../../common/utils/channel/message-channel-listener-injection-token";
|
||||||
|
import type { MessageChannelListener } from "../../common/utils/channel/message-channel-listener-injection-token";
|
||||||
|
import clusterManagerInjectable from "../cluster-manager.injectable";
|
||||||
|
|
||||||
|
const setVisibileClusterListenerInjectable = getInjectable({
|
||||||
|
id: "set-visible-cluster-listener",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const channel = di.inject(setVisibleClusterChannelInjectable);
|
||||||
|
const clusterManager = di.inject(clusterManagerInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
channel,
|
||||||
|
handler: (message) => {
|
||||||
|
switch (message.action) {
|
||||||
|
case "clear":
|
||||||
|
clusterManager.visibleCluster = undefined;
|
||||||
|
break;
|
||||||
|
case "set":
|
||||||
|
clusterManager.visibleCluster = message.clusterId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as MessageChannelListener<SetVisibleClusterChannel>;
|
||||||
|
},
|
||||||
|
injectionToken: messageChannelListenerInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setVisibileClusterListenerInjectable;
|
||||||
|
|
||||||
@ -5,7 +5,7 @@
|
|||||||
import type { IpcMainInvokeEvent } from "electron";
|
import type { IpcMainInvokeEvent } from "electron";
|
||||||
import { BrowserWindow, Menu } from "electron";
|
import { BrowserWindow, Menu } from "electron";
|
||||||
import { clusterFrameMap } from "../../../../common/cluster-frames";
|
import { clusterFrameMap } from "../../../../common/cluster-frames";
|
||||||
import { clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterDeleteHandler, clusterSetDeletingHandler, clusterClearDeletingHandler } from "../../../../common/ipc/cluster";
|
import { clusterSetFrameIdHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterDeleteHandler, clusterSetDeletingHandler, clusterClearDeletingHandler } from "../../../../common/ipc/cluster";
|
||||||
import type { ClusterId } from "../../../../common/cluster-types";
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
import { ClusterStore } from "../../../../common/cluster-store/cluster-store";
|
import { ClusterStore } from "../../../../common/cluster-store/cluster-store";
|
||||||
import { appEventBus } from "../../../../common/app-event-bus/event-bus";
|
import { appEventBus } from "../../../../common/app-event-bus/event-bus";
|
||||||
@ -48,10 +48,6 @@ export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLoc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMainOn(clusterVisibilityHandler, (event, clusterId?: ClusterId) => {
|
|
||||||
clusterManager.visibleCluster = clusterId;
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainHandle(clusterRefreshHandler, (event, clusterId: ClusterId) => {
|
ipcMainHandle(clusterRefreshHandler, (event, clusterId: ClusterId) => {
|
||||||
return ClusterStore.getInstance()
|
return ClusterStore.getInstance()
|
||||||
.getById(clusterId)
|
.getById(clusterId)
|
||||||
|
|||||||
@ -13,10 +13,12 @@ import kubectlBinaryNameInjectable from "./binary-name.injectable";
|
|||||||
import bundledKubectlBinaryPathInjectable from "./bundled-binary-path.injectable";
|
import bundledKubectlBinaryPathInjectable from "./bundled-binary-path.injectable";
|
||||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||||
|
|
||||||
|
export type CreateKubectl = (clusterVersion: string) => Kubectl;
|
||||||
|
|
||||||
const createKubectlInjectable = getInjectable({
|
const createKubectlInjectable = getInjectable({
|
||||||
id: "create-kubectl",
|
id: "create-kubectl",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di): CreateKubectl => {
|
||||||
const dependencies: KubectlDependencies = {
|
const dependencies: KubectlDependencies = {
|
||||||
userStore: di.inject(userStoreInjectable),
|
userStore: di.inject(userStoreInjectable),
|
||||||
directoryForKubectlBinaries: di.inject(directoryForKubectlBinariesInjectable),
|
directoryForKubectlBinaries: di.inject(directoryForKubectlBinariesInjectable),
|
||||||
@ -27,7 +29,7 @@ const createKubectlInjectable = getInjectable({
|
|||||||
baseBundeledBinariesDirectory: di.inject(baseBundledBinariesDirectoryInjectable),
|
baseBundeledBinariesDirectory: di.inject(baseBundledBinariesDirectoryInjectable),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (clusterVersion: string) => new Kubectl(dependencies, clusterVersion);
|
return (clusterVersion) => new Kubectl(dependencies, clusterVersion);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
24
src/renderer/cluster/send-set-visible.injectable.ts
Normal file
24
src/renderer/cluster/send-set-visible.injectable.ts
Normal file
@ -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 type { SetVisibleClusterChannel } from "../../common/cluster/set-visible-channel.injectable";
|
||||||
|
import setVisibleClusterChannelInjectable from "../../common/cluster/set-visible-channel.injectable";
|
||||||
|
import type { EmitChannelMessage } from "../../common/utils/channel/message-to-channel-injection-token";
|
||||||
|
import messageToChannelInjectable from "../utils/channel/message-to-channel.injectable";
|
||||||
|
|
||||||
|
export type SendSetVisibleCluster = EmitChannelMessage<SetVisibleClusterChannel>;
|
||||||
|
|
||||||
|
const sendSetVisibleClusterInjectable = getInjectable({
|
||||||
|
id: "send-set-visible-cluster",
|
||||||
|
instantiate: (di): SendSetVisibleCluster => {
|
||||||
|
const channel = di.inject(setVisibleClusterChannelInjectable);
|
||||||
|
const messageToChannel = di.inject(messageToChannelInjectable);
|
||||||
|
|
||||||
|
return (message) => messageToChannel(channel, message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default sendSetVisibleClusterInjectable;
|
||||||
@ -3,11 +3,20 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import getClusterByIdInjectable from "../../../common/cluster/get-by-id.injectable";
|
||||||
|
import loggerInjectable from "../../../common/logger.injectable";
|
||||||
|
import sendSetVisibleClusterInjectable from "../../cluster/send-set-visible.injectable";
|
||||||
import { ClusterFrameHandler } from "./cluster-frame-handler";
|
import { ClusterFrameHandler } from "./cluster-frame-handler";
|
||||||
|
import clusterFrameParentElementInjectable from "./parent-element.injectable";
|
||||||
|
|
||||||
const clusterFrameHandlerInjectable = getInjectable({
|
const clusterFrameHandlerInjectable = getInjectable({
|
||||||
id: "cluster-frame-handler",
|
id: "cluster-frame-handler",
|
||||||
instantiate: () => new ClusterFrameHandler(),
|
instantiate: (di) => new ClusterFrameHandler({
|
||||||
|
getClusterById: di.inject(getClusterByIdInjectable),
|
||||||
|
sendSetVisibleCluster: di.inject(sendSetVisibleClusterInjectable),
|
||||||
|
parentElem: di.inject(clusterFrameParentElementInjectable),
|
||||||
|
logger: di.inject(loggerInjectable),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default clusterFrameHandlerInjectable;
|
export default clusterFrameHandlerInjectable;
|
||||||
|
|||||||
@ -4,24 +4,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { action, makeObservable, observable, when } from "mobx";
|
import { action, makeObservable, observable, when } from "mobx";
|
||||||
import logger from "../../../main/logger";
|
|
||||||
import { clusterVisibilityHandler } from "../../../common/ipc/cluster";
|
|
||||||
import { ClusterStore } from "../../../common/cluster-store/cluster-store";
|
|
||||||
import type { ClusterId } from "../../../common/cluster-types";
|
import type { ClusterId } from "../../../common/cluster-types";
|
||||||
import type { Disposer } from "../../utils";
|
import type { Disposer } from "../../utils";
|
||||||
import { getClusterFrameUrl, onceDefined } from "../../utils";
|
import { getClusterFrameUrl, onceDefined } from "../../utils";
|
||||||
import { ipcRenderer } from "electron";
|
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
import type { GetClusterById } from "../../../common/cluster/get-by-id.injectable";
|
||||||
|
import type { SendSetVisibleCluster } from "../../cluster/send-set-visible.injectable";
|
||||||
|
import type { Logger } from "../../../common/logger";
|
||||||
|
|
||||||
export interface LensView {
|
export interface LensView {
|
||||||
isLoaded: boolean;
|
isLoaded: boolean;
|
||||||
frame: HTMLIFrameElement;
|
frame: HTMLIFrameElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ClusterFrameHandlerDependencies {
|
||||||
|
getClusterById: GetClusterById;
|
||||||
|
sendSetVisibleCluster: SendSetVisibleCluster;
|
||||||
|
readonly parentElem: HTMLElement;
|
||||||
|
readonly logger: Logger;
|
||||||
|
}
|
||||||
|
|
||||||
export class ClusterFrameHandler {
|
export class ClusterFrameHandler {
|
||||||
private readonly views = observable.map<string, LensView>();
|
private readonly views = observable.map<string, LensView>();
|
||||||
|
|
||||||
constructor() {
|
constructor(protected readonly dependencies: ClusterFrameHandlerDependencies) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,36 +37,33 @@ export class ClusterFrameHandler {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
public initView(clusterId: ClusterId) {
|
public initView(clusterId: ClusterId) {
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = this.dependencies.getClusterById(clusterId);
|
||||||
const parentElem = document.getElementById("lens-views");
|
|
||||||
|
|
||||||
assert(parentElem, "DOM with #lens-views must be present");
|
|
||||||
|
|
||||||
if (!cluster || this.views.has(clusterId)) {
|
if (!cluster || this.views.has(clusterId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`[LENS-VIEW]: init dashboard, clusterId=${clusterId}`);
|
this.dependencies.logger.info(`[LENS-VIEW]: init dashboard, clusterId=${clusterId}`);
|
||||||
const iframe = document.createElement("iframe");
|
const iframe = document.createElement("iframe");
|
||||||
|
|
||||||
iframe.id = `cluster-frame-${cluster.id}`;
|
iframe.id = `cluster-frame-${cluster.id}`;
|
||||||
iframe.name = cluster.contextName;
|
iframe.name = cluster.contextName;
|
||||||
iframe.setAttribute("src", getClusterFrameUrl(clusterId));
|
iframe.setAttribute("src", getClusterFrameUrl(clusterId));
|
||||||
iframe.addEventListener("load", action(() => {
|
iframe.addEventListener("load", action(() => {
|
||||||
logger.info(`[LENS-VIEW]: frame for clusterId=${clusterId} has loaded`);
|
this.dependencies.logger.info(`[LENS-VIEW]: frame for clusterId=${clusterId} has loaded`);
|
||||||
const view = this.views.get(clusterId);
|
const view = this.views.get(clusterId);
|
||||||
|
|
||||||
assert(view, `view for ${clusterId} MUST still exist here`);
|
assert(view, `view for ${clusterId} MUST still exist here`);
|
||||||
view.isLoaded = true;
|
view.isLoaded = true;
|
||||||
}), { once: true });
|
}), { once: true });
|
||||||
this.views.set(clusterId, { frame: iframe, isLoaded: false });
|
this.views.set(clusterId, { frame: iframe, isLoaded: false });
|
||||||
parentElem.appendChild(iframe);
|
this.dependencies.parentElem.appendChild(iframe);
|
||||||
|
|
||||||
logger.info(`[LENS-VIEW]: waiting cluster to be ready, clusterId=${clusterId}`);
|
this.dependencies.logger.info(`[LENS-VIEW]: waiting cluster to be ready, clusterId=${clusterId}`);
|
||||||
|
|
||||||
const dispose = when(
|
const dispose = when(
|
||||||
() => cluster.ready,
|
() => cluster.ready,
|
||||||
() => logger.info(`[LENS-VIEW]: cluster is ready, clusterId=${clusterId}`),
|
() => this.dependencies.logger.info(`[LENS-VIEW]: cluster is ready, clusterId=${clusterId}`),
|
||||||
);
|
);
|
||||||
|
|
||||||
when(
|
when(
|
||||||
@ -69,14 +72,14 @@ export class ClusterFrameHandler {
|
|||||||
() => {
|
() => {
|
||||||
when(
|
when(
|
||||||
() => {
|
() => {
|
||||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
const cluster = this.dependencies.getClusterById(clusterId);
|
||||||
|
|
||||||
return Boolean(!cluster || (cluster.disconnected && this.views.get(clusterId)?.isLoaded));
|
return Boolean(!cluster || (cluster.disconnected && this.views.get(clusterId)?.isLoaded));
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
|
this.dependencies.logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
|
||||||
this.views.delete(clusterId);
|
this.views.delete(clusterId);
|
||||||
parentElem.removeChild(iframe);
|
this.dependencies.parentElem.removeChild(iframe);
|
||||||
dispose();
|
dispose();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -90,15 +93,15 @@ export class ClusterFrameHandler {
|
|||||||
// Clear the previous when ASAP
|
// Clear the previous when ASAP
|
||||||
this.prevVisibleClusterChange?.();
|
this.prevVisibleClusterChange?.();
|
||||||
|
|
||||||
logger.info(`[LENS-VIEW]: refreshing iframe views, visible cluster id=${clusterId}`);
|
this.dependencies.logger.info(`[LENS-VIEW]: refreshing iframe views, visible cluster id=${clusterId}`);
|
||||||
ipcRenderer.send(clusterVisibilityHandler);
|
this.dependencies.sendSetVisibleCluster({ action: "clear" });
|
||||||
|
|
||||||
for (const { frame: view } of this.views.values()) {
|
for (const { frame: view } of this.views.values()) {
|
||||||
view.classList.add("hidden");
|
view.classList.add("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
const cluster = clusterId
|
const cluster = clusterId
|
||||||
? ClusterStore.getInstance().getById(clusterId)
|
? this.dependencies.getClusterById(clusterId)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
if (cluster && clusterId) {
|
if (cluster && clusterId) {
|
||||||
@ -113,10 +116,10 @@ export class ClusterFrameHandler {
|
|||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
(view: LensView) => {
|
(view: LensView) => {
|
||||||
logger.info(`[LENS-VIEW]: cluster id=${clusterId} should now be visible`);
|
this.dependencies.logger.info(`[LENS-VIEW]: cluster id=${clusterId} should now be visible`);
|
||||||
view.frame.classList.remove("hidden");
|
view.frame.classList.remove("hidden");
|
||||||
view.frame.focus();
|
view.frame.focus();
|
||||||
ipcRenderer.send(clusterVisibilityHandler, clusterId);
|
this.dependencies.sendSetVisibleCluster({ action: "set", clusterId });
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import assert from "assert";
|
||||||
|
|
||||||
|
const clusterFrameParentElementInjectable = getInjectable({
|
||||||
|
id: "cluster-frame-parent-element",
|
||||||
|
instantiate: () => {
|
||||||
|
const elem = document.getElementById("#lens-view");
|
||||||
|
|
||||||
|
assert(elem, "DOM with #lens-views must be present");
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clusterFrameParentElementInjectable;
|
||||||
@ -65,6 +65,7 @@ import setupSystemCaInjectable from "./frames/root-frame/setup-system-ca.injecta
|
|||||||
import extensionShouldBeEnabledForClusterFrameInjectable from "./extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
import extensionShouldBeEnabledForClusterFrameInjectable from "./extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||||
import { asyncComputed } from "@ogre-tools/injectable-react";
|
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||||
import forceUpdateModalRootFrameComponentInjectable from "./application-update/force-update-modal/force-update-modal-root-frame-component.injectable";
|
import forceUpdateModalRootFrameComponentInjectable from "./application-update/force-update-modal/force-update-modal-root-frame-component.injectable";
|
||||||
|
import clusterFrameParentElementInjectable from "./components/cluster-manager/parent-element.injectable";
|
||||||
import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injectable";
|
import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injectable";
|
||||||
import getEntitySettingCommandsInjectable from "./components/command-palette/registered-commands/get-entity-setting-commands.injectable";
|
import getEntitySettingCommandsInjectable from "./components/command-palette/registered-commands/get-entity-setting-commands.injectable";
|
||||||
import storageSaveDelayInjectable from "./utils/create-storage/storage-save-delay.injectable";
|
import storageSaveDelayInjectable from "./utils/create-storage/storage-save-delay.injectable";
|
||||||
@ -108,6 +109,7 @@ export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {})
|
|||||||
|
|
||||||
di.override(terminalSpawningPoolInjectable, () => document.createElement("div"));
|
di.override(terminalSpawningPoolInjectable, () => document.createElement("div"));
|
||||||
di.override(hostedClusterIdInjectable, () => undefined);
|
di.override(hostedClusterIdInjectable, () => undefined);
|
||||||
|
di.override(clusterFrameParentElementInjectable, () => document.createElement("div"));
|
||||||
|
|
||||||
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
|
||||||
di.override(joinPathsInjectable, () => joinPathsFake);
|
di.override(joinPathsInjectable, () => joinPathsFake);
|
||||||
|
|||||||
@ -19,7 +19,6 @@ const routePathParametersInjectable = getInjectable({
|
|||||||
|
|
||||||
return <Param>(route: Route<Param>): IComputedValue<Partial<Param>> => (
|
return <Param>(route: Route<Param>): IComputedValue<Partial<Param>> => (
|
||||||
getOrInsertWith(pathParametersCache, route, () => computed(() => (
|
getOrInsertWith(pathParametersCache, route, () => computed(() => (
|
||||||
console.log(currentPath.get()),
|
|
||||||
matchPath(currentPath.get(), {
|
matchPath(currentPath.get(), {
|
||||||
path: route.path,
|
path: route.path,
|
||||||
exact: true,
|
exact: true,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user