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:
parent
c426eb9899
commit
b86b118e3e
@ -91,7 +91,7 @@ export class KubernetesCluster extends CatalogEntity<KubernetesClusterMetadata,
|
||||
}
|
||||
|
||||
async onRun() {
|
||||
requestMain(navigateToClusterHandler, this.getId());
|
||||
await requestMain(navigateToClusterHandler, this.getId());
|
||||
}
|
||||
|
||||
onDetailsOpen(): void {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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 }) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user