mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
dock: don't use kube-object-store while editing resources
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
c22609ee0c
commit
05552fefab
@ -246,18 +246,16 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
}
|
||||
|
||||
@action
|
||||
async load(params: { name: string; namespace?: string, save?: boolean }): Promise<T> {
|
||||
const { name, namespace, save = true } = params;
|
||||
async load(params: { name: string; namespace?: string }): Promise<T> {
|
||||
const { name, namespace } = params;
|
||||
let item = this.getByName(name, namespace);
|
||||
|
||||
if (!item) {
|
||||
item = await this.loadItem(params);
|
||||
|
||||
if (save) {
|
||||
const newItems = this.sortItems([...this.items, item]);
|
||||
const newItems = this.sortItems([...this.items, item]);
|
||||
|
||||
this.items.replace(newItems);
|
||||
}
|
||||
this.items.replace(newItems);
|
||||
}
|
||||
|
||||
return item;
|
||||
@ -267,10 +265,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
async loadFromPath(resourcePath: string) {
|
||||
const { namespace, name } = parseKubeApi(resourcePath);
|
||||
|
||||
return this.load({
|
||||
name, namespace,
|
||||
save: false, // don't save loaded resource to store
|
||||
});
|
||||
return this.load({ name, namespace });
|
||||
}
|
||||
|
||||
protected async createItem(params: { name: string; namespace?: string }, data?: Partial<T>): Promise<T> {
|
||||
|
||||
@ -20,16 +20,14 @@
|
||||
*/
|
||||
|
||||
import { makeObservable } from "mobx";
|
||||
import { autoBind } from "../../utils";
|
||||
import { DockTabStore } from "./dock-tab.store";
|
||||
import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
|
||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||
import { apiManager } from "../../../common/k8s-api/api-manager";
|
||||
import type { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
||||
import yaml from "js-yaml";
|
||||
import { parseKubeApi } from "../../../common/k8s-api/kube-api-parse";
|
||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -37,43 +35,13 @@ export class EditResourceStore extends DockTabStore<EditingResource> {
|
||||
constructor() {
|
||||
super({ storageKey: "edit_resource_store" });
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
async init() {
|
||||
super.init();
|
||||
async getResource(tabId: TabId): Promise<KubeObject> {
|
||||
const resourcePath = this.getResourcePath(tabId);
|
||||
const { name, namespace } = parseKubeApi(resourcePath);
|
||||
|
||||
this.dispose.push(
|
||||
dockStore.onTabChange(({ tabId }) => this.editResource(tabId), {
|
||||
tabKind: TabKind.EDIT_RESOURCE,
|
||||
fireImmediately: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async editResource(tabId: TabId) {
|
||||
await this.whenReady;
|
||||
const store = this.getStore(tabId);
|
||||
const data = this.getData(tabId);
|
||||
|
||||
if (data.resource && !data.draft) {
|
||||
try {
|
||||
let resource = this.getResource(tabId);
|
||||
|
||||
resource ??= await store.loadFromPath(data.resource);
|
||||
data.draft ||= yaml.dump(resource.toPlainObject()); // dump resource if empty
|
||||
} catch (error) {
|
||||
console.error(`[DOCK]: dumping '${data.resource}' has failed: ${error}`, { store, data });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getStore(tabId: TabId): KubeObjectStore<KubeObject> | undefined {
|
||||
return apiManager.getStore(this.getResourcePath(tabId));
|
||||
}
|
||||
|
||||
getResource(tabId: TabId): KubeObject | undefined {
|
||||
return this.getStore(tabId)?.getByPath(this.getResourcePath(tabId));
|
||||
return apiManager.getApi(resourcePath)?.get({ name, namespace });
|
||||
}
|
||||
|
||||
getResourcePath(tabId: TabId): string {
|
||||
|
||||
@ -20,8 +20,9 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import yaml from "js-yaml";
|
||||
import { makeObservable, observable, reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { editResourceStore } from "./edit-resource.store";
|
||||
import { InfoPanel, InfoPanelProps } from "./info-panel";
|
||||
import { Badge } from "../badge";
|
||||
@ -35,31 +36,44 @@ interface Props extends InfoPanelProps {
|
||||
|
||||
@observer
|
||||
export class EditResourceInfoPanel extends React.Component<Props> {
|
||||
@observable.ref resource?: KubeObject;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.tabId, async (tabId) => {
|
||||
this.resource = null;
|
||||
this.resource = await editResourceStore.getResource(tabId);
|
||||
|
||||
const { draft } = editResourceStore.getData(tabId);
|
||||
|
||||
if (!draft) {
|
||||
this.saveDraft(this.resource.toPlainObject(), tabId);
|
||||
}
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
get tabId() {
|
||||
return this.props.tabId;
|
||||
}
|
||||
|
||||
get resource(): KubeObject | undefined {
|
||||
return editResourceStore.getResource(this.tabId);
|
||||
}
|
||||
|
||||
get draft(): string {
|
||||
return editResourceStore.getData(this.tabId)?.draft;
|
||||
}
|
||||
|
||||
private saveDraft(draft: string | KubeObject) {
|
||||
private saveDraft(draft: string | object, tabId = this.tabId) {
|
||||
if (typeof draft === "object") {
|
||||
draft = draft ? yaml.dump(draft.toPlainObject()) : undefined;
|
||||
draft = yaml.dump(draft);
|
||||
}
|
||||
|
||||
editResourceStore.getData(this.tabId).draft = draft;
|
||||
editResourceStore.getData(tabId).draft = draft;
|
||||
}
|
||||
|
||||
save = async () => {
|
||||
const store = editResourceStore.getStore(this.tabId);
|
||||
const { resource: resourcePath, draft } = editResourceStore.getData(this.tabId);
|
||||
const resource = store.getByPath(resourcePath) ?? await store.loadFromPath(resourcePath);
|
||||
const currentVersion = resource.toPlainObject();
|
||||
const resource = await editResourceStore.getResource(this.tabId); // get latest resource version
|
||||
const { draft } = editResourceStore.getData(this.tabId);
|
||||
const currentVersion = resource.toPlainObject() as KubeObject;
|
||||
const editedVersion = yaml.load(draft) as KubeObject;
|
||||
const patches = createPatch(currentVersion, editedVersion);
|
||||
const editingVersion = editedVersion.metadata.resourceVersion;
|
||||
@ -71,19 +85,20 @@ export class EditResourceInfoPanel extends React.Component<Props> {
|
||||
{resource.kind} version <b>{resource.getName()}</b> is updated on the server while editing.
|
||||
</p>
|
||||
<p>
|
||||
Please backup your changes and <a onClick={() => this.saveDraft(resource)}>refresh resource</a> to the editor.
|
||||
Please backup your changes and{" "}
|
||||
<a onClick={() => this.saveDraft(resource.toPlainObject())}>refresh resource</a> to the editor.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const updatedResource = await store.patch(this.resource, patches);
|
||||
const updatedResource = await this.resource.patch(patches);
|
||||
|
||||
this.saveDraft(updatedResource); // dump latest resource version for editing
|
||||
this.saveDraft(updatedResource); // dump latest version for editing
|
||||
|
||||
return (
|
||||
<p>
|
||||
{updatedResource.kind} <b>{updatedResource.getName()}</b> updated.
|
||||
{updatedResource.kind} <b>{updatedResource.metadata.name}</b> updated.
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user