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

PoC: Stale resource in details panel after update from apis/store, fix #7186

Updated currently for: Replication Controllers & Namespaces.

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2023-02-17 16:21:49 +02:00
parent 2959e01d1e
commit 998a9e8e96
4 changed files with 71 additions and 34 deletions

View File

@ -7,6 +7,8 @@ import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-ur
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable"; import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import { asyncComputed } from "@ogre-tools/injectable-react"; import { asyncComputed } from "@ogre-tools/injectable-react";
import type { KubeObject } from "../../../common/k8s-api/kube-object"; import type { KubeObject } from "../../../common/k8s-api/kube-object";
import type { IComputedValue } from "mobx";
import { action, computed, observable, runInAction } from "mobx";
export type CurrentKubeObject = export type CurrentKubeObject =
| undefined | undefined
@ -41,4 +43,36 @@ const currentKubeObjectInDetailsInjectable = getInjectable({
}, },
}); });
export type KubeObjectDetailsItemValue = KubeObject | Error | undefined;
export type KubeObjectDetailsItemComputed = IComputedValue<KubeObjectDetailsItemValue>;
export const currentKubeObjectInDetailsInjectable2 = getInjectable({
id: "current-kube-object-in-details-2",
instantiate(di): KubeObjectDetailsItemComputed {
const kubeObjectUrlParam = di.inject(kubeDetailsUrlParamInjectable);
const apiManager = di.inject(apiManagerInjectable);
const kubeObject = observable.box<KubeObjectDetailsItemValue>();
return computed(() => {
const kubeObjUrlPath = kubeObjectUrlParam.get();
if (!kubeObjUrlPath) return; // details panel is hidden
const store = apiManager.getStore(kubeObjUrlPath);
const object = store?.getByPath(kubeObjUrlPath);
if (!object) {
store?.loadFromPath(kubeObjUrlPath)
.then(action((obj) => kubeObject.set(obj)))
.catch(action((error) => kubeObject.set(Error(error))));
} else {
runInAction(() => kubeObject.set(object));
}
return kubeObject.get() ?? object;
});
},
});
export default currentKubeObjectInDetailsInjectable; export default currentKubeObjectInDetailsInjectable;

View File

@ -6,18 +6,23 @@ import { getInjectable } from "@ogre-tools/injectable";
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token"; import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
import { computed } from "mobx"; import { computed } from "mobx";
import { NamespaceDetails } from "../../../+namespaces"; import { NamespaceDetails } from "../../../+namespaces";
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version"; import {
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable"; kubeObjectMatchesToKindAndApiVersion,
} from "../kube-object-matches-to-kind-and-api-version";
import {
currentKubeObjectInDetailsInjectable2,
} from "../../current-kube-object-in-details.injectable";
import type { KubeObject } from "../../../../../common/k8s-api/kube-object";
const namespacesDetailItemInjectable = getInjectable({ const namespacesDetailItemInjectable = getInjectable({
id: "namespaces-detail-item", id: "namespaces-detail-item",
instantiate: (di) => { instantiate: (di) => {
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable); const kubeObject = di.inject(currentKubeObjectInDetailsInjectable2);
return { return {
Component: NamespaceDetails, Component: NamespaceDetails,
enabled: computed(() => isNamespace(kubeObject.value.get()?.object)), enabled: computed(() => isNamespace(kubeObject.get() as KubeObject)),
orderNumber: 10, orderNumber: 10,
}; };
}, },

View File

@ -8,18 +8,21 @@ import { computed } from "mobx";
import { import {
kubeObjectMatchesToKindAndApiVersion, kubeObjectMatchesToKindAndApiVersion,
} from "../kube-object-matches-to-kind-and-api-version"; } from "../kube-object-matches-to-kind-and-api-version";
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable"; import {
currentKubeObjectInDetailsInjectable2,
} from "../../current-kube-object-in-details.injectable";
import { ReplicationControllerDetails } from "../../../+workloads-replicationcontrollers"; import { ReplicationControllerDetails } from "../../../+workloads-replicationcontrollers";
import type { KubeObject } from "../../../../../common/k8s-api/kube-object";
const replicationControllerDetailItemInjectable = getInjectable({ const replicationControllerDetailItemInjectable = getInjectable({
id: "replication-controller-detail-item", id: "replication-controller-detail-item",
instantiate(di) { instantiate(di) {
const kubeObject = di.inject(currentKubeObjectInDetailsInjectable); const kubeObject = di.inject(currentKubeObjectInDetailsInjectable2);
return { return {
Component: ReplicationControllerDetails, Component: ReplicationControllerDetails,
enabled: computed(() => isReplicationController(kubeObject.value.get()?.object)), enabled: computed(() => isReplicationController(kubeObject.get() as KubeObject)),
orderNumber: 10, orderNumber: 10,
}; };
}, },

View File

@ -9,16 +9,20 @@ import React from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import type { IComputedValue } from "mobx"; import type { IComputedValue } from "mobx";
import { Drawer } from "../drawer"; import { Drawer } from "../drawer";
import type { KubeObject } from "../../../common/k8s-api/kube-object"; import { KubeObject } from "../../../common/k8s-api/kube-object";
import { Spinner } from "../spinner"; import { Spinner } from "../spinner";
import { KubeObjectMenu } from "../kube-object-menu"; import { KubeObjectMenu } from "../kube-object-menu";
import type { HideDetails } from "../kube-detail-params/hide-details.injectable"; import type { HideDetails } from "../kube-detail-params/hide-details.injectable";
import type { IAsyncComputed } from "@ogre-tools/injectable-react";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable"; import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
import kubeObjectDetailItemsInjectable from "./kube-object-detail-items/kube-object-detail-items.injectable"; import kubeObjectDetailItemsInjectable
import type { CurrentKubeObject } from "./current-kube-object-in-details.injectable"; from "./kube-object-detail-items/kube-object-detail-items.injectable";
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable"; import type {
KubeObjectDetailsItemComputed,
} from "./current-kube-object-in-details.injectable";
import {
currentKubeObjectInDetailsInjectable2,
} from "./current-kube-object-in-details.injectable";
export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> { export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
className?: string; className?: string;
@ -27,7 +31,7 @@ export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
interface Dependencies { interface Dependencies {
detailComponents: IComputedValue<React.ElementType[]>; detailComponents: IComputedValue<React.ElementType[]>;
kubeObject: IAsyncComputed<CurrentKubeObject>; kubeObject: KubeObjectDetailsItemComputed;
hideDetails: HideDetails; hideDetails: HideDetails;
} }
@ -38,36 +42,27 @@ const NonInjectedKubeObjectDetails = observer((props: Dependencies) => {
kubeObject, kubeObject,
} = props; } = props;
const currentKubeObject = kubeObject.value.get(); const object = kubeObject.get();
const isLoading = kubeObject.pending.get();
return ( return (
<Drawer <Drawer
className="KubeObjectDetails flex column" className="KubeObjectDetails flex column"
open={Boolean(isLoading || currentKubeObject)} open={!!object}
title={( title={
currentKubeObject?.object object instanceof KubeObject ? `${object.kind}: ${object.getName()}` : ""
? `${currentKubeObject.object.kind}: ${currentKubeObject.object.getName()}` }
: "" toolbar={object && <KubeObjectMenu object={object as KubeObject} toolbar />}
)}
toolbar={currentKubeObject?.object && <KubeObjectMenu object={currentKubeObject.object} toolbar={true}/>}
onClose={hideDetails} onClose={hideDetails}
> >
{isLoading && <Spinner center/>} {!object && <Spinner center />}
{currentKubeObject?.error && ( {object instanceof Error && (
<div className="box center"> <div className="box center">
Resource loading has failed: Resource loading has failed:
<b>{currentKubeObject.error}</b> <b>{object}</b>
</div> </div>
)} )}
{currentKubeObject?.object && ( {object && detailComponents.get()
<> .map((Component, index) => <Component key={index} object={object} />)}
{
detailComponents.get()
.map((Component, index) => <Component key={index} object={currentKubeObject.object} />)
}
</>
)}
</Drawer> </Drawer>
); );
}); });
@ -77,6 +72,6 @@ export const KubeObjectDetails = withInjectables<Dependencies>(NonInjectedKubeOb
...props, ...props,
hideDetails: di.inject(hideDetailsInjectable), hideDetails: di.inject(hideDetailsInjectable),
detailComponents: di.inject(kubeObjectDetailItemsInjectable), detailComponents: di.inject(kubeObjectDetailItemsInjectable),
kubeObject: di.inject(currentKubeObjectInDetailsInjectable), kubeObject: di.inject(currentKubeObjectInDetailsInjectable2),
}), }),
}); });