diff --git a/.eslintrc.js b/.eslintrc.js index b993078333d7..148ba2c6014d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -33,15 +33,6 @@ module.exports = { } }, overrides: [ - { - files: [ - "extensions/**/*.ts", - "extensions/**/*.tsx", - ], - rules: { - "import/no-unresolved": "off", // warns on @k8slens/extensions - } - }, { files: [ "**/*.js" @@ -229,6 +220,15 @@ module.exports = { { "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]}, ] }, - } + }, + { + files: [ + "extensions/**/*.ts", + "extensions/**/*.tsx", + ], + rules: { + "import/no-unresolved": "off", // warns on @k8slens/extensions + } + }, ] }; diff --git a/src/common/__tests__/search-store.test.ts b/src/common/__tests__/search-store.test.ts index b4c99b7e1955..49baa60ea913 100644 --- a/src/common/__tests__/search-store.test.ts +++ b/src/common/__tests__/search-store.test.ts @@ -22,6 +22,7 @@ import { SearchStore } from "../search-store"; import { Console } from "console"; import { stdout, stderr } from "process"; +import { DockStore } from "../../renderer/components/dock"; jest.mock("electron", () => ({ app: { @@ -31,7 +32,6 @@ jest.mock("electron", () => ({ console = new Console(stdout, stderr); -let searchStore: SearchStore = null; const logs = [ "1:M 30 Oct 2020 16:17:41.553 # Connection with replica 172.17.0.12:6379 lost", "1:M 30 Oct 2020 16:17:41.623 * Replica 172.17.0.12:6379 asks for synchronization", @@ -39,16 +39,26 @@ const logs = [ ]; describe("search store tests", () => { - beforeEach(async () => { - searchStore = new SearchStore(); + beforeEach(() => { + DockStore.createInstance(); + SearchStore.createInstance(); }); + afterEach(() => { + DockStore.resetInstance(); + SearchStore.resetInstance(); + }) + it("does nothing with empty search query", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch([], ""); expect(searchStore.occurrences).toEqual([]); }); it("doesn't break if no text provided", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(null, "replica"); expect(searchStore.occurrences).toEqual([]); @@ -57,33 +67,45 @@ describe("search store tests", () => { }); it("find 3 occurrences across 3 lines", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "172"); expect(searchStore.occurrences).toEqual([0, 1, 2]); }); it("find occurrences within 1 line (case-insensitive)", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "Starting"); expect(searchStore.occurrences).toEqual([2, 2]); }); it("sets overlay index equal to first occurrence", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "Replica"); expect(searchStore.activeOverlayIndex).toBe(0); }); it("set overlay index to next occurrence", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "172"); searchStore.setNextOverlayActive(); expect(searchStore.activeOverlayIndex).toBe(1); }); it("sets overlay to last occurrence", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "172"); searchStore.setPrevOverlayActive(); expect(searchStore.activeOverlayIndex).toBe(2); }); it("gets line index where overlay is located", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "synchronization"); expect(searchStore.activeOverlayLine).toBe(1); }); @@ -95,12 +117,16 @@ describe("search store tests", () => { }); it("gets active find number", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "172"); searchStore.setNextOverlayActive(); expect(searchStore.activeFind).toBe(2); }); it("gets total finds number", () => { + const searchStore = SearchStore.getInstance(); + searchStore.onSearch(logs, "Starting"); expect(searchStore.totalFinds).toBe(2); }); diff --git a/src/common/search-store.ts b/src/common/search-store.ts index ae4ba5fa5c35..b81bc62df3fe 100644 --- a/src/common/search-store.ts +++ b/src/common/search-store.ts @@ -20,10 +20,10 @@ */ import { action, computed, observable,reaction } from "mobx"; -import { dockStore } from "../renderer/components/dock/dock.store"; -import { autobind } from "../renderer/utils"; +import { DockStore } from "../renderer/components/dock"; +import { autobind, Singleton } from "../renderer/utils"; -export class SearchStore { +export class SearchStore extends Singleton { /** * An utility methods escaping user string to safely pass it into new Regex(variable) * @param value Unescaped string @@ -54,8 +54,10 @@ export class SearchStore { @observable activeOverlayIndex = -1; constructor() { - reaction(() => dockStore.selectedTabId, () => { - searchStore.reset(); + super(); + + reaction(() => DockStore.getInstance().selectedTabId, () => { + this.reset(); }); } @@ -173,5 +175,3 @@ export class SearchStore { this.occurrences = []; } } - -export const searchStore = new SearchStore; diff --git a/src/renderer/api/__tests__/crd.test.ts b/src/renderer/api/__tests__/crd.test.ts index af7db4280c45..61fa4ae83fbc 100644 --- a/src/renderer/api/__tests__/crd.test.ts +++ b/src/renderer/api/__tests__/crd.test.ts @@ -19,10 +19,23 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { Cluster } from "../../../main/cluster"; +import { ApiManager } from "../api-manager"; import { CustomResourceDefinition } from "../endpoints"; import type { IKubeObjectMetadata } from "../kube-object"; describe("Crds", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + describe("getVersion", () => { it("should get the first version name from the list of versions", () => { const crd = new CustomResourceDefinition({ diff --git a/src/renderer/api/__tests__/kube-api.test.ts b/src/renderer/api/__tests__/kube-api.test.ts index 99454c0133f8..f692af2706ce 100644 --- a/src/renderer/api/__tests__/kube-api.test.ts +++ b/src/renderer/api/__tests__/kube-api.test.ts @@ -19,10 +19,23 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { Cluster } from "../../../main/cluster"; +import { ApiManager } from "../api-manager"; import { KubeApi } from "../kube-api"; import { KubeObject } from "../kube-object"; describe("KubeApi", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + it("uses url from apiBase if apiBase contains the resource", async () => { (fetch as any).mockResponse(async (request: any) => { if (request.url === "/api-kube/apis/networking.k8s.io/v1") { diff --git a/src/renderer/api/__tests__/pods.test.ts b/src/renderer/api/__tests__/pods.test.ts index 3315581d0469..f8567b69e737 100644 --- a/src/renderer/api/__tests__/pods.test.ts +++ b/src/renderer/api/__tests__/pods.test.ts @@ -19,6 +19,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { Cluster } from "../../../main/cluster"; +import { ApiManager } from "../api-manager"; import { Pod } from "../endpoints"; interface GetDummyPodOptions { @@ -164,6 +166,17 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po } describe("Pods", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + const podTests = []; for (let r = 0; r < 3; r += 1) { diff --git a/src/renderer/api/api-manager.ts b/src/renderer/api/api-manager.ts index 95e14ae9068b..54acc5988c65 100644 --- a/src/renderer/api/api-manager.ts +++ b/src/renderer/api/api-manager.ts @@ -92,14 +92,14 @@ export class ApiManager extends Singleton { } @action - registerStore>(storeConstructor: KubeObjectStoreConstructor, apis?: KubeApi[]): this { + registerStore>(storeConstructor: KubeObjectStoreConstructor, apis?: KubeApi[]): Store { const store = new storeConstructor(this.cluster); for (const api of apis ?? [store.api]) { this.stores.set(api.apiBase, store); } - return this; + return store; } getStore>(api: string | KubeApi): Store | undefined { diff --git a/src/renderer/components/+workloads-deployments/deployment-scale-dialog.test.tsx b/src/renderer/components/+workloads-deployments/deployment-scale-dialog.test.tsx index d3f78c785456..5848d4f84724 100644 --- a/src/renderer/components/+workloads-deployments/deployment-scale-dialog.test.tsx +++ b/src/renderer/components/+workloads-deployments/deployment-scale-dialog.test.tsx @@ -24,8 +24,10 @@ import { render, waitFor, fireEvent } from "@testing-library/react"; import "@testing-library/jest-dom/extend-expect"; import { DeploymentScaleDialog } from "./deployment-scale-dialog"; -jest.mock("../../api/endpoints"); -import { Deployment, deploymentApi } from "../../api/endpoints"; +jest.mock("../../api/endpoints/deployment.api"); +import { Deployment, deploymentApi } from "../../api/endpoints/deployment.api"; +import { ApiManager } from "../../api/api-manager"; +import { Cluster } from "../../../main/cluster"; const dummyDeployment: Deployment = { apiVersion: "v1", @@ -116,6 +118,16 @@ const dummyDeployment: Deployment = { }; describe("", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); it("renders w/o errors", () => { const { container } = render(); diff --git a/src/renderer/components/+workloads-replicasets/replicaset-scale-dialog.test.tsx b/src/renderer/components/+workloads-replicasets/replicaset-scale-dialog.test.tsx index 631bdb393cf4..c4f49bf3cdb7 100755 --- a/src/renderer/components/+workloads-replicasets/replicaset-scale-dialog.test.tsx +++ b/src/renderer/components/+workloads-replicasets/replicaset-scale-dialog.test.tsx @@ -26,6 +26,8 @@ import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog"; import { render, waitFor, fireEvent } from "@testing-library/react"; import React from "react"; import { ReplicaSet, replicaSetApi } from "../../api/endpoints/replica-set.api"; +import { Cluster } from "../../../main/cluster"; +import { ApiManager } from "../../api/api-manager"; const dummyReplicaSet: ReplicaSet = { apiVersion: "v1", @@ -111,6 +113,17 @@ const dummyReplicaSet: ReplicaSet = { }; describe("", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + it("renders w/o errors", () => { const { container } = render(); diff --git a/src/renderer/components/+workloads-statefulsets/statefulset-scale-dialog.test.tsx b/src/renderer/components/+workloads-statefulsets/statefulset-scale-dialog.test.tsx index f6813bdfd9d6..c10b7da8681b 100755 --- a/src/renderer/components/+workloads-statefulsets/statefulset-scale-dialog.test.tsx +++ b/src/renderer/components/+workloads-statefulsets/statefulset-scale-dialog.test.tsx @@ -26,6 +26,8 @@ import { StatefulSet, statefulSetApi } from "../../api/endpoints"; import { StatefulSetScaleDialog } from "./statefulset-scale-dialog"; import { render, waitFor, fireEvent } from "@testing-library/react"; import React from "react"; +import { Cluster } from "../../../main/cluster"; +import { ApiManager } from "../../api/api-manager"; const dummyStatefulSet: StatefulSet = { apiVersion: "v1", @@ -121,6 +123,17 @@ const dummyStatefulSet: StatefulSet = { }; describe("", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + it("renders w/o errors", () => { const { container } = render(); diff --git a/src/renderer/components/dock/__test__/dock-tabs.test.tsx b/src/renderer/components/dock/__test__/dock-tabs.test.tsx index 0c5ae7defdc2..cc962b0ae096 100644 --- a/src/renderer/components/dock/__test__/dock-tabs.test.tsx +++ b/src/renderer/components/dock/__test__/dock-tabs.test.tsx @@ -24,7 +24,7 @@ import { render, fireEvent } from "@testing-library/react"; import "@testing-library/jest-dom/extend-expect"; import { DockTabs } from "../dock-tabs"; -import { dockStore, IDockTab, TabKind } from "../dock.store"; +import { DockStore, TabKind } from "../dock.store"; jest.mock("electron", () => ({ app: { @@ -36,8 +36,8 @@ const onChangeTab = jest.fn(); const getComponent = () => ( @@ -59,27 +59,22 @@ Object.defineProperty(window, "matchMedia", { const renderTabs = () => render(getComponent()); -const getTabKinds = () => dockStore.tabs.map(tab => tab.kind); +const getTabKinds = () => DockStore.getInstance().tabs.map(tab => tab.kind); describe("", () => { beforeEach(() => { - const terminalTab: IDockTab = { id: "terminal1", kind: TabKind.TERMINAL, title: "Terminal" }; - const createResourceTab: IDockTab = { id: "create", kind: TabKind.CREATE_RESOURCE, title: "Create resource" }; - const editResourceTab: IDockTab = { id: "edit", kind: TabKind.EDIT_RESOURCE, title: "Edit resource" }; - const installChartTab: IDockTab = { id: "install", kind: TabKind.INSTALL_CHART, title: "Install chart" }; - const logsTab: IDockTab = { id: "logs", kind: TabKind.POD_LOGS, title: "Logs" }; - - dockStore.tabs.push( - terminalTab, - createResourceTab, - editResourceTab, - installChartTab, - logsTab + DockStore.createInstance().tabs.push( + { id: "terminal1", kind: TabKind.TERMINAL, title: "Terminal" }, + { id: "create", kind: TabKind.CREATE_RESOURCE, title: "Create resource" }, + { id: "edit", kind: TabKind.EDIT_RESOURCE, title: "Edit resource" }, + { id: "install", kind: TabKind.INSTALL_CHART, title: "Install chart" }, + { id: "logs", kind: TabKind.POD_LOGS, title: "Logs" }, ); }); afterEach(() => { - dockStore.reset(); + DockStore.getInstance().reset(); + DockStore.resetInstance(); }); it("renders w/o errors", () => { @@ -174,7 +169,7 @@ describe("", () => { }); it("disables 'Close All' & 'Close Other' items if only 1 tab available", () => { - dockStore.tabs = [{ + DockStore.getInstance().tabs = [{ id: "terminal", kind: TabKind.TERMINAL, title: "Terminal" }]; const { container, getByText } = renderTabs(); @@ -189,7 +184,7 @@ describe("", () => { }); it("disables 'Close To The Right' item if last tab clicked", () => { - dockStore.tabs = [ + DockStore.getInstance().tabs = [ { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal" }, { id: "logs", kind: TabKind.POD_LOGS, title: "Pod Logs" }, ]; diff --git a/src/renderer/components/dock/__test__/log-resource-selector.test.tsx b/src/renderer/components/dock/__test__/log-resource-selector.test.tsx index 62566b868afa..bc839b19b3f2 100644 --- a/src/renderer/components/dock/__test__/log-resource-selector.test.tsx +++ b/src/renderer/components/dock/__test__/log-resource-selector.test.tsx @@ -30,6 +30,8 @@ import type { LogTabData } from "../log-tab.store"; import { dockerPod, deploymentPod1 } from "./pod.mock"; import { ThemeStore } from "../../../theme.store"; import { UserStore } from "../../../../common/user-store"; +import { Cluster } from "../../../../main/cluster"; +import { ApiManager } from "../../../api/api-manager"; jest.mock("electron", () => ({ app: { @@ -70,6 +72,17 @@ const getFewPodsTabData = (): LogTabData => { }; describe("", () => { + beforeEach(() => { + ApiManager.createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })); + }); + + afterEach(() => { + ApiManager.resetInstance(); + }); + beforeEach(() => { UserStore.createInstance(); ThemeStore.createInstance(); 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 7c11a0ce0534..8369eb8d55dd 100644 --- a/src/renderer/components/dock/__test__/log-tab.store.test.ts +++ b/src/renderer/components/dock/__test__/log-tab.store.test.ts @@ -19,11 +19,13 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import _ from "lodash"; import { PodsStore } from "../../+workloads-pods/pods.store"; import { Cluster } from "../../../../main/cluster"; -import { Pod } from "../../../api/endpoints"; -import { dockStore } from "../dock.store"; -import { logTabStore } from "../log-tab.store"; +import { ApiManager } from "../../../api/api-manager"; +import { Pod, podsApi } from "../../../api/endpoints"; +import { DockStore } from "../dock.store"; +import { LogTabStore } from "../log-tab.store"; import { deploymentPod1, deploymentPod2, deploymentPod3, dockerPod } from "./pod.mock"; jest.mock("electron", () => ({ @@ -32,22 +34,31 @@ jest.mock("electron", () => ({ }, })); -const podsStore = new PodsStore(new Cluster({ - id: "foo", - kubeConfigPath: "/foo/bar", -})); - -podsStore.items.push(new Pod(dockerPod)); -podsStore.items.push(new Pod(deploymentPod1)); -podsStore.items.push(new Pod(deploymentPod2)); - describe("log tab store", () => { + beforeEach(() => { + const store = ApiManager + .createInstance(new Cluster({ + id: "foo", + kubeConfigPath: "/bar", + })) + .registerStore(PodsStore); + DockStore.createInstance(); + LogTabStore.createInstance(); + + store.items.push(new Pod(dockerPod)); + store.items.push(new Pod(deploymentPod1)); + store.items.push(new Pod(deploymentPod2)); + }); + afterEach(() => { - logTabStore.reset(); - dockStore.reset(); + ApiManager.resetInstance(); + LogTabStore.resetInstance(); + DockStore.resetInstance(); }); it("creates log tab without sibling pods", () => { + const logTabStore = LogTabStore.getInstance(); + const dockStore = DockStore.getInstance(); const selectedPod = new Pod(dockerPod); const selectedContainer = selectedPod.getAllContainers()[0]; @@ -66,6 +77,8 @@ describe("log tab store", () => { }); it("creates log tab with sibling pods", () => { + const logTabStore = LogTabStore.getInstance(); + const dockStore = DockStore.getInstance(); const selectedPod = new Pod(deploymentPod1); const siblingPod = new Pod(deploymentPod2); const selectedContainer = selectedPod.getInitContainers()[0]; @@ -85,6 +98,9 @@ describe("log tab store", () => { }); it("removes item from pods list if pod deleted from store", () => { + const logTabStore = LogTabStore.getInstance(); + const dockStore = DockStore.getInstance(); + const podsStore = ApiManager.getInstance().getStore(podsApi); const selectedPod = new Pod(deploymentPod1); const selectedContainer = selectedPod.getInitContainers()[0]; @@ -105,6 +121,9 @@ describe("log tab store", () => { }); it("adds item into pods list if new sibling pod added to store", () => { + const logTabStore = LogTabStore.getInstance(); + const dockStore = DockStore.getInstance(); + const podsStore = ApiManager.getInstance().getStore(podsApi); const selectedPod = new Pod(deploymentPod1); const selectedContainer = selectedPod.getInitContainers()[0]; @@ -125,6 +144,9 @@ describe("log tab store", () => { }); it("closes tab if no pods left in store", () => { + const logTabStore = LogTabStore.getInstance(); + const dockStore = DockStore.getInstance(); + const podsStore = ApiManager.getInstance().getStore(podsApi); const selectedPod = new Pod(deploymentPod1); const selectedContainer = selectedPod.getInitContainers()[0]; diff --git a/src/renderer/components/dock/dock-tab.store.ts b/src/renderer/components/dock/dock-tab.store.ts index 42732cf4a45d..2b0d19fd660a 100644 --- a/src/renderer/components/dock/dock-tab.store.ts +++ b/src/renderer/components/dock/dock-tab.store.ts @@ -20,8 +20,8 @@ */ import { autorun, observable, reaction, toJS } from "mobx"; -import { autobind, createStorage, StorageHelper } from "../../utils"; -import { dockStore, TabId } from "./dock.store"; +import { autobind, createStorage, Singleton, StorageHelper } from "../../utils"; +import { DockStore, TabId } from "./dock.store"; export interface DockTabStoreOptions { autoInit?: boolean; // load data from storage when `storageKey` is provided and bind events, default: true @@ -31,11 +31,13 @@ export interface DockTabStoreOptions { export type DockTabStorageState = Record; @autobind() -export class DockTabStore { +export class DockTabStore extends Singleton { protected storage?: StorageHelper>; protected data = observable.map(); constructor(protected options: DockTabStoreOptions = {}) { + super(); + this.options = { autoInit: true, ...this.options, @@ -60,7 +62,7 @@ export class DockTabStore { // clear data for closed tabs autorun(() => { - const currentTabs = dockStore.tabs.map(tab => tab.id); + const currentTabs = DockStore.getInstance().tabs.map(tab => tab.id); Array.from(this.data.keys()).forEach(tabId => { if (!currentTabs.includes(tabId)) { diff --git a/src/renderer/components/dock/dock-tab.tsx b/src/renderer/components/dock/dock-tab.tsx index 433a7cf57f84..e7f0f3d5efad 100644 --- a/src/renderer/components/dock/dock-tab.tsx +++ b/src/renderer/components/dock/dock-tab.tsx @@ -24,7 +24,7 @@ import "./dock-tab.scss"; import React from "react"; import { observer } from "mobx-react"; import { autobind, cssNames, prevDefault } from "../../utils"; -import { dockStore, IDockTab } from "./dock.store"; +import { DockStore, IDockTab } from "./dock.store"; import { Tab, TabProps } from "../tabs"; import { Icon } from "../icon"; import { Menu, MenuItem } from "../menu"; @@ -44,11 +44,11 @@ export class DockTab extends React.Component { @autobind() close() { - dockStore.closeTab(this.tabId); + DockStore.getInstance().closeTab(this.tabId); } renderMenu() { - const { closeTab, closeAllTabs, closeOtherTabs, closeTabsToTheRight, tabs, getTabIndex } = dockStore; + const { closeTab, closeAllTabs, closeOtherTabs, closeTabsToTheRight, tabs, getTabIndex } = DockStore.getInstance(); const closeAllDisabled = tabs.length === 1; const closeOtherDisabled = tabs.length === 1; const closeRightDisabled = getTabIndex(this.tabId) === tabs.length - 1; diff --git a/src/renderer/components/dock/dock.store.ts b/src/renderer/components/dock/dock.store.ts index 2edbbce75c6a..5992fc4ab9c8 100644 --- a/src/renderer/components/dock/dock.store.ts +++ b/src/renderer/components/dock/dock.store.ts @@ -21,7 +21,7 @@ import MD5 from "crypto-js/md5"; import { action, computed, IReactionOptions, observable, reaction } from "mobx"; -import { autobind, createStorage } from "../../utils"; +import { autobind, createStorage, Singleton } from "../../utils"; import throttle from "lodash/throttle"; export type TabId = string; @@ -50,7 +50,7 @@ export interface DockStorageState { } @autobind() -export class DockStore implements DockStorageState { +export class DockStore extends Singleton implements DockStorageState { readonly minHeight = 100; @observable fullSize = false; @@ -102,6 +102,7 @@ export class DockStore implements DockStorageState { } constructor() { + super(); this.init(); } @@ -267,5 +268,3 @@ export class DockStore implements DockStorageState { this.storage?.reset(); } } - -export const dockStore = new DockStore(); diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index c3c4ca520bcf..311b695bdcd4 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -32,7 +32,7 @@ import { ResizeDirection, ResizingAnchor } from "../resizing-anchor"; import { CreateResource } from "./create-resource"; import { createResourceTab } from "./create-resource.store"; import { DockTabs } from "./dock-tabs"; -import { dockStore, IDockTab, TabKind } from "./dock.store"; +import { DockStore, IDockTab, TabKind } from "./dock.store"; import { EditResource } from "./edit-resource"; import { InstallChart } from "./install-chart"; import { Logs } from "./logs"; @@ -47,7 +47,7 @@ interface Props { @observer export class Dock extends React.Component { onKeydown = (evt: React.KeyboardEvent) => { - const { close, closeTab, selectedTab } = dockStore; + const { close, closeTab, selectedTab } = DockStore.getInstance(); if (!selectedTab) return; const { code, ctrlKey, shiftKey } = evt.nativeEvent; @@ -63,7 +63,7 @@ export class Dock extends React.Component { }; onChangeTab = (tab: IDockTab) => { - const { open, selectTab } = dockStore; + const { open, selectTab } = DockStore.getInstance(); open(); selectTab(tab.id); @@ -87,7 +87,7 @@ export class Dock extends React.Component { } renderTabContent() { - const { isOpen, height, selectedTab } = dockStore; + const { isOpen, height, selectedTab } = DockStore.getInstance(); if (!isOpen || !selectedTab) return null; @@ -100,6 +100,7 @@ export class Dock extends React.Component { render() { const { className } = this.props; + const dockStore = DockStore.getInstance(); const { isOpen, toggle, tabs, toggleFillSize, selectedTab, hasTabs, fullSize } = dockStore; return ( diff --git a/src/renderer/components/dock/index.ts b/src/renderer/components/dock/index.ts index a4cb5982f7e8..d9c7bc55e8e0 100644 --- a/src/renderer/components/dock/index.ts +++ b/src/renderer/components/dock/index.ts @@ -20,3 +20,5 @@ */ export * from "./dock"; +export * from "./dock.store"; +export * from "./dock-tab.store"; diff --git a/src/renderer/components/dock/log-tab.store.ts b/src/renderer/components/dock/log-tab.store.ts index da6d5262ea0b..ad83401649c3 100644 --- a/src/renderer/components/dock/log-tab.store.ts +++ b/src/renderer/components/dock/log-tab.store.ts @@ -27,7 +27,7 @@ import { ApiManager } from "../../api/api-manager"; import { IPodContainer, Pod, podsApi } from "../../api/endpoints"; import type { WorkloadKubeObject } from "../../api/workload-kube-object"; import { DockTabStore } from "./dock-tab.store"; -import { dockStore, IDockTab, TabKind } from "./dock.store"; +import { DockStore, IDockTab, TabKind } from "./dock.store"; export interface LogTabData { pods: Pod[]; @@ -92,11 +92,11 @@ export class LogTabStore extends DockTabStore { renameTab(tabId: string) { const { selectedPod } = this.getData(tabId); - dockStore.renameTab(tabId, `Pod ${selectedPod.metadata.name}`); + DockStore.getInstance().renameTab(tabId, `Pod ${selectedPod.metadata.name}`); } private createDockTab(tabParams: Partial) { - dockStore.createTab({ + DockStore.getInstance().createTab({ kind: TabKind.POD_LOGS, ...tabParams }, false); @@ -138,8 +138,6 @@ export class LogTabStore extends DockTabStore { private closeTab(tabId: string) { this.clearData(tabId); - dockStore.closeTab(tabId); + DockStore.getInstance().closeTab(tabId); } } - -export const logTabStore = new LogTabStore(); diff --git a/src/renderer/initializers/api-manager-stores.ts b/src/renderer/initializers/api-manager-stores.ts index 117a962b730e..5f70704ab7e8 100644 --- a/src/renderer/initializers/api-manager-stores.ts +++ b/src/renderer/initializers/api-manager-stores.ts @@ -52,34 +52,35 @@ import { ReplicaSetStore } from "../components/+workloads-replicasets"; import { StatefulSetStore } from "../components/+workloads-statefulsets"; export function initApiManagerStores() { - ApiManager.getInstance() - .registerStore(HpaStore) - .registerStore(LimitRangesStore) - .registerStore(ConfigMapsStore) - .registerStore(PodDisruptionBudgetsStore) - .registerStore(ResourceQuotasStore) - .registerStore(SecretsStore) - .registerStore(CrdStore) - .registerStore(EventStore) - .registerStore(NamespaceStore) - .registerStore(EndpointStore) - .registerStore(IngressStore) - .registerStore(NetworkPolicyStore) - .registerStore(ServiceStore) - .registerStore(NodesStore) - .registerStore(PodSecurityPoliciesStore) - .registerStore(StorageClassStore) - .registerStore(PersistentVolumeClaimStore) - .registerStore(PersistentVolumesStore) - .registerStore(ServiceAccountsStore) - .registerStore(CronJobStore) - .registerStore(DaemonSetStore) - .registerStore(DeploymentStore) - .registerStore(JobStore) - .registerStore(PodsStore) - .registerStore(ReplicaSetStore) - .registerStore(StatefulSetStore) - .registerStore(RolesStore, [roleApi, clusterRoleApi]) - .registerStore(RoleBindingsStore, [roleBindingApi, clusterRoleBindingApi]) - .registerStore(ClusterObjectStore); + const am = ApiManager.getInstance(); + + am.registerStore(HpaStore) + am.registerStore(LimitRangesStore) + am.registerStore(ConfigMapsStore) + am.registerStore(PodDisruptionBudgetsStore) + am.registerStore(ResourceQuotasStore) + am.registerStore(SecretsStore) + am.registerStore(CrdStore) + am.registerStore(EventStore) + am.registerStore(NamespaceStore) + am.registerStore(EndpointStore) + am.registerStore(IngressStore) + am.registerStore(NetworkPolicyStore) + am.registerStore(ServiceStore) + am.registerStore(NodesStore) + am.registerStore(PodSecurityPoliciesStore) + am.registerStore(StorageClassStore) + am.registerStore(PersistentVolumeClaimStore) + am.registerStore(PersistentVolumesStore) + am.registerStore(ServiceAccountsStore) + am.registerStore(CronJobStore) + am.registerStore(DaemonSetStore) + am.registerStore(DeploymentStore) + am.registerStore(JobStore) + am.registerStore(PodsStore) + am.registerStore(ReplicaSetStore) + am.registerStore(StatefulSetStore) + am.registerStore(RolesStore, [roleApi, clusterRoleApi]) + am.registerStore(RoleBindingsStore, [roleBindingApi, clusterRoleBindingApi]) + am.registerStore(ClusterObjectStore); }