mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Support Events on CustomResourece details panel
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
33e6771da3
commit
718834212e
@ -16,7 +16,6 @@ import type { HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricTa
|
|||||||
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
|
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
@ -121,8 +120,6 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="HpaDetails">
|
<div className="HpaDetails">
|
||||||
<KubeObjectMeta object={hpa}/>
|
|
||||||
|
|
||||||
<DrawerItem name="Reference">
|
<DrawerItem name="Reference">
|
||||||
{scaleTargetRef && (
|
{scaleTargetRef && (
|
||||||
<Link to={getDetailsUrl(apiManager.lookupApiLink(scaleTargetRef, hpa))}>
|
<Link to={getDetailsUrl(apiManager.lookupApiLink(scaleTargetRef, hpa))}>
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { cssNames } from "../../utils";
|
|||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
import type { KubeObjectDetailsProps } from "../kube-object-details";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
import type { AdditionalPrinterColumnsV1 } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import type { AdditionalPrinterColumnsV1 } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
import { CustomResourceDefinition } from "../../../common/k8s-api/endpoints/custom-resource-definition.api";
|
||||||
@ -21,7 +20,7 @@ import { KubeObject } from "../../../common/k8s-api/kube-object";
|
|||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
|
|
||||||
export interface CustomResourceDetailsProps extends KubeObjectDetailsProps<KubeObject> {
|
export interface CustomResourceDetailsProps extends KubeObjectDetailsProps<KubeObject> {
|
||||||
crd: CustomResourceDefinition;
|
crd?: CustomResourceDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertSpecValue(value: unknown): React.ReactNode {
|
function convertSpecValue(value: unknown): React.ReactNode {
|
||||||
@ -129,7 +128,6 @@ export class CustomResourceDetails extends React.Component<CustomResourceDetails
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("CrdResourceDetails", crd.getResourceKind())}>
|
<div className={cssNames("CrdResourceDetails", crd.getResourceKind())}>
|
||||||
<KubeObjectMeta object={object} />
|
|
||||||
{this.renderAdditionalColumns(object, extraColumns)}
|
{this.renderAdditionalColumns(object, extraColumns)}
|
||||||
{this.renderStatus(object, extraColumns)}
|
{this.renderStatus(object, extraColumns)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -58,7 +58,7 @@ export class CustomResourceDefinitionStore extends KubeObjectStore<CustomResourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
getByObject(obj: KubeObject) {
|
getByObject(obj: KubeObject) {
|
||||||
if (!obj) return null;
|
if (!obj) return undefined;
|
||||||
const { kind, apiVersion } = obj;
|
const { kind, apiVersion } = obj;
|
||||||
|
|
||||||
return this.items.find(crd => (
|
return this.items.find(crd => (
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
|
|||||||
import { getDetailsUrl } from "../kube-detail-params";
|
import { getDetailsUrl } from "../kube-detail-params";
|
||||||
import type { Job } from "../../../common/k8s-api/endpoints";
|
import type { Job } from "../../../common/k8s-api/endpoints";
|
||||||
import { CronJob } from "../../../common/k8s-api/endpoints";
|
import { CronJob } from "../../../common/k8s-api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import logger from "../../../common/logger";
|
import logger from "../../../common/logger";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
import type { SubscribeStores } from "../../kube-watch-api/kube-watch-api";
|
||||||
@ -61,7 +60,6 @@ class NonInjectedCronJobDetails extends React.Component<CronJobDetailsProps & De
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="CronJobDetails">
|
<div className="CronJobDetails">
|
||||||
<KubeObjectMeta object={cronJob}/>
|
|
||||||
<DrawerItem name="Schedule">
|
<DrawerItem name="Schedule">
|
||||||
{
|
{
|
||||||
cronJob.isNeverRun()
|
cronJob.isNeverRun()
|
||||||
|
|||||||
@ -3,10 +3,15 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computed } from "mobx";
|
|
||||||
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
||||||
import loggerInjectable from "../../../common/logger.injectable";
|
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||||
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
|
|
||||||
|
export type CurrentKubeObject =
|
||||||
|
| undefined
|
||||||
|
| { object: KubeObject; error?: undefined }
|
||||||
|
| { object?: undefined; error: string };
|
||||||
|
|
||||||
const currentKubeObjectInDetailsInjectable = getInjectable({
|
const currentKubeObjectInDetailsInjectable = getInjectable({
|
||||||
id: "current-kube-object-in-details",
|
id: "current-kube-object-in-details",
|
||||||
@ -14,19 +19,21 @@ const currentKubeObjectInDetailsInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const urlParam = di.inject(kubeDetailsUrlParamInjectable);
|
const urlParam = di.inject(kubeDetailsUrlParamInjectable);
|
||||||
const apiManager = di.inject(apiManagerInjectable);
|
const apiManager = di.inject(apiManagerInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
|
||||||
|
|
||||||
return computed(() => {
|
return asyncComputed(async (): Promise<CurrentKubeObject> => {
|
||||||
const path = urlParam.get();
|
const path = urlParam.get();
|
||||||
|
const store = apiManager.getStore(path);
|
||||||
|
|
||||||
|
if (!store) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return apiManager.getStore(path)?.getByPath(path);
|
const object = await store.loadFromPath(path);
|
||||||
} catch (error) {
|
|
||||||
logger.error(
|
|
||||||
`[KUBE-OBJECT-DETAILS]: failed to get store or object ${path}: ${error}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return undefined;
|
return { object };
|
||||||
|
} catch (error) {
|
||||||
|
return { error: String(error) };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import React from "react";
|
||||||
|
import { CustomResourceDetails } from "../+custom-resources";
|
||||||
|
import customResourceDefinitionStoreInjectable from "../+custom-resources/definition.store.injectable";
|
||||||
|
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-items/kube-object-detail-item-injection-token";
|
||||||
|
|
||||||
|
const customResourceDetailItemInjectable = getInjectable({
|
||||||
|
id: "custom-resource-detail-item",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const customResourceDefinitionStore = di.inject(customResourceDefinitionStoreInjectable);
|
||||||
|
const currentKubeObjectInDetails = di.inject(currentKubeObjectInDetailsInjectable);
|
||||||
|
const currentCustomResourceDefinition = computed(() => {
|
||||||
|
const { object } = currentKubeObjectInDetails.value.get() ?? {};
|
||||||
|
|
||||||
|
if (!object) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return customResourceDefinitionStore.getByObject(object);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
Component: ({ object }) => <CustomResourceDetails object={object} crd={currentCustomResourceDefinition.get()} />,
|
||||||
|
enabled: computed(() => Boolean(currentCustomResourceDefinition.get())),
|
||||||
|
orderNumber: 100,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default customResourceDetailItemInjectable;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import { KubeObjectMeta } from "../kube-object-meta";
|
||||||
|
import { kubeObjectDetailItemInjectionToken } from "./kube-object-detail-items/kube-object-detail-item-injection-token";
|
||||||
|
|
||||||
|
const defaultKubeObjectMetaDetailsItemInjectable = getInjectable({
|
||||||
|
id: "default-kube-object-meta-details-item",
|
||||||
|
instantiate: () => ({
|
||||||
|
Component: KubeObjectMeta,
|
||||||
|
enabled: computed(() => true),
|
||||||
|
orderNumber: -Infinity,
|
||||||
|
}),
|
||||||
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defaultKubeObjectMetaDetailsItemInjectable;
|
||||||
@ -17,7 +17,7 @@ const clusterRoleBindingDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ClusterRoleBindingDetails,
|
Component: ClusterRoleBindingDetails,
|
||||||
enabled: computed(() => isClusterRoleBinding(kubeObject.get())),
|
enabled: computed(() => isClusterRoleBinding(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const clusterRoleDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ClusterRoleDetails,
|
Component: ClusterRoleDetails,
|
||||||
enabled: computed(() => isClusterRole(kubeObject.get())),
|
enabled: computed(() => isClusterRole(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const configMapDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ConfigMapDetails,
|
Component: ConfigMapDetails,
|
||||||
enabled: computed(() => isConfigMap(kubeObject.get())),
|
enabled: computed(() => isConfigMap(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const cronJobDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: CronJobDetails,
|
Component: CronJobDetails,
|
||||||
enabled: computed(() => isCronJob(kubeObject.get())),
|
enabled: computed(() => isCronJob(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const customResourceDefinitionsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: CRDDetails,
|
Component: CRDDetails,
|
||||||
enabled: computed(() => isCustomResourceDefinition(kubeObject.get())),
|
enabled: computed(() => isCustomResourceDefinition(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const daemonSetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: DaemonSetDetails,
|
Component: DaemonSetDetails,
|
||||||
enabled: computed(() => isDaemonSet(kubeObject.get())),
|
enabled: computed(() => isDaemonSet(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const deploymentDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: DeploymentDetails,
|
Component: DeploymentDetails,
|
||||||
enabled: computed(() => isDeployment(kubeObject.get())),
|
enabled: computed(() => isDeployment(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const endpointsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: EndpointsDetails,
|
Component: EndpointsDetails,
|
||||||
enabled: computed(() => isEndpoint(kubeObject.get())),
|
enabled: computed(() => isEndpoint(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const eventsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: EventDetails,
|
Component: EventDetails,
|
||||||
enabled: computed(() => isEvent(kubeObject.get())),
|
enabled: computed(() => isEvent(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const horizontalPodAutoscalerDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: HpaDetails,
|
Component: HpaDetails,
|
||||||
enabled: computed(() => isHorizontalPodAutoscaler(kubeObject.get())),
|
enabled: computed(() => isHorizontalPodAutoscaler(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const ingressDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: IngressDetails,
|
Component: IngressDetails,
|
||||||
enabled: computed(() => isIngress(kubeObject.get())),
|
enabled: computed(() => isIngress(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const jobDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: JobDetails,
|
Component: JobDetails,
|
||||||
enabled: computed(() => isJob(kubeObject.get())),
|
enabled: computed(() => isJob(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -6,77 +6,15 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
|
||||||
import { KubeEventDetails } from "../../../+events/kube-event-details";
|
import { KubeEventDetails } from "../../../+events/kube-event-details";
|
||||||
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
|
|
||||||
import { isClusterRole } from "./cluster-role-detail-item.injectable";
|
|
||||||
import { isClusterRoleBinding } from "./cluster-role-binding-detail-item.injectable";
|
|
||||||
import { isCronJob } from "./cron-job-detail-item.injectable";
|
|
||||||
import { isDaemonSet } from "./daemon-set-detail-item.injectable";
|
|
||||||
import { isDeployment } from "./deployment-detail-item.injectable";
|
|
||||||
import { isEndpoint } from "./endpoints-detail-item.injectable";
|
|
||||||
import { isHorizontalPodAutoscaler } from "./horizontal-pod-autoscaler-detail-item.injectable";
|
|
||||||
import { isIngress } from "./ingress-detail-item.injectable";
|
|
||||||
import { isJob } from "./job-detail-item.injectable";
|
|
||||||
import { isNetworkPolicy } from "./network-policy-detail-item.injectable";
|
|
||||||
import { isPersistentVolume } from "./persistent-volume-detail-item.injectable";
|
|
||||||
import { isPersistentVolumeClaim } from "./persistent-volume-claim-detail-item.injectable";
|
|
||||||
import { isNode } from "./node-detail-item.injectable";
|
|
||||||
import { isPod } from "./pod-detail-item.injectable";
|
|
||||||
import { isReplicaSet } from "./replica-set-detail-item.injectable";
|
|
||||||
import { isRole } from "./role-detail-item.injectable";
|
|
||||||
import { isRoleBinding } from "./role-binding-detail-item.injectable";
|
|
||||||
import { isService } from "./service-detail-item.injectable";
|
|
||||||
import { isServiceAccount } from "./service-account-detail-item.injectable";
|
|
||||||
import { isStatefulSet } from "./stateful-set-detail-item.injectable";
|
|
||||||
import { isStorageClass } from "./storage-class-detail-item.injectable";
|
|
||||||
|
|
||||||
const kubeEventDetailItemInjectable = getInjectable({
|
const kubeEventDetailItemInjectable = getInjectable({
|
||||||
id: "kube-event-detail-item",
|
id: "kube-event-detail-item",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: () => ({
|
||||||
const currentKubeObjectInDetails = di.inject(
|
Component: KubeEventDetails,
|
||||||
currentKubeObjectInDetailsInjectable,
|
enabled: computed(() => true),
|
||||||
);
|
orderNumber: Infinity,
|
||||||
|
}),
|
||||||
return {
|
|
||||||
Component: KubeEventDetails,
|
|
||||||
|
|
||||||
enabled: computed(() => {
|
|
||||||
const kubeObject = currentKubeObjectInDetails.get();
|
|
||||||
|
|
||||||
if (!kubeObject) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const predicates = [
|
|
||||||
isClusterRole,
|
|
||||||
isClusterRoleBinding,
|
|
||||||
isCronJob,
|
|
||||||
isDaemonSet,
|
|
||||||
isDeployment,
|
|
||||||
isEndpoint,
|
|
||||||
isHorizontalPodAutoscaler,
|
|
||||||
isIngress,
|
|
||||||
isJob,
|
|
||||||
isNetworkPolicy,
|
|
||||||
isNode,
|
|
||||||
isPersistentVolume,
|
|
||||||
isPersistentVolumeClaim,
|
|
||||||
isPod,
|
|
||||||
isReplicaSet,
|
|
||||||
isRole,
|
|
||||||
isRoleBinding,
|
|
||||||
isService,
|
|
||||||
isServiceAccount,
|
|
||||||
isStatefulSet,
|
|
||||||
isStorageClass,
|
|
||||||
];
|
|
||||||
|
|
||||||
return predicates.some((predicate) => predicate(kubeObject));
|
|
||||||
}),
|
|
||||||
|
|
||||||
orderNumber: 355,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
injectionToken: kubeObjectDetailItemInjectionToken,
|
injectionToken: kubeObjectDetailItemInjectionToken,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const leaseDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: LeaseDetails,
|
Component: LeaseDetails,
|
||||||
enabled: computed(() => isLease(kubeObject.get())),
|
enabled: computed(() => isLease(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const limitRangeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: LimitRangeDetails,
|
Component: LimitRangeDetails,
|
||||||
enabled: computed(() => isLimitRange(kubeObject.get())),
|
enabled: computed(() => isLimitRange(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const namespacesDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NamespaceDetails,
|
Component: NamespaceDetails,
|
||||||
enabled: computed(() => isNamespace(kubeObject.get())),
|
enabled: computed(() => isNamespace(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const networkPolicyDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NetworkPolicyDetails,
|
Component: NetworkPolicyDetails,
|
||||||
enabled: computed(() => isNetworkPolicy(kubeObject.get())),
|
enabled: computed(() => isNetworkPolicy(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const nodeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: NodeDetails,
|
Component: NodeDetails,
|
||||||
enabled: computed(() => isNode(kubeObject.get())),
|
enabled: computed(() => isNode(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const persistentVolumeClaimDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PersistentVolumeClaimDetails,
|
Component: PersistentVolumeClaimDetails,
|
||||||
enabled: computed(() => isPersistentVolumeClaim(kubeObject.get())),
|
enabled: computed(() => isPersistentVolumeClaim(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const persistentVolumeDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PersistentVolumeDetails,
|
Component: PersistentVolumeDetails,
|
||||||
enabled: computed(() => isPersistentVolume(kubeObject.get())),
|
enabled: computed(() => isPersistentVolume(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const podDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PodDetails,
|
Component: PodDetails,
|
||||||
enabled: computed(() => isPod(kubeObject.get())),
|
enabled: computed(() => isPod(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const podDisruptionBudgetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PodDisruptionBudgetDetails,
|
Component: PodDisruptionBudgetDetails,
|
||||||
enabled: computed(() => isPodDisruptionBudget(kubeObject.get())),
|
enabled: computed(() => isPodDisruptionBudget(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const podSecurityPolicyDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PodSecurityPolicyDetails,
|
Component: PodSecurityPolicyDetails,
|
||||||
enabled: computed(() => isPodSecurityPolicy(kubeObject.get())),
|
enabled: computed(() => isPodSecurityPolicy(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const priorityClassDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: PriorityClassesDetails,
|
Component: PriorityClassesDetails,
|
||||||
enabled: computed(() => isPriorityClass(kubeObject.get())),
|
enabled: computed(() => isPriorityClass(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const replicaSetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ReplicaSetDetails,
|
Component: ReplicaSetDetails,
|
||||||
enabled: computed(() => isReplicaSet(kubeObject.get())),
|
enabled: computed(() => isReplicaSet(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const resourceQuotaDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ResourceQuotaDetails,
|
Component: ResourceQuotaDetails,
|
||||||
enabled: computed(() => isResourceQuota(kubeObject.get())),
|
enabled: computed(() => isResourceQuota(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const roleBindingDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: RoleBindingDetails,
|
Component: RoleBindingDetails,
|
||||||
enabled: computed(() => isRoleBinding(kubeObject.get())),
|
enabled: computed(() => isRoleBinding(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const roleDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: RoleDetails,
|
Component: RoleDetails,
|
||||||
enabled: computed(() => isRole(kubeObject.get())),
|
enabled: computed(() => isRole(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const runtimeClassDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: RuntimeClassesDetails,
|
Component: RuntimeClassesDetails,
|
||||||
enabled: computed(() => isRuntimeClass(kubeObject.get())),
|
enabled: computed(() => isRuntimeClass(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const secretsDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: SecretDetails,
|
Component: SecretDetails,
|
||||||
enabled: computed(() => isSecret(kubeObject.get())),
|
enabled: computed(() => isSecret(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const serviceAccountDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ServiceAccountsDetails,
|
Component: ServiceAccountsDetails,
|
||||||
enabled: computed(() => isServiceAccount(kubeObject.get())),
|
enabled: computed(() => isServiceAccount(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const serviceDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: ServiceDetails,
|
Component: ServiceDetails,
|
||||||
enabled: computed(() => isService(kubeObject.get())),
|
enabled: computed(() => isService(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const statefulSetDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: StatefulSetDetails,
|
Component: StatefulSetDetails,
|
||||||
enabled: computed(() => isStatefulSet(kubeObject.get())),
|
enabled: computed(() => isStatefulSet(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const storageClassDetailItemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
Component: StorageClassDetails,
|
Component: StorageClassDetails,
|
||||||
enabled: computed(() => isStorageClass(kubeObject.get())),
|
enabled: computed(() => isStorageClass(kubeObject.value.get()?.object)),
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -55,7 +55,7 @@ const kubeObjectDetailItemRegistratorInjectable = getInjectable({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRelevantKubeObject(kubeObject.get())) {
|
if (!isRelevantKubeObject(kubeObject.value.get()?.object)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,25 +6,18 @@
|
|||||||
import "./kube-object-details.scss";
|
import "./kube-object-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { observable, reaction, makeObservable } from "mobx";
|
|
||||||
import { Drawer } from "../drawer";
|
import { Drawer } from "../drawer";
|
||||||
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
import type { KubeObject } from "../../../common/k8s-api/kube-object";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import type { ApiManager } from "../../../common/k8s-api/api-manager";
|
|
||||||
import { KubeObjectMenu } from "../kube-object-menu";
|
import { KubeObjectMenu } from "../kube-object-menu";
|
||||||
import { CustomResourceDetails } from "../+custom-resources";
|
|
||||||
import { KubeObjectMeta } from "../kube-object-meta";
|
|
||||||
import type { PageParam } from "../../navigation";
|
|
||||||
import type { HideDetails } from "../kube-detail-params/hide-details.injectable";
|
import type { HideDetails } from "../kube-detail-params/hide-details.injectable";
|
||||||
import type { CustomResourceDefinitionStore } from "../+custom-resources/definition.store";
|
import type { IAsyncComputed } from "@ogre-tools/injectable-react";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
|
|
||||||
import customResourceDefinitionStoreInjectable from "../+custom-resources/definition.store.injectable";
|
|
||||||
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
import hideDetailsInjectable from "../kube-detail-params/hide-details.injectable";
|
||||||
import kubeDetailsUrlParamInjectable from "../kube-detail-params/kube-details-url.injectable";
|
|
||||||
import kubeObjectDetailItemsInjectable from "./kube-object-detail-items/kube-object-detail-items.injectable";
|
import kubeObjectDetailItemsInjectable from "./kube-object-detail-items/kube-object-detail-items.injectable";
|
||||||
|
import type { CurrentKubeObject } from "./current-kube-object-in-details.injectable";
|
||||||
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable";
|
import currentKubeObjectInDetailsInjectable from "./current-kube-object-in-details.injectable";
|
||||||
|
|
||||||
export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
||||||
@ -34,128 +27,55 @@ export interface KubeObjectDetailsProps<Kube extends KubeObject = KubeObject> {
|
|||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
detailComponents: IComputedValue<React.ElementType[]>;
|
detailComponents: IComputedValue<React.ElementType[]>;
|
||||||
kubeObject: IComputedValue<KubeObject | undefined>;
|
kubeObject: IAsyncComputed<CurrentKubeObject>;
|
||||||
kubeDetailsUrlParam: PageParam<string>;
|
|
||||||
apiManager: ApiManager;
|
|
||||||
hideDetails: HideDetails;
|
hideDetails: HideDetails;
|
||||||
customResourceDefinitionStore: CustomResourceDefinitionStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
const NonInjectedKubeObjectDetails = observer((props: Dependencies) => {
|
||||||
class NonInjectedKubeObjectDetails extends React.Component<Dependencies> {
|
const {
|
||||||
@observable isLoading = false;
|
detailComponents,
|
||||||
@observable.ref loadingError: React.ReactNode;
|
hideDetails,
|
||||||
|
kubeObject,
|
||||||
|
} = props;
|
||||||
|
|
||||||
constructor(props: Dependencies) {
|
const currentKubeObject = kubeObject.value.get();
|
||||||
super(props);
|
const isLoading = kubeObject.pending.get();
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
get path() {
|
return (
|
||||||
return this.props.kubeDetailsUrlParam.get();
|
<Drawer
|
||||||
}
|
className="KubeObjectDetails flex column"
|
||||||
|
open={Boolean(isLoading || currentKubeObject)}
|
||||||
get object() {
|
title={(
|
||||||
return this.props.kubeObject.get();
|
currentKubeObject?.object
|
||||||
}
|
? `${currentKubeObject.object.kind}: ${currentKubeObject.object.getName()}`
|
||||||
|
: ""
|
||||||
componentDidMount(): void {
|
)}
|
||||||
disposeOnUnmount(this, [
|
toolbar={currentKubeObject?.object && <KubeObjectMenu object={currentKubeObject.object} toolbar={true}/>}
|
||||||
reaction(() => [
|
onClose={hideDetails}
|
||||||
this.path,
|
>
|
||||||
this.object, // resource might be updated via watch-event or from already opened details
|
{isLoading && <Spinner center/>}
|
||||||
this.props.customResourceDefinitionStore.items.length, // crd stores initialized after loading
|
{currentKubeObject?.error && (
|
||||||
], async () => {
|
<div className="box center">
|
||||||
this.loadingError = "";
|
Resource loading has failed:
|
||||||
const { path, object } = this;
|
<b>{currentKubeObject.error}</b>
|
||||||
|
</div>
|
||||||
if (!object) {
|
)}
|
||||||
const store = this.props.apiManager.getStore(path);
|
{currentKubeObject?.object && (
|
||||||
|
<>
|
||||||
if (store) {
|
{
|
||||||
this.isLoading = true;
|
detailComponents.get()
|
||||||
|
.map((Component, index) => <Component key={index} object={currentKubeObject.object} />)
|
||||||
try {
|
|
||||||
await store.loadFromPath(path);
|
|
||||||
} catch (err) {
|
|
||||||
this.loadingError = (
|
|
||||||
<>
|
|
||||||
Resource loading has failed:
|
|
||||||
<b>{String(err)}</b>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
</>
|
||||||
}),
|
)}
|
||||||
]);
|
</Drawer>
|
||||||
}
|
);
|
||||||
|
});
|
||||||
renderTitle(object: KubeObject | null | undefined) {
|
|
||||||
if (!object) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${object.kind}: ${object.getName()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderContents(object: KubeObject) {
|
|
||||||
const details = this.props.detailComponents.get();
|
|
||||||
|
|
||||||
if (details.length === 0) {
|
|
||||||
const crd = this.props.customResourceDefinitionStore.getByObject(object);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a fallback so that if a custom resource object doesn't have
|
|
||||||
* any defined details we should try and display at least some details
|
|
||||||
*/
|
|
||||||
if (crd) {
|
|
||||||
return (
|
|
||||||
<CustomResourceDetails
|
|
||||||
key={object.getId()}
|
|
||||||
object={object}
|
|
||||||
crd={crd}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// if we still don't have any details to show, just show the standard object metadata
|
|
||||||
return <KubeObjectMeta key={object.getId()} object={object} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return details.map((DetailComponent, index) => (
|
|
||||||
<DetailComponent key={index} object={object} />
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { object, isLoading, loadingError } = this;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Drawer
|
|
||||||
className="KubeObjectDetails flex column"
|
|
||||||
open={!!(object || isLoading || loadingError)}
|
|
||||||
title={this.renderTitle(object)}
|
|
||||||
toolbar={object && <KubeObjectMenu object={object} toolbar={true}/>}
|
|
||||||
onClose={this.props.hideDetails}
|
|
||||||
>
|
|
||||||
{isLoading && <Spinner center/>}
|
|
||||||
{loadingError && <div className="box center">{loadingError}</div>}
|
|
||||||
{object && this.renderContents(object)}
|
|
||||||
</Drawer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const KubeObjectDetails = withInjectables<Dependencies>(NonInjectedKubeObjectDetails, {
|
export const KubeObjectDetails = withInjectables<Dependencies>(NonInjectedKubeObjectDetails, {
|
||||||
getProps: (di, props) => ({
|
getProps: (di, props) => ({
|
||||||
...props,
|
...props,
|
||||||
apiManager: di.inject(apiManagerInjectable),
|
|
||||||
customResourceDefinitionStore: di.inject(customResourceDefinitionStoreInjectable),
|
|
||||||
hideDetails: di.inject(hideDetailsInjectable),
|
hideDetails: di.inject(hideDetailsInjectable),
|
||||||
kubeDetailsUrlParam: di.inject(kubeDetailsUrlParamInjectable),
|
|
||||||
detailComponents: di.inject(kubeObjectDetailItemsInjectable),
|
detailComponents: di.inject(kubeObjectDetailItemsInjectable),
|
||||||
kubeObject: di.inject(currentKubeObjectInDetailsInjectable),
|
kubeObject: di.inject(currentKubeObjectInDetailsInjectable),
|
||||||
}),
|
}),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user