diff --git a/src/renderer/components/cluster-manager/cluster-status.scss b/src/renderer/components/cluster-manager/cluster-status.scss index 59a0103db8..f746c583be 100644 --- a/src/renderer/components/cluster-manager/cluster-status.scss +++ b/src/renderer/components/cluster-manager/cluster-status.scss @@ -1,9 +1,11 @@ .ClusterStatus { --flex-gap: #{$padding * 2}; + position: relative; min-width: 350px; margin: auto; text-align: center; + z-index: 1; pre { @include hidden-scrollbar; diff --git a/src/renderer/components/cluster-manager/cluster-view.scss b/src/renderer/components/cluster-manager/cluster-view.scss index c7283cd445..60191867b6 100644 --- a/src/renderer/components/cluster-manager/cluster-view.scss +++ b/src/renderer/components/cluster-manager/cluster-view.scss @@ -1,18 +1,24 @@ .ClusterView { + position: relative; width: 100%; height: 100%; - display: none; - - &.loaded { - display: flex; - } + display: flex; + flex: 1; } -//#lens-views { -// position: absolute; -// left: 0; -// top: 0; -// width: 0; -// height: 0; -// overflow: hidden; -//} +#lens-views { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + display: flex; + + > * { + flex: 1; + } + + body > & { + display: none; + } +} diff --git a/src/renderer/components/cluster-manager/cluster-view.tsx b/src/renderer/components/cluster-manager/cluster-view.tsx index 8d991fe97c..57b62258cd 100644 --- a/src/renderer/components/cluster-manager/cluster-view.tsx +++ b/src/renderer/components/cluster-manager/cluster-view.tsx @@ -1,66 +1,87 @@ import "./cluster-view.scss" import React from "react"; -import { WebviewTag } from "electron" -import { action, autorun, computed, observable } from "mobx"; +import { WebviewTag } from "electron"; +import { observable, reaction } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import { ClusterId, clusterStore } from "../../../common/cluster-store"; import { getMatchedClusterId } from "./cluster-view.route"; import { ClusterStatus } from "./cluster-status"; -import logger from "../../../main/logger"; import { clusterIpc } from "../../../common/cluster-ipc"; +import logger from "../../../main/logger"; -const lensViews = observable.map() -const isLoaded = observable.map() +// todo: figure out how to replace webview-tag to iframe +// fixme: webview reloading/blinking when switching common <-> cluster views + +interface LensView { + clusterId: ClusterId; + webview: WebviewTag + isLoaded?: boolean +} + +const lensViews = observable.map() +const lensViewsHolder = document.createElement("div") +lensViewsHolder.id = "lens-views" +document.body.appendChild(lensViewsHolder); @observer export class ClusterView extends React.Component { protected placeholder: HTMLElement; - @computed get cluster() { + get cluster() { return clusterStore.getById(getMatchedClusterId()) } - // fixme: attach/detach doesn't work properly componentDidMount() { - // disposeOnUnmount(this, [ - // autorun(() => { - // const activeClusterId = this.cluster?.id; - // if (activeClusterId) { - // this.initView(activeClusterId); - // Array.from(lensViews).forEach(([clusterId, view]) => { - // if (activeClusterId === clusterId && isLoaded.has(clusterId)) { - // this.placeholder.appendChild(view) - // } else { - // view.parentElement.removeChild(view); - // } - // }) - // } - // }), - // ]) + this.attachViews(); + disposeOnUnmount(this, [ + reaction(() => this.cluster, selectedCluster => { + this.initView(selectedCluster?.id) + this.refreshViews() + }, { + fireImmediately: true + }) + ]) } - @action - initView(clusterId: ClusterId) { - if (lensViews.has(clusterId)) { + componentWillUnmount() { + this.detachViews(); + } + + initView = (clusterId: ClusterId) => { + if (!clusterId || lensViews.has(clusterId)) { return; } logger.info(`[WEBVIEW]: init view for clusterId=${clusterId}`) const webview = document.createElement("webview"); - webview.className = "ClusterView" webview.setAttribute("src", `//${clusterId}.${location.host}`) webview.setAttribute("nodeintegration", "true") webview.setAttribute("enableremotemodule", "true") webview.addEventListener("did-finish-load", () => { logger.info(`[WEBVIEW]: loaded, clusterId=${clusterId}`) - isLoaded.set(clusterId, true); - webview.classList.add("loaded") clusterIpc.init.invokeFromRenderer(clusterId); // push cluster-state to webview + lensViews.get(clusterId).isLoaded = true; + this.refreshViews(); }); webview.addEventListener("did-fail-load", (event) => { logger.error(`[WEBVIEW]: failed to load, clusterId=${clusterId}`, event) }); - lensViews.set(clusterId, webview); - document.body.appendChild(webview); + lensViews.set(clusterId, { clusterId, webview }); + lensViewsHolder.appendChild(webview); // add to dom and start loading frame + } + + attachViews = () => { + this.placeholder.appendChild(lensViewsHolder) + } + + detachViews = () => { + document.body.appendChild(lensViewsHolder); + } + + refreshViews = () => { + lensViews.forEach(({ clusterId, webview, isLoaded }) => { + const isActive = clusterId === this.cluster?.id; + webview.style.display = isLoaded && isActive ? "flex" : "none" + }) } bindRef = (elem: HTMLElement) => { @@ -69,10 +90,11 @@ export class ClusterView extends React.Component { render() { const { cluster } = this; - const showStatus = cluster && !cluster.accessible; + const view = lensViews.get(cluster?.id); + const showStatusPage = cluster && (!cluster.accessible || !view?.isLoaded); return (
- {showStatus && } + {showStatusPage && }
) }