diff --git a/src/renderer/components/dock/__test__/dock-tabs.test.tsx b/src/renderer/components/dock/__test__/dock-tabs.test.tsx
index ad27853900..e2061c6543 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 { fireEvent, render } 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, DockTab, TabKind } from "../dock.store";
import { noop } from "../../../utils";
jest.mock("electron", () => ({
@@ -33,12 +33,12 @@ jest.mock("electron", () => ({
},
}));
-const initialTabs: IDockTab[] = [
- { id: "terminal", 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" },
+const initialTabs: DockTab[] = [
+ { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal", pinned: false, },
+ { id: "create", kind: TabKind.CREATE_RESOURCE, title: "Create resource", pinned: false, },
+ { id: "edit", kind: TabKind.EDIT_RESOURCE, title: "Edit resource", pinned: false, },
+ { id: "install", kind: TabKind.INSTALL_CHART, title: "Install chart", pinned: false, },
+ { id: "logs", kind: TabKind.POD_LOGS, title: "Logs", pinned: false, },
];
const getComponent = () => (
@@ -142,7 +142,7 @@ describe("", () => {
it("disables 'Close All' & 'Close Other' items if only 1 tab available", () => {
dockStore.tabs = [{
- id: "terminal", kind: TabKind.TERMINAL, title: "Terminal"
+ id: "terminal", kind: TabKind.TERMINAL, title: "Terminal", pinned: false,
}];
const { container, getByText } = renderTabs();
const tab = container.querySelector(".Tab");
@@ -157,8 +157,8 @@ describe("", () => {
it("disables 'Close To The Right' item if last tab clicked", () => {
dockStore.tabs = [
- { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal" },
- { id: "logs", kind: TabKind.POD_LOGS, title: "Pod Logs" },
+ { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal", pinned: false, },
+ { id: "logs", kind: TabKind.POD_LOGS, title: "Pod Logs", pinned: false, },
];
const { container, getByText } = renderTabs();
const tab = container.querySelectorAll(".Tab")[1];
diff --git a/src/renderer/components/dock/create-resource.store.ts b/src/renderer/components/dock/create-resource.store.ts
index 2e049deacf..f0b6b41154 100644
--- a/src/renderer/components/dock/create-resource.store.ts
+++ b/src/renderer/components/dock/create-resource.store.ts
@@ -27,7 +27,7 @@ import filehound from "filehound";
import { watch } from "chokidar";
import { autoBind } from "../../utils";
import { DockTabStore } from "./dock-tab.store";
-import { dockStore, IDockTab, TabKind } from "./dock.store";
+import { dockStore, DockTabCreateSpecific, TabKind } from "./dock.store";
export class CreateResourceStore extends DockTabStore {
constructor() {
@@ -81,10 +81,10 @@ export class CreateResourceStore extends DockTabStore {
export const createResourceStore = new CreateResourceStore();
-export function createResourceTab(tabParams: Partial = {}) {
+export function createResourceTab(tabParams: DockTabCreateSpecific = {}) {
return dockStore.createTab({
- kind: TabKind.CREATE_RESOURCE,
title: "Create resource",
- ...tabParams
+ ...tabParams,
+ kind: TabKind.CREATE_RESOURCE,
});
}
diff --git a/src/renderer/components/dock/create-resource.tsx b/src/renderer/components/dock/create-resource.tsx
index 413cbebc6d..f3423a7771 100644
--- a/src/renderer/components/dock/create-resource.tsx
+++ b/src/renderer/components/dock/create-resource.tsx
@@ -30,7 +30,7 @@ import { observable, makeObservable } from "mobx";
import { observer } from "mobx-react";
import { cssNames } from "../../utils";
import { createResourceStore } from "./create-resource.store";
-import type { IDockTab } from "./dock.store";
+import type { DockTab } from "./dock.store";
import { EditorPanel } from "./editor-panel";
import { InfoPanel } from "./info-panel";
import { resourceApplierApi } from "../../api/endpoints/resource-applier.api";
@@ -39,7 +39,7 @@ import { Notifications } from "../notifications";
interface Props {
className?: string;
- tab: IDockTab;
+ tab: DockTab;
}
@observer
diff --git a/src/renderer/components/dock/dock-tab.tsx b/src/renderer/components/dock/dock-tab.tsx
index dd4ff63824..a42a2dd64b 100644
--- a/src/renderer/components/dock/dock-tab.tsx
+++ b/src/renderer/components/dock/dock-tab.tsx
@@ -24,13 +24,13 @@ import "./dock-tab.scss";
import React from "react";
import { observer } from "mobx-react";
import { boundMethod, cssNames, prevDefault, isMiddleClick } from "../../utils";
-import { dockStore, IDockTab } from "./dock.store";
+import { dockStore, DockTab as DockTabModel } from "./dock.store";
import { Tab, TabProps } from "../tabs";
import { Icon } from "../icon";
import { Menu, MenuItem } from "../menu";
import { observable, makeObservable } from "mobx";
-export interface DockTabProps extends TabProps {
+export interface DockTabProps extends TabProps {
moreActions?: React.ReactNode;
}
diff --git a/src/renderer/components/dock/dock-tabs.tsx b/src/renderer/components/dock/dock-tabs.tsx
index 6064259cbc..372ef100d9 100644
--- a/src/renderer/components/dock/dock-tabs.tsx
+++ b/src/renderer/components/dock/dock-tabs.tsx
@@ -24,19 +24,19 @@ import React, { Fragment } from "react";
import { Icon } from "../icon";
import { Tabs } from "../tabs/tabs";
import { DockTab } from "./dock-tab";
-import type { IDockTab } from "./dock.store";
+import type { DockTab as DockTabModel } from "./dock.store";
import { TabKind } from "./dock.store";
import { TerminalTab } from "./terminal-tab";
interface Props {
- tabs: IDockTab[]
+ tabs: DockTabModel[]
autoFocus: boolean
- selectedTab: IDockTab
- onChangeTab: (tab: IDockTab) => void
+ selectedTab: DockTabModel
+ onChangeTab: (tab: DockTabModel) => void
}
export const DockTabs = ({ tabs, autoFocus, selectedTab, onChangeTab }: Props) => {
- const renderTab = (tab?: IDockTab) => {
+ const renderTab = (tab?: DockTabModel) => {
if (!tab) {
return null;
}
diff --git a/src/renderer/components/dock/dock.store.ts b/src/renderer/components/dock/dock.store.ts
index 2c9789ce41..516aba403b 100644
--- a/src/renderer/components/dock/dock.store.ts
+++ b/src/renderer/components/dock/dock.store.ts
@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-import MD5 from "crypto-js/md5";
+import * as uuid from "uuid";
import { action, computed, IReactionOptions, makeObservable, observable, reaction } from "mobx";
import { autoBind, createStorage } from "../../utils";
import throttle from "lodash/throttle";
@@ -35,16 +35,55 @@ export enum TabKind {
POD_LOGS = "pod-logs",
}
-export interface IDockTab {
+/**
+ * This is the storage model for dock tabs.
+ *
+ * All fields are required.
+ */
+export type DockTab = Required;
+
+/**
+ * These are the arguments for creating a new Tab on the dock
+ */
+export interface DockTabCreate {
+ /**
+ * The ID of the tab for reference purposes.
+ */
id?: TabId;
+
+ /**
+ * What kind of dock tab it is
+ */
kind: TabKind;
+
+ /**
+ * The tab's title, defaults to `kind`
+ */
title?: string;
- pinned?: boolean; // not closable
+
+ /**
+ * If true then the dock entry will take up the whole view and will not be
+ * closable.
+ */
+ pinned?: boolean;
+
+ /**
+ * Extra fields are supported.
+ */
+ [key: string]: any;
}
+/**
+ * This type is for function which specifically create a single type of dock tab.
+ *
+ * That way users should get a type error if they try and specify a `kind`
+ * themselves.
+ */
+export type DockTabCreateSpecific = Omit;
+
export interface DockStorageState {
height: number;
- tabs: IDockTab[];
+ tabs: DockTab[];
selectedTabId?: TabId;
isOpen?: boolean;
}
@@ -62,7 +101,7 @@ export class DockStore implements DockStorageState {
private storage = createStorage("dock", {
height: 300,
tabs: [
- { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal" },
+ { id: "terminal", kind: TabKind.TERMINAL, title: "Terminal", pinned: false },
],
});
@@ -88,11 +127,11 @@ export class DockStore implements DockStorageState {
});
}
- get tabs(): IDockTab[] {
+ get tabs(): DockTab[] {
return this.storage.get().tabs;
}
- set tabs(tabs: IDockTab[]) {
+ set tabs(tabs: DockTab[]) {
this.storage.merge({ tabs });
}
@@ -191,15 +230,31 @@ export class DockStore implements DockStorageState {
}
@action
- createTab(anonTab: IDockTab, addNumber = true): IDockTab {
- const tabId = MD5(Math.random().toString() + Date.now()).toString();
- const tab: IDockTab = { id: tabId, ...anonTab };
+ createTab(rawTabDesc: DockTabCreate, addNumber = true): DockTab {
+ const {
+ id = uuid.v4(),
+ kind,
+ pinned = false,
+ ...restOfTabFields
+ } = rawTabDesc;
+ let { title = kind } = rawTabDesc;
if (addNumber) {
- const tabNumber = this.getNewTabNumber(tab.kind);
+ const tabNumber = this.getNewTabNumber(kind);
- if (tabNumber > 1) tab.title += ` (${tabNumber})`;
+ if (tabNumber > 1) {
+ title += ` (${tabNumber})`;
+ }
}
+
+ const tab: DockTab = {
+ ...restOfTabFields,
+ id,
+ kind,
+ pinned,
+ title
+ };
+
this.tabs.push(tab);
this.selectTab(tab.id);
this.open();
@@ -234,7 +289,7 @@ export class DockStore implements DockStorageState {
}
}
- closeTabs(tabs: IDockTab[]) {
+ closeTabs(tabs: DockTab[]) {
tabs.forEach(tab => this.closeTab(tab.id));
}
diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx
index c3c4ca520b..a8cea06d7b 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, DockTab, TabKind } from "./dock.store";
import { EditResource } from "./edit-resource";
import { InstallChart } from "./install-chart";
import { Logs } from "./logs";
@@ -62,14 +62,14 @@ export class Dock extends React.Component {
}
};
- onChangeTab = (tab: IDockTab) => {
+ onChangeTab = (tab: DockTab) => {
const { open, selectTab } = dockStore;
open();
selectTab(tab.id);
};
- renderTab(tab: IDockTab) {
+ renderTab(tab: DockTab) {
switch (tab.kind) {
case TabKind.CREATE_RESOURCE:
return ;
diff --git a/src/renderer/components/dock/edit-resource.store.ts b/src/renderer/components/dock/edit-resource.store.ts
index 9b10491901..7931d86451 100644
--- a/src/renderer/components/dock/edit-resource.store.ts
+++ b/src/renderer/components/dock/edit-resource.store.ts
@@ -22,7 +22,7 @@
import { autoBind, noop } from "../../utils";
import { DockTabStore } from "./dock-tab.store";
import { autorun, IReactionDisposer } from "mobx";
-import { dockStore, IDockTab, TabId, TabKind } from "./dock.store";
+import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
import type { KubeObject } from "../../api/kube-object";
import { apiManager } from "../../api/api-manager";
import type { KubeObjectStore } from "../../kube-object.store";
@@ -96,7 +96,7 @@ export class EditResourceStore extends DockTabStore {
return this.getData(tabId)?.resource;
}
- getTabByResource(object: KubeObject): IDockTab {
+ getTabByResource(object: KubeObject): DockTab {
const [tabId] = Array.from(this.data).find(([, { resource }]) => {
return object.selfLink === resource;
}) || [];
@@ -115,7 +115,7 @@ export class EditResourceStore extends DockTabStore {
export const editResourceStore = new EditResourceStore();
-export function editResourceTab(object: KubeObject, tabParams: Partial = {}) {
+export function editResourceTab(object: KubeObject, tabParams: DockTabCreateSpecific = {}) {
// use existing tab if already opened
let tab = editResourceStore.getTabByResource(object);
@@ -128,8 +128,8 @@ export function editResourceTab(object: KubeObject, tabParams: Partial
if (!tab) {
tab = dockStore.createTab({
title: `${object.kind}: ${object.getName()}`,
+ ...tabParams,
kind: TabKind.EDIT_RESOURCE,
- ...tabParams
}, false);
editResourceStore.setData(tab.id, {
resource: object.selfLink,
diff --git a/src/renderer/components/dock/edit-resource.tsx b/src/renderer/components/dock/edit-resource.tsx
index 455bbda61a..0496ef3104 100644
--- a/src/renderer/components/dock/edit-resource.tsx
+++ b/src/renderer/components/dock/edit-resource.tsx
@@ -25,7 +25,7 @@ import React from "react";
import { action, computed, makeObservable, observable } from "mobx";
import { observer } from "mobx-react";
import jsYaml from "js-yaml";
-import type { IDockTab } from "./dock.store";
+import type { DockTab } from "./dock.store";
import { cssNames } from "../../utils";
import { editResourceStore } from "./edit-resource.store";
import { InfoPanel } from "./info-panel";
@@ -36,7 +36,7 @@ import type { KubeObject } from "../../api/kube-object";
interface Props {
className?: string;
- tab: IDockTab;
+ tab: DockTab;
}
@observer
diff --git a/src/renderer/components/dock/install-chart.store.ts b/src/renderer/components/dock/install-chart.store.ts
index 20e0a7a0ac..f7ae6930e6 100644
--- a/src/renderer/components/dock/install-chart.store.ts
+++ b/src/renderer/components/dock/install-chart.store.ts
@@ -20,7 +20,7 @@
*/
import { action, autorun, makeObservable } from "mobx";
-import { dockStore, IDockTab, TabId, TabKind } from "./dock.store";
+import { dockStore, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
import { DockTabStore } from "./dock-tab.store";
import { getChartDetails, getChartValues, HelmChart } from "../../api/endpoints/helm-charts.api";
import type { IReleaseUpdateDetails } from "../../api/endpoints/helm-releases.api";
@@ -98,12 +98,12 @@ export class InstallChartStore extends DockTabStore {
export const installChartStore = new InstallChartStore();
-export function createInstallChartTab(chart: HelmChart, tabParams: Partial = {}) {
+export function createInstallChartTab(chart: HelmChart, tabParams: DockTabCreateSpecific = {}) {
const { name, repo, version } = chart;
const tab = dockStore.createTab({
- kind: TabKind.INSTALL_CHART,
title: `Helm Install: ${repo}/${name}`,
- ...tabParams
+ ...tabParams,
+ kind: TabKind.INSTALL_CHART,
}, false);
installChartStore.setData(tab.id, {
diff --git a/src/renderer/components/dock/install-chart.tsx b/src/renderer/components/dock/install-chart.tsx
index 69e0313eec..b0113018ea 100644
--- a/src/renderer/components/dock/install-chart.tsx
+++ b/src/renderer/components/dock/install-chart.tsx
@@ -24,7 +24,7 @@ import "./install-chart.scss";
import React, { Component } from "react";
import { observable, makeObservable } from "mobx";
import { observer } from "mobx-react";
-import { dockStore, IDockTab } from "./dock.store";
+import { dockStore, DockTab } from "./dock.store";
import { InfoPanel } from "./info-panel";
import { Badge } from "../badge";
import { NamespaceSelect } from "../+namespaces/namespace-select";
@@ -42,7 +42,7 @@ import { navigate } from "../../navigation";
import { releaseURL } from "../../../common/routes";
interface Props {
- tab: IDockTab;
+ tab: DockTab;
}
@observer
diff --git a/src/renderer/components/dock/log-tab.store.ts b/src/renderer/components/dock/log-tab.store.ts
index 560cea5cff..50be7a1e34 100644
--- a/src/renderer/components/dock/log-tab.store.ts
+++ b/src/renderer/components/dock/log-tab.store.ts
@@ -26,7 +26,7 @@ import { podsStore } from "../+workloads-pods/pods.store";
import { IPodContainer, Pod } 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, DockTabCreateSpecific, TabKind } from "./dock.store";
export interface LogTabData {
pods: Pod[];
@@ -90,10 +90,10 @@ export class LogTabStore extends DockTabStore {
dockStore.renameTab(tabId, `Pod ${selectedPod.metadata.name}`);
}
- private createDockTab(tabParams: Partial) {
+ private createDockTab(tabParams: DockTabCreateSpecific) {
dockStore.createTab({
+ ...tabParams,
kind: TabKind.POD_LOGS,
- ...tabParams
}, false);
}
diff --git a/src/renderer/components/dock/logs.tsx b/src/renderer/components/dock/logs.tsx
index 4649d28eeb..6c5c8d115f 100644
--- a/src/renderer/components/dock/logs.tsx
+++ b/src/renderer/components/dock/logs.tsx
@@ -25,7 +25,7 @@ import { disposeOnUnmount, observer } from "mobx-react";
import { searchStore } from "../../../common/search-store";
import { boundMethod } from "../../utils";
-import type { IDockTab } from "./dock.store";
+import type { DockTab } from "./dock.store";
import { InfoPanel } from "./info-panel";
import { LogResourceSelector } from "./log-resource-selector";
import { LogList } from "./log-list";
@@ -36,7 +36,7 @@ import { LogTabData, logTabStore } from "./log-tab.store";
interface Props {
className?: string
- tab: IDockTab
+ tab: DockTab
}
@observer
diff --git a/src/renderer/components/dock/terminal-window.tsx b/src/renderer/components/dock/terminal-window.tsx
index d5b4d4a53b..652086d811 100644
--- a/src/renderer/components/dock/terminal-window.tsx
+++ b/src/renderer/components/dock/terminal-window.tsx
@@ -25,14 +25,14 @@ import React from "react";
import { reaction } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react";
import { cssNames } from "../../utils";
-import type { IDockTab } from "./dock.store";
+import type { DockTab } from "./dock.store";
import type { Terminal } from "./terminal";
import { terminalStore } from "./terminal.store";
import { ThemeStore } from "../../theme.store";
interface Props {
className?: string;
- tab: IDockTab;
+ tab: DockTab;
}
@observer
diff --git a/src/renderer/components/dock/terminal.store.ts b/src/renderer/components/dock/terminal.store.ts
index 7f0396336e..47d100b3ab 100644
--- a/src/renderer/components/dock/terminal.store.ts
+++ b/src/renderer/components/dock/terminal.store.ts
@@ -23,18 +23,18 @@ import { autorun, observable } from "mobx";
import { autoBind } from "../../utils";
import { Terminal } from "./terminal";
import { TerminalApi } from "../../api/terminal-api";
-import { dockStore, IDockTab, TabId, TabKind } from "./dock.store";
+import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
import { WebSocketApiState } from "../../api/websocket-api";
-export interface ITerminalTab extends IDockTab {
+export interface ITerminalTab extends DockTab {
node?: string; // activate node shell mode
}
-export function createTerminalTab(tabParams: Partial = {}) {
+export function createTerminalTab(tabParams: DockTabCreateSpecific = {}) {
return dockStore.createTab({
- kind: TabKind.TERMINAL,
title: `Terminal`,
- ...tabParams
+ ...tabParams,
+ kind: TabKind.TERMINAL,
});
}
diff --git a/src/renderer/components/dock/upgrade-chart.store.ts b/src/renderer/components/dock/upgrade-chart.store.ts
index 5aafdfb0ea..4a43ae4ab1 100644
--- a/src/renderer/components/dock/upgrade-chart.store.ts
+++ b/src/renderer/components/dock/upgrade-chart.store.ts
@@ -20,7 +20,7 @@
*/
import { action, autorun, computed, IReactionDisposer, reaction, makeObservable } from "mobx";
-import { dockStore, IDockTab, TabId, TabKind } from "./dock.store";
+import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
import { DockTabStore } from "./dock-tab.store";
import { getReleaseValues, HelmRelease } from "../../api/endpoints/helm-releases.api";
import { releaseStore } from "../+apps-releases/release.store";
@@ -120,14 +120,14 @@ export class UpgradeChartStore extends DockTabStore {
this.values.setData(tabId, values);
}
- getTabByRelease(releaseName: string): IDockTab {
+ getTabByRelease(releaseName: string): DockTab {
return dockStore.getTabById(this.releaseNameReverseLookup.get(releaseName));
}
}
export const upgradeChartStore = new UpgradeChartStore();
-export function createUpgradeChartTab(release: HelmRelease, tabParams: Partial = {}) {
+export function createUpgradeChartTab(release: HelmRelease, tabParams: DockTabCreateSpecific = {}) {
let tab = upgradeChartStore.getTabByRelease(release.getName());
if (tab) {
@@ -137,9 +137,9 @@ export function createUpgradeChartTab(release: HelmRelease, tabParams: Partial