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
|
@action
|
||||||
async load(params: { name: string; namespace?: string, save?: boolean }): Promise<T> {
|
async load(params: { name: string; namespace?: string }): Promise<T> {
|
||||||
const { name, namespace, save = true } = params;
|
const { name, namespace } = params;
|
||||||
let item = this.getByName(name, namespace);
|
let item = this.getByName(name, namespace);
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
item = await this.loadItem(params);
|
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;
|
return item;
|
||||||
@ -267,10 +265,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
|||||||
async loadFromPath(resourcePath: string) {
|
async loadFromPath(resourcePath: string) {
|
||||||
const { namespace, name } = parseKubeApi(resourcePath);
|
const { namespace, name } = parseKubeApi(resourcePath);
|
||||||
|
|
||||||
return this.load({
|
return this.load({ name, namespace });
|
||||||
name, namespace,
|
|
||||||
save: false, // don't save loaded resource to store
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async createItem(params: { name: string; namespace?: string }, data?: Partial<T>): Promise<T> {
|
protected async createItem(params: { name: string; namespace?: string }, data?: Partial<T>): Promise<T> {
|
||||||
|
|||||||
@ -20,16 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { makeObservable } from "mobx";
|
import { makeObservable } from "mobx";
|
||||||
import { autoBind } from "../../utils";
|
|
||||||
import { DockTabStore } from "./dock-tab.store";
|
import { DockTabStore } from "./dock-tab.store";
|
||||||
import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.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 { apiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import type { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
|
import { parseKubeApi } from "../../../common/k8s-api/kube-api-parse";
|
||||||
import yaml from "js-yaml";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
|
||||||
export interface EditingResource {
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,43 +35,13 @@ export class EditResourceStore extends DockTabStore<EditingResource> {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super({ storageKey: "edit_resource_store" });
|
super({ storageKey: "edit_resource_store" });
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
autoBind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async getResource(tabId: TabId): Promise<KubeObject> {
|
||||||
super.init();
|
const resourcePath = this.getResourcePath(tabId);
|
||||||
|
const { name, namespace } = parseKubeApi(resourcePath);
|
||||||
|
|
||||||
this.dispose.push(
|
return apiManager.getApi(resourcePath)?.get({ name, namespace });
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getResourcePath(tabId: TabId): string {
|
getResourcePath(tabId: TabId): string {
|
||||||
|
|||||||
@ -20,8 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import yaml from "js-yaml";
|
import yaml from "js-yaml";
|
||||||
|
import { makeObservable, observable, reaction } from "mobx";
|
||||||
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { editResourceStore } from "./edit-resource.store";
|
import { editResourceStore } from "./edit-resource.store";
|
||||||
import { InfoPanel, InfoPanelProps } from "./info-panel";
|
import { InfoPanel, InfoPanelProps } from "./info-panel";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
@ -35,31 +36,44 @@ interface Props extends InfoPanelProps {
|
|||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class EditResourceInfoPanel extends React.Component<Props> {
|
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() {
|
get tabId() {
|
||||||
return this.props.tabId;
|
return this.props.tabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get resource(): KubeObject | undefined {
|
private saveDraft(draft: string | object, tabId = this.tabId) {
|
||||||
return editResourceStore.getResource(this.tabId);
|
|
||||||
}
|
|
||||||
|
|
||||||
get draft(): string {
|
|
||||||
return editResourceStore.getData(this.tabId)?.draft;
|
|
||||||
}
|
|
||||||
|
|
||||||
private saveDraft(draft: string | KubeObject) {
|
|
||||||
if (typeof draft === "object") {
|
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 () => {
|
save = async () => {
|
||||||
const store = editResourceStore.getStore(this.tabId);
|
const resource = await editResourceStore.getResource(this.tabId); // get latest resource version
|
||||||
const { resource: resourcePath, draft } = editResourceStore.getData(this.tabId);
|
const { draft } = editResourceStore.getData(this.tabId);
|
||||||
const resource = store.getByPath(resourcePath) ?? await store.loadFromPath(resourcePath);
|
const currentVersion = resource.toPlainObject() as KubeObject;
|
||||||
const currentVersion = resource.toPlainObject();
|
|
||||||
const editedVersion = yaml.load(draft) as KubeObject;
|
const editedVersion = yaml.load(draft) as KubeObject;
|
||||||
const patches = createPatch(currentVersion, editedVersion);
|
const patches = createPatch(currentVersion, editedVersion);
|
||||||
const editingVersion = editedVersion.metadata.resourceVersion;
|
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.
|
{resource.kind} version <b>{resource.getName()}</b> is updated on the server while editing.
|
||||||
</p>
|
</p>
|
||||||
<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>
|
</p>
|
||||||
</div>
|
</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 (
|
return (
|
||||||
<p>
|
<p>
|
||||||
{updatedResource.kind} <b>{updatedResource.getName()}</b> updated.
|
{updatedResource.kind} <b>{updatedResource.metadata.name}</b> updated.
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user