From 0cd865a0d40bf0c41ced57a65155db2c7876436a Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Mon, 25 Jan 2021 14:23:40 +0300 Subject: [PATCH] Refreshing tab pods if pod amount is changed in store Signed-off-by: Alex Andreev --- .../dock/__test__/log-tab.store.test.ts | 65 +++++++++++++++++-- .../components/dock/__test__/pod.mock.ts | 48 ++++++++++++++ .../components/dock/log-resource-selector.tsx | 30 +++++---- src/renderer/components/dock/log-tab.store.ts | 48 +++++++++++++- src/renderer/kube-object.store.ts | 4 ++ 5 files changed, 174 insertions(+), 21 deletions(-) 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 a923df0a09..12e3c5e99b 100644 --- a/src/renderer/components/dock/__test__/log-tab.store.test.ts +++ b/src/renderer/components/dock/__test__/log-tab.store.test.ts @@ -5,18 +5,18 @@ import { podsStore } from "../../+workloads-pods/pods.store"; import { Pod } from "../../../api/endpoints"; import { dockStore } from "../dock.store"; -import { LogTabStore } from "../log-tab.store"; -import { deploymentPod1, deploymentPod2, dockerPod } from "./pod.mock"; +import { logTabStore } from "../log-tab.store"; +import { deploymentPod1, deploymentPod2, deploymentPod3, dockerPod } from "./pod.mock"; -let logTabStore: LogTabStore = null; podsStore.items.push(new Pod(dockerPod)); podsStore.items.push(new Pod(deploymentPod1)); podsStore.items.push(new Pod(deploymentPod2)); describe("log tab store", () => { - beforeEach(async () => { - logTabStore = new LogTabStore(); + afterEach(() => { + logTabStore.reset(); + dockStore.reset(); }); it("creates log tab without sibling pods", () => { @@ -55,4 +55,59 @@ describe("log tab store", () => { previous: false }); }); + + it("removes item from pods list if pod deleted from store", () => { + const selectedPod = new Pod(deploymentPod1); + const selectedContainer = selectedPod.getInitContainers()[0]; + + logTabStore.createPodTab({ + selectedPod, + selectedContainer + }); + + podsStore.items.pop(); + + expect(logTabStore.getData(dockStore.selectedTabId)).toEqual({ + pods: [selectedPod], + selectedPod, + selectedContainer, + showTimestamps: false, + previous: false + }); + }); + + it("adds item into pods list if new sibling pod added to store", () => { + const selectedPod = new Pod(deploymentPod1); + const selectedContainer = selectedPod.getInitContainers()[0]; + + logTabStore.createPodTab({ + selectedPod, + selectedContainer + }); + + podsStore.items.push(new Pod(deploymentPod3)); + + expect(logTabStore.getData(dockStore.selectedTabId)).toEqual({ + pods: [selectedPod, deploymentPod3], + selectedPod, + selectedContainer, + showTimestamps: false, + previous: false + }); + }); + + it("closes tab if no pods left in store", () => { + const selectedPod = new Pod(deploymentPod1); + const selectedContainer = selectedPod.getInitContainers()[0]; + + logTabStore.createPodTab({ + selectedPod, + selectedContainer + }); + + podsStore.items.clear(); + + expect(logTabStore.getData(dockStore.selectedTabId)).toBeUndefined(); + expect(dockStore.getTabById(dockStore.selectedTabId)).toBeUndefined(); + }); }); \ No newline at end of file diff --git a/src/renderer/components/dock/__test__/pod.mock.ts b/src/renderer/components/dock/__test__/pod.mock.ts index d6f0757e06..1675772133 100644 --- a/src/renderer/components/dock/__test__/pod.mock.ts +++ b/src/renderer/components/dock/__test__/pod.mock.ts @@ -152,4 +152,52 @@ export const deploymentPod2 = { podIP: "dummy", startTime: "dummy", } +}; + +export const deploymentPod3 = { + apiVersion: "v1", + kind: "dummy", + metadata: { + uid: "deploymentPod3", + name: "deploymentPod3", + creationTimestamp: "dummy", + resourceVersion: "dummy", + namespace: "default", + ownerReferences: [{ + apiVersion: "v1", + kind: "Deployment", + name: "super-deployment", + uid: "uuid", + controller: true, + blockOwnerDeletion: true, + }] + }, + spec: { + containers: [ + { + name: "node-exporter", + image: "docker.io/prom/node-exporter:v1.0.0-rc.0", + imagePullPolicy: "pull" + }, + { + name: "node-exporter-1", + image: "docker.io/prom/node-exporter:v1.0.0-rc.0", + imagePullPolicy: "pull" + } + ], + serviceAccountName: "dummy", + serviceAccount: "dummy", + }, + status: { + phase: "Running", + conditions: [{ + type: "Running", + status: "Running", + lastProbeTime: 1, + lastTransitionTime: "Some time", + }], + hostIP: "dummy", + podIP: "dummy", + startTime: "dummy", + } }; \ No newline at end of file diff --git a/src/renderer/components/dock/log-resource-selector.tsx b/src/renderer/components/dock/log-resource-selector.tsx index 95e83da493..a9d1366eba 100644 --- a/src/renderer/components/dock/log-resource-selector.tsx +++ b/src/renderer/components/dock/log-resource-selector.tsx @@ -1,6 +1,6 @@ import "./log-resource-selector.scss"; -import React from "react"; +import React, { useEffect } from "react"; import { observer } from "mobx-react"; import { Pod } from "../../api/endpoints"; @@ -33,24 +33,20 @@ export const LogResourceSelector = observer((props: Props) => { reload(); }; + const selectFirstContainer = () => { + save({ selectedContainer: pod.getAllContainers()[0] }); + }; + + const renameTab = () => { + dockStore.renameTab(tabId, `Pod ${pod.getName()}`); + }; + const onPodChange = (option: SelectOption) => { const selectedPod = podsStore.getByName(option.value, pod.getNs()); - if (!selectedPod) { - return; - } - - save({ - selectedPod, - selectedContainer: selectedPod.getAllContainers()[0] - }); - - dockStore.renameTab(tabId, `Pod ${option.value}`); - - reload(); + save({ selectedPod }); }; - const getSelectOptions = (items: string[]) => { return items.map(item => { return { @@ -78,6 +74,12 @@ export const LogResourceSelector = observer((props: Props) => { } ]; + useEffect(() => { + selectFirstContainer(); + renameTab(); + reload(); + }, [selectedPod]); + return (
Namespace diff --git a/src/renderer/components/dock/log-tab.store.ts b/src/renderer/components/dock/log-tab.store.ts index ab651f42c3..f54d8845ae 100644 --- a/src/renderer/components/dock/log-tab.store.ts +++ b/src/renderer/components/dock/log-tab.store.ts @@ -1,4 +1,5 @@ import uniqueId from "lodash/uniqueId"; +import { reaction } from "mobx"; import { podsStore } from "../+workloads-pods/pods.store"; import { IPodContainer, Pod } from "../../api/endpoints"; @@ -28,9 +29,13 @@ export class LogTabStore extends DockTabStore { super({ storageName: "pod_logs" }); + + reaction(() => podsStore.items.length, () => { + this.updateTabsData(); + }); } - public createPodTab({ selectedPod, selectedContainer }: PodLogsTabData) { + createPodTab({ selectedPod, selectedContainer }: PodLogsTabData): void { const podOwner = selectedPod.getOwnerRefs()[0]; const pods = podsStore.getPodsByOwnerId(podOwner?.uid); const title = `Pod ${selectedPod.getName()}`; @@ -42,7 +47,7 @@ export class LogTabStore extends DockTabStore { }); } - public createWorkloadTab({ workload }: WorkloadLogsTabData) { + createWorkloadTab({ workload }: WorkloadLogsTabData): void { const pods = podsStore.getPodsByOwnerId(workload.getId()); if (!pods.length) return; @@ -58,6 +63,10 @@ export class LogTabStore extends DockTabStore { }); } + private get tabId() { + return dockStore.selectedTabId; + } + private createDockTab(tabParams: Partial) { dockStore.createTab({ kind: TabKind.POD_LOGS, @@ -75,6 +84,41 @@ export class LogTabStore extends DockTabStore { previous: false }); } + + private updateTabsData() { + this.data.forEach((value, tabId) => { + this.updatePodsData(tabId); + }); + } + + private updatePodsData(tabId: string) { + const tabData = this.getData(tabId); + const selectedPod = new Pod(tabData.selectedPod); + const owner = selectedPod.getOwnerRefs()[0]; + const pods = podsStore.getPodsByOwnerId(owner?.uid); + let newSelectedPod = selectedPod; + + if (!pods.length) { + this.closeTab(tabId); + + return; + } + + if (!pods.includes(selectedPod)) { + newSelectedPod = pods[0]; + } + + this.setData(tabId, { + ...tabData, + selectedPod: newSelectedPod, + pods + }); + } + + private closeTab(tabId: string) { + this.clearData(tabId); + dockStore.closeTab(tabId); + } } export const logTabStore = new LogTabStore(); diff --git a/src/renderer/kube-object.store.ts b/src/renderer/kube-object.store.ts index bb2fffd819..2e0dfa7ff5 100644 --- a/src/renderer/kube-object.store.ts +++ b/src/renderer/kube-object.store.ts @@ -42,6 +42,10 @@ export abstract class KubeObjectStore extends ItemSt } } + getById(id: string) { + return this.items.find(item => item.getId() === id); + } + getByName(name: string, namespace?: string): T { return this.items.find(item => { return item.getName() === name && (