1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fix cluster view closing sometimes

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-07-27 15:49:06 -04:00
parent c426eb9899
commit b86b118e3e
6 changed files with 67 additions and 45 deletions

View File

@ -91,7 +91,7 @@ export class KubernetesCluster extends CatalogEntity<KubernetesClusterMetadata,
}
async onRun() {
requestMain(navigateToClusterHandler, this.getId());
await requestMain(navigateToClusterHandler, this.getId());
}
onDetailsOpen(): void {

View File

@ -36,6 +36,20 @@ export class ClusterFrames extends Singleton {
return [...this.mapping.values()];
}
public getClusterIdFromFrameInfo(query: ClusterFrameInfo): ClusterId | undefined {
for (const [clusterId, info] of this.mapping) {
if (
info.frameId === query.frameId
&& info.processId === query.processId
&& info.windowId === query.windowId
) {
return clusterId;
}
}
return undefined;
}
public set(clusterId: ClusterId, info: ClusterFrameInfo): void {
this.mapping.set(clusterId, info);
}

View File

@ -109,6 +109,22 @@ export function* filter<T>(src: Iterable<T>, fn: (from: T) => any): Iterable<T>
}
}
/**
* 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<T>(src: Iterable<T | undefined | null>): Iterable<T> {
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`

View File

@ -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<ClusterFrameInfo | number | undefined> {
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<void> {
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() {

View File

@ -63,15 +63,6 @@ export class ClusterView extends React.Component<Props> {
}
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<Props> {
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<Props> {
]);
}
componentWillUnmount() {
refreshViews();
catalogEntityRegistry.activeEntity = null;
}
renderStatus(): React.ReactNode {
const { clusterId, cluster, isReady } = this;

View File

@ -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 }) => {