From 31fe837dd14779a3d614dc43562a4d14c95f6cc2 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 17 Mar 2021 16:59:31 +0200 Subject: [PATCH] responding to comments, dock-tab.store more tweaks Signed-off-by: Roman --- .../components/dock/dock-tab.store.ts | 20 +++++---- .../components/dock/edit-resource.store.ts | 38 +++++++++++++--- .../components/dock/edit-resource.tsx | 44 +++++++++---------- 3 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/renderer/components/dock/dock-tab.store.ts b/src/renderer/components/dock/dock-tab.store.ts index 117d7118df..c951d221fd 100644 --- a/src/renderer/components/dock/dock-tab.store.ts +++ b/src/renderer/components/dock/dock-tab.store.ts @@ -1,4 +1,4 @@ -import { autorun, observable, reaction } from "mobx"; +import { autorun, observable, reaction, toJS } from "mobx"; import { autobind, createStorage, StorageHelper } from "../../utils"; import { dockStore, TabId } from "./dock.store"; @@ -11,7 +11,7 @@ export type DockTabStorageState = Record; @autobind() export class DockTabStore { - private storage?: StorageHelper>; + protected storage?: StorageHelper>; protected data = observable.map(); constructor(protected options: DockTabStoreOptions = {}) { @@ -49,18 +49,22 @@ export class DockTabStore { }); } - protected serializeBeforeSave(data: T): T { + protected finalizeDataForSave(data: T): T { return data; } protected getStorableData(): DockTabStorageState { - const allTabsData = this.data.toJSON(); + const allTabsData = toJS(this.data, { recurseEverything: true }); - return Object.entries(allTabsData).reduce((data, [tabId, tabData]) => { - data[tabId] = this.serializeBeforeSave(tabData); + return Object.fromEntries( + Object.entries(allTabsData).map(([tabId, tabData]) => { + return [tabId, this.finalizeDataForSave(tabData)]; + }) + ); + } - return data; - }, allTabsData); + isReady(tabId: TabId): boolean { + return Boolean(this.getData(tabId) !== undefined); } getData(tabId: TabId) { diff --git a/src/renderer/components/dock/edit-resource.store.ts b/src/renderer/components/dock/edit-resource.store.ts index 1509289e28..c7c82048e1 100644 --- a/src/renderer/components/dock/edit-resource.store.ts +++ b/src/renderer/components/dock/edit-resource.store.ts @@ -1,23 +1,29 @@ import { autobind, noop } from "../../utils"; import { DockTabStore } from "./dock-tab.store"; import { autorun, IReactionDisposer } from "mobx"; -import { dockStore, IDockTab, TabKind } from "./dock.store"; +import { dockStore, IDockTab, TabId, TabKind } from "./dock.store"; import { KubeObject } from "../../api/kube-object"; import { apiManager } from "../../api/api-manager"; +import { KubeObjectStore } from "../../kube-object.store"; -export interface KubeEditResource { +export interface EditingResource { resource: string; // resource path, e.g. /api/v1/namespaces/default draft?: string; // edited draft in yaml } @autobind() -export class EditResourceStore extends DockTabStore { - private watchers = new Map(); +export class EditResourceStore extends DockTabStore { + private watchers = new Map(); constructor() { super({ storageKey: "edit_resource_store", }); + } + + protected async init() { + super.init(); + await this.storage.whenReady; autorun(() => { Array.from(this.data).forEach(([tabId, { resource }]) => { @@ -41,16 +47,34 @@ export class EditResourceStore extends DockTabStore { } } }, { - delay: 100 // make sure all stores initialized + delay: 100 // make sure all kube-object stores are initialized })); }); }); } - - protected serializeBeforeSave({ draft, ...data }: KubeEditResource) { + + protected finalizeDataForSave({ draft, ...data }: EditingResource): EditingResource { return data; // skip saving draft to local-storage } + isReady(tabId: TabId) { + const tabDataReady = super.isReady(tabId); + + return Boolean(tabDataReady && this.getResource(tabId)); // ready to edit resource + } + + getStore(tabId: TabId): KubeObjectStore | undefined { + return apiManager.getStore(this.getResourcePath(tabId)); + } + + getResource(tabId: TabId): KubeObject | undefined { + return this.getStore(tabId)?.getByPath(this.getResourcePath(tabId)); + } + + getResourcePath(tabId: TabId): string | undefined { + return this.getData(tabId)?.resource; + } + getTabByResource(object: KubeObject): IDockTab { const [tabId] = Array.from(this.data).find(([, { resource }]) => { return object.selfLink === resource; diff --git a/src/renderer/components/dock/edit-resource.tsx b/src/renderer/components/dock/edit-resource.tsx index 104f8f1ea3..236a63d923 100644 --- a/src/renderer/components/dock/edit-resource.tsx +++ b/src/renderer/components/dock/edit-resource.tsx @@ -1,8 +1,8 @@ import "./edit-resource.scss"; import React from "react"; -import { autorun, observable } from "mobx"; -import { disposeOnUnmount, observer } from "mobx-react"; +import { observable, when } from "mobx"; +import { observer } from "mobx-react"; import jsYaml from "js-yaml"; import { IDockTab } from "./dock.store"; import { cssNames } from "../../utils"; @@ -11,8 +11,6 @@ import { InfoPanel } from "./info-panel"; import { Badge } from "../badge"; import { EditorPanel } from "./editor-panel"; import { Spinner } from "../spinner"; -import { apiManager } from "../../api/api-manager"; -import { KubeObject } from "../../api/kube-object"; interface Props { className?: string; @@ -23,30 +21,28 @@ interface Props { export class EditResource extends React.Component { @observable error = ""; - @disposeOnUnmount - autoDumpResourceOnInit = autorun(() => { - if (!this.tabData) return; + async componentDidMount() { + await when(() => this.isReady); - if (this.tabData.draft === undefined && this.resource) { - this.saveDraft(this.resource); + if (!this.tabData.draft) { + this.saveDraft(this.resource); // make initial dump to editor } - }); + } get tabId() { return this.props.tab.id; } + get isReady() { + return editResourceStore.isReady(this.tabId); + } + get tabData() { return editResourceStore.getData(this.tabId); } - get resource(): KubeObject { - const { resource } = this.tabData; - const store = apiManager.getStore(resource); - - if (store) { - return store.getByPath(resource); - } + get resource() { + return editResourceStore.getResource(this.tabId); } saveDraft(draft: string | object) { @@ -68,8 +64,8 @@ export class EditResource extends React.Component { if (this.error) { return; } - const { resource, draft } = this.tabData; - const store = apiManager.getStore(resource); + const { draft } = this.tabData; + const store = editResourceStore.getStore(this.tabId); const updatedResource = await store.update(this.resource, jsYaml.safeLoad(draft)); this.saveDraft(updatedResource); // update with new resourceVersion to avoid further errors on save @@ -84,13 +80,13 @@ export class EditResource extends React.Component { }; render() { - const { tabId, resource, tabData, error, onChange, save } = this; - const { draft } = tabData; - - if (!resource || draft === undefined) { + if (!this.isReady) { return ; } - const { kind, getNs, getName } = resource; + + const { tabId, error, onChange, save } = this; + const { kind, getNs, getName } = this.resource; + const { draft } = this.tabData; return (