diff --git a/src/common/k8s-api/kube-object.ts b/src/common/k8s-api/kube-object.ts index bcbe6bf05f..0cb4ac15f6 100644 --- a/src/common/k8s-api/kube-object.ts +++ b/src/common/k8s-api/kube-object.ts @@ -98,6 +98,12 @@ export interface KubeObjectStatus { export type KubeMetaField = keyof KubeObjectMetadata; +export class KubeCreationError extends Error { + constructor(message: string, public data: any) { + super(message); + } +} + export class KubeObject implements ItemObject { static readonly kind: string; static readonly namespaced: boolean; @@ -209,10 +215,14 @@ export class KubeObject ({ ...ownerRef, namespace })); diff --git a/src/renderer/components/dock/__test__/log-tab.store.test.ts b/src/renderer/components/dock/__test__/log-tab.store.test.ts index 8eea8ce970..5221c1a8c0 100644 --- a/src/renderer/components/dock/__test__/log-tab.store.test.ts +++ b/src/renderer/components/dock/__test__/log-tab.store.test.ts @@ -25,9 +25,11 @@ import { Pod } from "../../../../common/k8s-api/endpoints"; import { ThemeStore } from "../../../theme.store"; import { dockStore } from "../dock.store"; import { logTabStore } from "../log-tab.store"; -import { TerminalStore } from "../terminal.store"; import { deploymentPod1, deploymentPod2, deploymentPod3, dockerPod } from "./pod.mock"; import fse from "fs-extra"; +import { mockWindow } from "../../../../../__mocks__/windowMock"; + +mockWindow(); jest.mock("react-monaco-editor", () => null); @@ -45,7 +47,6 @@ describe("log tab store", () => { beforeEach(() => { UserStore.createInstance(); ThemeStore.createInstance(); - TerminalStore.createInstance(); }); afterEach(() => { @@ -53,7 +54,6 @@ describe("log tab store", () => { dockStore.reset(); UserStore.resetInstance(); ThemeStore.resetInstance(); - TerminalStore.resetInstance(); fse.remove("tmp"); }); @@ -135,11 +135,11 @@ describe("log tab store", () => { }); // FIXME: this is failed when it's not .only == depends on something above - it.only("closes tab if no pods left in store", () => { + it.only("closes tab if no pods left in store", async () => { const selectedPod = new Pod(deploymentPod1); const selectedContainer = selectedPod.getInitContainers()[0]; - logTabStore.createPodTab({ + const id = logTabStore.createPodTab({ selectedPod, selectedContainer }); @@ -147,6 +147,7 @@ describe("log tab store", () => { podsStore.items.clear(); expect(logTabStore.getData(dockStore.selectedTabId)).toBeUndefined(); - expect(dockStore.getTabById(dockStore.selectedTabId)).toBeUndefined(); + expect(logTabStore.getData(id)).toBeUndefined(); + expect(dockStore.getTabById(id)).toBeUndefined(); }); }); diff --git a/src/renderer/components/dock/dock.store.ts b/src/renderer/components/dock/dock.store.ts index 7551de1a2f..f2fd74a064 100644 --- a/src/renderer/components/dock/dock.store.ts +++ b/src/renderer/components/dock/dock.store.ts @@ -160,7 +160,7 @@ export class DockStore implements DockStorageState { window.addEventListener("resize", throttle(this.adjustHeight, 250)); // create monaco models this.whenReady.then(() => {this.tabs.forEach(tab => { - if (this.usesMonacoEditor(tab)) { + if (this.usesMonacoEditor(tab)) { monacoModelsManager.addModel(tab.id); } });}); @@ -274,7 +274,7 @@ export class DockStore implements DockStorageState { title }; - // add monaco model + // add monaco model if (this.usesMonacoEditor(tab)) { monacoModelsManager.addModel(id); } @@ -287,14 +287,14 @@ export class DockStore implements DockStorageState { } @action - async closeTab(tabId: TabId) { + closeTab(tabId: TabId) { const tab = this.getTabById(tabId); if (!tab || tab.pinned) { return; } - // remove monaco model + // remove monaco model if (this.usesMonacoEditor(tab)) { monacoModelsManager.removeModel(tabId); } @@ -305,12 +305,6 @@ export class DockStore implements DockStorageState { if (this.tabs.length) { const newTab = this.tabs.slice(-1)[0]; // last - if (newTab?.kind === TabKind.TERMINAL) { - // close the dock when selected sibling inactive terminal tab - const { TerminalStore } = await import("./terminal.store"); - - if (!TerminalStore.getInstance(false)?.isConnected(newTab.id)) this.close(); - } this.selectTab(newTab.id); } else { this.selectedTabId = null; diff --git a/src/renderer/components/dock/log-tab.store.ts b/src/renderer/components/dock/log-tab.store.ts index 5b6b73904f..d28410a8ad 100644 --- a/src/renderer/components/dock/log-tab.store.ts +++ b/src/renderer/components/dock/log-tab.store.ts @@ -25,6 +25,7 @@ import { podsStore } from "../+workloads-pods/pods.store"; import { IPodContainer, Pod } from "../../../common/k8s-api/endpoints"; import type { WorkloadKubeObject } from "../../../common/k8s-api/workload-kube-object"; +import logger from "../../../common/logger"; import { DockTabStore } from "./dock-tab.store"; import { dockStore, DockTabCreateSpecific, TabKind } from "./dock.store"; @@ -51,17 +52,15 @@ export class LogTabStore extends DockTabStore { storageKey: "pod_logs" }); - reaction(() => podsStore.items.length, () => { - this.updateTabsData(); - }); + reaction(() => podsStore.items.length, () => this.updateTabsData()); } - createPodTab({ selectedPod, selectedContainer }: PodLogsTabData): void { + createPodTab({ selectedPod, selectedContainer }: PodLogsTabData): string { const podOwner = selectedPod.getOwnerRefs()[0]; const pods = podsStore.getPodsByOwnerId(podOwner?.uid); const title = `Pod ${selectedPod.getName()}`; - this.createLogsTab(title, { + return this.createLogsTab(title, { pods: pods.length ? pods : [selectedPod], selectedPod, selectedContainer @@ -95,9 +94,9 @@ export class LogTabStore extends DockTabStore { ...tabParams, kind: TabKind.POD_LOGS, }, false); - } + } - private createLogsTab(title: string, data: LogTabData) { + private createLogsTab(title: string, data: LogTabData): string { const id = uniqueId("log-tab-"); this.createDockTab({ id, title }); @@ -106,38 +105,45 @@ export class LogTabStore extends DockTabStore { showTimestamps: false, previous: false }); + + return id; } - private async updateTabsData() { - const promises: Promise[] = []; - + private updateTabsData() { for (const [tabId, tabData] of this.data) { - const pod = new Pod(tabData.selectedPod); - const pods = podsStore.getPodsByOwnerId(pod.getOwnerRefs()[0]?.uid); - const isSelectedPodInList = pods.find(item => item.getId() == pod.getId()); - const selectedPod = isSelectedPodInList ? pod : pods[0]; - const selectedContainer = isSelectedPodInList ? tabData.selectedContainer : pod.getAllContainers()[0]; + try { + if (!tabData.selectedPod) { + tabData.selectedPod = tabData.pods[0]; + } - if (pods.length) { - this.setData(tabId, { - ...tabData, - selectedPod, - selectedContainer, - pods - }); - - this.renameTab(tabId); - } else { - promises.push(this.closeTab(tabId)); + const pod = new Pod(tabData.selectedPod); + const pods = podsStore.getPodsByOwnerId(pod.getOwnerRefs()[0]?.uid); + const isSelectedPodInList = pods.find(item => item.getId() == pod.getId()); + const selectedPod = isSelectedPodInList ? pod : pods[0]; + const selectedContainer = isSelectedPodInList ? tabData.selectedContainer : pod.getAllContainers()[0]; + + if (pods.length > 0) { + this.setData(tabId, { + ...tabData, + selectedPod, + selectedContainer, + pods + }); + + this.renameTab(tabId); + } else { + this.closeTab(tabId); + } + } catch (error) { + logger.error(`[LOG-TAB-STORE]: failed to set data for tabId=${tabId} deleting`, error,); + this.data.delete(tabId); } } - - await Promise.all(promises); } - private async closeTab(tabId: string) { + private closeTab(tabId: string) { this.clearData(tabId); - await dockStore.closeTab(tabId); + dockStore.closeTab(tabId); } }