1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

responding to comments, dock-tab.store more tweaks

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-03-17 16:59:31 +02:00
parent c48135e0f3
commit 31fe837dd1
3 changed files with 63 additions and 39 deletions

View File

@ -1,4 +1,4 @@
import { autorun, observable, reaction } from "mobx"; import { autorun, observable, reaction, toJS } from "mobx";
import { autobind, createStorage, StorageHelper } from "../../utils"; import { autobind, createStorage, StorageHelper } from "../../utils";
import { dockStore, TabId } from "./dock.store"; import { dockStore, TabId } from "./dock.store";
@ -11,7 +11,7 @@ export type DockTabStorageState<T> = Record<TabId, T>;
@autobind() @autobind()
export class DockTabStore<T> { export class DockTabStore<T> {
private storage?: StorageHelper<DockTabStorageState<T>>; protected storage?: StorageHelper<DockTabStorageState<T>>;
protected data = observable.map<TabId, T>(); protected data = observable.map<TabId, T>();
constructor(protected options: DockTabStoreOptions = {}) { constructor(protected options: DockTabStoreOptions = {}) {
@ -49,18 +49,22 @@ export class DockTabStore<T> {
}); });
} }
protected serializeBeforeSave(data: T): T { protected finalizeDataForSave(data: T): T {
return data; return data;
} }
protected getStorableData(): DockTabStorageState<T> { protected getStorableData(): DockTabStorageState<T> {
const allTabsData = this.data.toJSON(); const allTabsData = toJS(this.data, { recurseEverything: true });
return Object.entries(allTabsData).reduce((data, [tabId, tabData]) => { return Object.fromEntries(
data[tabId] = this.serializeBeforeSave(tabData); Object.entries(allTabsData).map(([tabId, tabData]) => {
return [tabId, this.finalizeDataForSave(tabData)];
})
);
}
return data; isReady(tabId: TabId): boolean {
}, allTabsData); return Boolean(this.getData(tabId) !== undefined);
} }
getData(tabId: TabId) { getData(tabId: TabId) {

View File

@ -1,23 +1,29 @@
import { autobind, noop } from "../../utils"; import { autobind, noop } from "../../utils";
import { DockTabStore } from "./dock-tab.store"; import { DockTabStore } from "./dock-tab.store";
import { autorun, IReactionDisposer } from "mobx"; 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 { KubeObject } from "../../api/kube-object";
import { apiManager } from "../../api/api-manager"; 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 resource: string; // resource path, e.g. /api/v1/namespaces/default
draft?: string; // edited draft in yaml draft?: string; // edited draft in yaml
} }
@autobind() @autobind()
export class EditResourceStore extends DockTabStore<KubeEditResource> { export class EditResourceStore extends DockTabStore<EditingResource> {
private watchers = new Map<string /*tabId*/, IReactionDisposer>(); private watchers = new Map<TabId, IReactionDisposer>();
constructor() { constructor() {
super({ super({
storageKey: "edit_resource_store", storageKey: "edit_resource_store",
}); });
}
protected async init() {
super.init();
await this.storage.whenReady;
autorun(() => { autorun(() => {
Array.from(this.data).forEach(([tabId, { resource }]) => { Array.from(this.data).forEach(([tabId, { resource }]) => {
@ -41,16 +47,34 @@ export class EditResourceStore extends DockTabStore<KubeEditResource> {
} }
} }
}, { }, {
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 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 { getTabByResource(object: KubeObject): IDockTab {
const [tabId] = Array.from(this.data).find(([, { resource }]) => { const [tabId] = Array.from(this.data).find(([, { resource }]) => {
return object.selfLink === resource; return object.selfLink === resource;

View File

@ -1,8 +1,8 @@
import "./edit-resource.scss"; import "./edit-resource.scss";
import React from "react"; import React from "react";
import { autorun, observable } from "mobx"; import { observable, when } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { observer } from "mobx-react";
import jsYaml from "js-yaml"; import jsYaml from "js-yaml";
import { IDockTab } from "./dock.store"; import { IDockTab } from "./dock.store";
import { cssNames } from "../../utils"; import { cssNames } from "../../utils";
@ -11,8 +11,6 @@ import { InfoPanel } from "./info-panel";
import { Badge } from "../badge"; import { Badge } from "../badge";
import { EditorPanel } from "./editor-panel"; import { EditorPanel } from "./editor-panel";
import { Spinner } from "../spinner"; import { Spinner } from "../spinner";
import { apiManager } from "../../api/api-manager";
import { KubeObject } from "../../api/kube-object";
interface Props { interface Props {
className?: string; className?: string;
@ -23,30 +21,28 @@ interface Props {
export class EditResource extends React.Component<Props> { export class EditResource extends React.Component<Props> {
@observable error = ""; @observable error = "";
@disposeOnUnmount async componentDidMount() {
autoDumpResourceOnInit = autorun(() => { await when(() => this.isReady);
if (!this.tabData) return;
if (this.tabData.draft === undefined && this.resource) { if (!this.tabData.draft) {
this.saveDraft(this.resource); this.saveDraft(this.resource); // make initial dump to editor
} }
}); }
get tabId() { get tabId() {
return this.props.tab.id; return this.props.tab.id;
} }
get isReady() {
return editResourceStore.isReady(this.tabId);
}
get tabData() { get tabData() {
return editResourceStore.getData(this.tabId); return editResourceStore.getData(this.tabId);
} }
get resource(): KubeObject { get resource() {
const { resource } = this.tabData; return editResourceStore.getResource(this.tabId);
const store = apiManager.getStore(resource);
if (store) {
return store.getByPath(resource);
}
} }
saveDraft(draft: string | object) { saveDraft(draft: string | object) {
@ -68,8 +64,8 @@ export class EditResource extends React.Component<Props> {
if (this.error) { if (this.error) {
return; return;
} }
const { resource, draft } = this.tabData; const { draft } = this.tabData;
const store = apiManager.getStore(resource); const store = editResourceStore.getStore(this.tabId);
const updatedResource = await store.update(this.resource, jsYaml.safeLoad(draft)); const updatedResource = await store.update(this.resource, jsYaml.safeLoad(draft));
this.saveDraft(updatedResource); // update with new resourceVersion to avoid further errors on save this.saveDraft(updatedResource); // update with new resourceVersion to avoid further errors on save
@ -84,13 +80,13 @@ export class EditResource extends React.Component<Props> {
}; };
render() { render() {
const { tabId, resource, tabData, error, onChange, save } = this; if (!this.isReady) {
const { draft } = tabData;
if (!resource || draft === undefined) {
return <Spinner center/>; return <Spinner center/>;
} }
const { kind, getNs, getName } = resource;
const { tabId, error, onChange, save } = this;
const { kind, getNs, getName } = this.resource;
const { draft } = this.tabData;
return ( return (
<div className={cssNames("EditResource flex column", this.props.className)}> <div className={cssNames("EditResource flex column", this.props.className)}>