diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index 15f7843f2f..b09d3734e0 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -91,7 +91,7 @@ export class KubernetesCluster extends CatalogEntity(src: Iterable, fn: (from: T) => any): Iterable } } +/** + * Creates a new iterator that iterates (lazily) over its input and yields the + * items that are not `null` or `undefined` value from `fn`. + * @param src A type that can be iterated over + * @param fn The function that is called for each value + */ +export function* keepDefined(src: Iterable): Iterable { + for (const from of src) { + if (from === null || from === undefined) { + continue; + } + + yield from; + } +} + /** * Creates a new iterator that iterates (lazily) over its input and yields the * result of `fn` when it is `truthy` diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 736fabe6ae..6c30f8c8c4 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -22,7 +22,7 @@ import { app, BrowserWindow, dialog, ipcMain, shell, webContents } from "electron"; import windowStateKeeper from "electron-window-state"; import { appEventBus } from "../common/event-bus"; -import { delay, iter, Singleton, toJS } from "../common/utils"; +import { delay, iter, Singleton } from "../common/utils"; import { ClusterFrameInfo, ClusterFrames } from "../common/cluster-frames"; import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import logger from "./logger"; @@ -42,7 +42,7 @@ export interface SendToViewArgs { export interface NavigateFrameInfoSpecifier { windowId?: number; - clusterId?: number; + clusterId?: string; frameId?: number; } @@ -237,49 +237,39 @@ export class WindowManager extends Singleton { * @param specifics The fallback options for specifying a target */ private getNavigateTarget(specifics: NavigateFrameInfoSpecifier[]): [ClusterFrameInfo | undefined, number | undefined] { - function helper(): ClusterFrameInfo | undefined | number { + function* helper(): Iterable { const clusterFrames = ClusterFrames.getInstance(); for (const fallback of specifics) { if (typeof fallback.clusterId === "string") { - const res = clusterFrames.getFrameInfoByClusterId(fallback.clusterId); - - if (res == null) { // intentional - return res; - } else { - continue; - } + yield clusterFrames.getFrameInfoByClusterId(fallback.clusterId); + continue; } if (typeof fallback.frameId === "number") { - const res = clusterFrames.getFrameInfoByFrameId(fallback.frameId); - - if (res == null) { // intentional - return res; - } else { - continue; - } + yield clusterFrames.getFrameInfoByFrameId(fallback.frameId); + continue; } if (typeof fallback.windowId === "number") { - return fallback.windowId; + yield fallback.windowId; } } return undefined; } - const target = helper(); - - if (target == null) { // intentional - return [undefined, undefined]; - } + const target = iter.first(iter.keepDefined(helper())); if (typeof target === "number") { return [undefined, target]; } - return [target, target.windowId]; + if (target) { + return [target, target.windowId]; + } + + return [undefined, undefined]; } /** @@ -289,18 +279,26 @@ export class WindowManager extends Singleton { */ async navigate(url: string, ...specifics: NavigateFrameInfoSpecifier[]): Promise { const [frameInfo, windowId] = this.getNavigateTarget(specifics); - - console.log("[WINDOW-MANAGER]: navigate to", url, "with", specifics, toJS(frameInfo), { windowId }); const browserWindow = await this.ensureWindow(windowId); const channel = frameInfo ? IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER : IpcRendererNavigationEvents.NAVIGATE_IN_APP; + const clusterId = frameInfo + ? ClusterFrames.getInstance().getClusterIdFromFrameInfo(frameInfo) + : undefined; - this.sendToView(browserWindow, { - channel, - frameInfo, - data: [url], - }); + if (clusterId && url.startsWith(`/cluster/${clusterId}`)) { + this.sendToView(browserWindow, { + channel: IpcRendererNavigationEvents.NAVIGATE_IN_APP, + data: [url], + }); + } else { + this.sendToView(browserWindow, { + channel, + frameInfo, + data: [url], + }); + } } reload() { diff --git a/src/renderer/components/cluster-manager/cluster-view.tsx b/src/renderer/components/cluster-manager/cluster-view.tsx index 3d0fea8e55..6f4d22dbf1 100644 --- a/src/renderer/components/cluster-manager/cluster-view.tsx +++ b/src/renderer/components/cluster-manager/cluster-view.tsx @@ -63,15 +63,6 @@ export class ClusterView extends React.Component { } componentDidMount() { - this.bindEvents(); - } - - componentWillUnmount() { - refreshViews(); - catalogEntityRegistry.activeEntity = null; - } - - bindEvents() { disposeOnUnmount(this, [ reaction(() => this.clusterId, async (clusterId) => { refreshViews(clusterId); // refresh visibility of active cluster @@ -82,9 +73,7 @@ export class ClusterView extends React.Component { fireImmediately: true, }), - reaction(() => [this.cluster?.ready, this.cluster?.disconnected], (values) => { - const disconnected = values[1]; - + reaction(() => [this.cluster?.ready, this.cluster?.disconnected], ([, disconnected]) => { if (hasLoadedView(this.clusterId) && disconnected) { navigate(`${catalogURL()}/${previousActiveTab.get()}`); // redirect to catalog when active cluster get disconnected/not available } @@ -92,6 +81,11 @@ export class ClusterView extends React.Component { ]); } + componentWillUnmount() { + refreshViews(); + catalogEntityRegistry.activeEntity = null; + } + renderStatus(): React.ReactNode { const { clusterId, cluster, isReady } = this; diff --git a/src/renderer/components/cluster-manager/lens-views.ts b/src/renderer/components/cluster-manager/lens-views.ts index ace85eed6e..f5355183ad 100644 --- a/src/renderer/components/cluster-manager/lens-views.ts +++ b/src/renderer/components/cluster-manager/lens-views.ts @@ -86,7 +86,7 @@ export async function autoCleanOnRemove(clusterId: ClusterId, iframe: HTMLIFrame } export function refreshViews(visibleClusterId?: string) { - logger.info(`[LENS-VIEW]: refreshing iframe views, visible cluster id=${visibleClusterId}`); + console.info(`[LENS-VIEW]: refreshing iframe views, visible cluster id=${visibleClusterId}`); const cluster = ClusterStore.getInstance().getById(visibleClusterId); lensViews.forEach(({ clusterId, view, isLoaded }) => {