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

replace all the rest of the legacy uses of apiManager

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-22 16:34:38 -04:00
parent 30f473a69a
commit 375018c330
10 changed files with 317 additions and 198 deletions

View File

@ -4,4 +4,3 @@
*/ */
export * from "./api-manager"; export * from "./api-manager";
export * from "./legacy-global";

View File

@ -8,7 +8,6 @@
import { isFunction, merge } from "lodash"; import { isFunction, merge } from "lodash";
import { stringify } from "querystring"; import { stringify } from "querystring";
import { apiKubePrefix, isDevelopment } from "../../common/vars"; import { apiKubePrefix, isDevelopment } from "../../common/vars";
import { apiManager } from "./api-manager";
import { apiBase, apiKube } from "./index"; import { apiBase, apiKube } from "./index";
import { createKubeApiURL, parseKubeApi } from "./kube-api-parse"; import { createKubeApiURL, parseKubeApi } from "./kube-api-parse";
import type { KubeObjectConstructor, KubeJsonApiDataFor, KubeObjectMetadata, KubeObjectScope } from "./kube-object"; import type { KubeObjectConstructor, KubeJsonApiDataFor, KubeObjectMetadata, KubeObjectScope } from "./kube-object";
@ -27,6 +26,8 @@ import type { Patch } from "rfc6902";
import assert from "assert"; import assert from "assert";
import type { PartialDeep } from "type-fest"; import type { PartialDeep } from "type-fest";
import logger from "../logger"; import logger from "../logger";
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import apiManagerInjectable from "./api-manager/manager.injectable";
/** /**
* The options used for creating a `KubeApi` * The options used for creating a `KubeApi`
@ -307,6 +308,22 @@ export interface DeleteResourceDescriptor extends ResourceDescriptor {
propagationPolicy?: PropagationPolicy; propagationPolicy?: PropagationPolicy;
} }
/**
* @deprecated In the new extension API, don't expose `KubeApi`'s constructor
*/
function legacyRegisterApi(apiBase: string, api: KubeApi): void {
// Try both just in case, because we might be in a testing environment
for (const env of [Environments.main, Environments.renderer]) {
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(env);
if (di) {
const apiManager = di.inject(apiManagerInjectable);
apiManager.registerApi(apiBase, api);
}
}
}
export class KubeApi< export class KubeApi<
Object extends KubeObject = KubeObject, Object extends KubeObject = KubeObject,
Data extends KubeJsonApiDataFor<Object> = KubeJsonApiDataFor<Object>, Data extends KubeJsonApiDataFor<Object> = KubeJsonApiDataFor<Object>,
@ -359,7 +376,7 @@ export class KubeApi<
this.request = request; this.request = request;
this.objectConstructor = objectConstructor; this.objectConstructor = objectConstructor;
this.parseResponse = this.parseResponse.bind(this); this.parseResponse = this.parseResponse.bind(this);
apiManager.registerApi<KubeApi<Object, Data>>(apiBase, this); legacyRegisterApi(apiBase, this as unknown as KubeApi);
} }
get apiVersionWithGroup() { get apiVersionWithGroup() {
@ -440,7 +457,7 @@ export class KubeApi<
if (this.apiVersionPreferred) { if (this.apiVersionPreferred) {
this.apiBase = this.computeApiBase(); this.apiBase = this.computeApiBase();
apiManager.registerApi<KubeApi<Object, Data>>(this.apiBase, this); legacyRegisterApi(this.apiBase, this as unknown as KubeApi);
} }
} }
} }

View File

@ -3,7 +3,6 @@
* 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 type { DiContainer } from "@ogre-tools/injectable"; import type { DiContainer } from "@ogre-tools/injectable";
import assert from "assert";
import { iter } from "../../common/utils"; import { iter } from "../../common/utils";
const legacyGlobalDis = new Map<Environments, DiContainer>(); const legacyGlobalDis = new Map<Environments, DiContainer>();
@ -35,9 +34,5 @@ export const getLegacyGlobalDiForExtensionApi = () => {
}; };
export function getEnvironmentSpecificLegacyGlobalDiForExtensionApi(environment: Environments) { export function getEnvironmentSpecificLegacyGlobalDiForExtensionApi(environment: Environments) {
const di = legacyGlobalDis.get(environment); return legacyGlobalDis.get(environment);
assert(di, `missing di for environment=${Environments[environment]}`);
return di;
} }

View File

@ -15,22 +15,30 @@ import { cssNames } from "../../utils";
import type { HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricTarget } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api"; import type { HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricTarget } from "../../../common/k8s-api/endpoints/horizontal-pod-autoscaler.api";
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 { apiManager } from "../../../common/k8s-api/api-manager"; import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { KubeObjectMeta } from "../kube-object-meta"; import { KubeObjectMeta } from "../kube-object-meta";
import { getDetailsUrl } from "../kube-detail-params";
import logger from "../../../common/logger"; import logger from "../../../common/logger";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
export interface HpaDetailsProps extends KubeObjectDetailsProps<HorizontalPodAutoscaler> { export interface HpaDetailsProps extends KubeObjectDetailsProps<HorizontalPodAutoscaler> {
} }
interface Dependencies {
apiManager: ApiManager;
getDetailsUrl: GetDetailsUrl;
}
@observer @observer
export class HpaDetails extends React.Component<HpaDetailsProps> { class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependencies> {
private renderTargetLink(target: HorizontalPodAutoscalerMetricTarget | undefined) { private renderTargetLink(target: HorizontalPodAutoscalerMetricTarget | undefined) {
if (!target) { if (!target) {
return null; return null;
} }
const { object: hpa } = this.props; const { object: hpa, apiManager, getDetailsUrl } = this.props;
const { kind, name } = target; const { kind, name } = target;
const objectUrl = getDetailsUrl(apiManager.lookupApiLink(target, hpa)); const objectUrl = getDetailsUrl(apiManager.lookupApiLink(target, hpa));
@ -119,7 +127,7 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
} }
render() { render() {
const { object: hpa } = this.props; const { object: hpa, apiManager, getDetailsUrl } = this.props;
if (!hpa) { if (!hpa) {
return null; return null;
@ -183,3 +191,11 @@ export class HpaDetails extends React.Component<HpaDetailsProps> {
); );
} }
} }
export const HpaDetails = withInjectables<Dependencies, HpaDetailsProps>(NonInjectedHpaDetails, {
getProps: (di, props) => ({
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
}),
});

View File

@ -14,78 +14,95 @@ import type { KubeObjectDetailsProps } from "../kube-object-details";
import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api"; import { KubeEvent } from "../../../common/k8s-api/endpoints/events.api";
import { KubeObjectMeta } from "../kube-object-meta"; import { KubeObjectMeta } from "../kube-object-meta";
import { Table, TableCell, TableHead, TableRow } from "../table"; import { Table, TableCell, TableHead, TableRow } from "../table";
import { getDetailsUrl } from "../kube-detail-params"; import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { apiManager } from "../../../common/k8s-api/api-manager";
import logger from "../../../common/logger"; import logger from "../../../common/logger";
import { DurationAbsoluteTimestamp } from "./duration-absolute"; import { DurationAbsoluteTimestamp } from "./duration-absolute";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import { cssNames } from "../../utils";
export interface EventDetailsProps extends KubeObjectDetailsProps<KubeEvent> { export interface EventDetailsProps extends KubeObjectDetailsProps<KubeEvent> {
} }
@observer interface Dependencies {
export class EventDetails extends React.Component<EventDetailsProps> { getDetailsUrl: GetDetailsUrl;
render() { apiManager: ApiManager;
const { object: event } = this.props;
if (!event) {
return null;
}
if (!(event instanceof KubeEvent)) {
logger.error("[EventDetails]: passed object that is not an instanceof KubeEvent", event);
return null;
}
const { message, reason, count, type, involvedObject } = event;
const { kind, name, namespace, fieldPath } = involvedObject;
return (
<div className="EventDetails">
<KubeObjectMeta object={event}/>
<DrawerItem name="Message">
{message}
</DrawerItem>
<DrawerItem name="Reason">
{reason}
</DrawerItem>
<DrawerItem name="Source">
{event.getSource()}
</DrawerItem>
<DrawerItem name="First seen">
<DurationAbsoluteTimestamp timestamp={event.firstTimestamp} />
</DrawerItem>
<DrawerItem name="Last seen">
<DurationAbsoluteTimestamp timestamp={event.lastTimestamp} />
</DrawerItem>
<DrawerItem name="Count">
{count}
</DrawerItem>
<DrawerItem name="Type" className="type">
<span className={kebabCase(type)}>{type}</span>
</DrawerItem>
<DrawerTitle>Involved object</DrawerTitle>
<Table>
<TableHead>
<TableCell>Name</TableCell>
<TableCell>Namespace</TableCell>
<TableCell>Kind</TableCell>
<TableCell>Field Path</TableCell>
</TableHead>
<TableRow>
<TableCell>
<Link to={getDetailsUrl(apiManager.lookupApiLink(involvedObject, event))}>
{name}
</Link>
</TableCell>
<TableCell>{namespace}</TableCell>
<TableCell>{kind}</TableCell>
<TableCell>{fieldPath}</TableCell>
</TableRow>
</Table>
</div>
);
}
} }
const NonInjectedEventDetails = observer(({
apiManager,
getDetailsUrl,
object: event,
className,
}: Dependencies & EventDetailsProps) => {
if (!event) {
return null;
}
if (!(event instanceof KubeEvent)) {
logger.error("[EventDetails]: passed object that is not an instanceof KubeEvent", event);
return null;
}
const { message, reason, count, type, involvedObject } = event;
const { kind, name, namespace, fieldPath } = involvedObject;
return (
<div className={cssNames("EventDetails", className)}>
<KubeObjectMeta object={event}/>
<DrawerItem name="Message">
{message}
</DrawerItem>
<DrawerItem name="Reason">
{reason}
</DrawerItem>
<DrawerItem name="Source">
{event.getSource()}
</DrawerItem>
<DrawerItem name="First seen">
<DurationAbsoluteTimestamp timestamp={event.firstTimestamp} />
</DrawerItem>
<DrawerItem name="Last seen">
<DurationAbsoluteTimestamp timestamp={event.lastTimestamp} />
</DrawerItem>
<DrawerItem name="Count">
{count}
</DrawerItem>
<DrawerItem name="Type" className="type">
<span className={kebabCase(type)}>{type}</span>
</DrawerItem>
<DrawerTitle>Involved object</DrawerTitle>
<Table>
<TableHead>
<TableCell>Name</TableCell>
<TableCell>Namespace</TableCell>
<TableCell>Kind</TableCell>
<TableCell>Field Path</TableCell>
</TableHead>
<TableRow>
<TableCell>
<Link to={getDetailsUrl(apiManager.lookupApiLink(involvedObject, event))}>
{name}
</Link>
</TableCell>
<TableCell>{namespace}</TableCell>
<TableCell>{kind}</TableCell>
<TableCell>{fieldPath}</TableCell>
</TableRow>
</Table>
</div>
);
});
export const EventDetails = withInjectables<Dependencies, EventDetailsProps>(NonInjectedEventDetails, {
getProps: (di, props) => ({
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
}),
});

View File

@ -22,9 +22,8 @@ import { Table, TableCell, TableHead, TableRow } from "../../table";
import { Button } from "../../button"; import { Button } from "../../button";
import { Notifications } from "../../notifications"; import { Notifications } from "../../notifications";
import type { ThemeStore } from "../../../themes/store"; import type { ThemeStore } from "../../../themes/store";
import { apiManager } from "../../../../common/k8s-api/api-manager"; import type { ApiManager } from "../../../../common/k8s-api/api-manager";
import { SubTitle } from "../../layout/sub-title"; import { SubTitle } from "../../layout/sub-title";
import { getDetailsUrl } from "../../kube-detail-params";
import { Checkbox } from "../../checkbox"; import { Checkbox } from "../../checkbox";
import { MonacoEditor } from "../../monaco-editor"; import { MonacoEditor } from "../../monaco-editor";
import type { IAsyncComputed } from "@ogre-tools/injectable-react"; import type { IAsyncComputed } from "@ogre-tools/injectable-react";
@ -39,6 +38,9 @@ import { KubeObjectAge } from "../../kube-object/age";
import type { KubeJsonApiData } from "../../../../common/k8s-api/kube-json-api"; import type { KubeJsonApiData } from "../../../../common/k8s-api/kube-json-api";
import { entries } from "../../../../common/utils/objects"; import { entries } from "../../../../common/utils/objects";
import themeStoreInjectable from "../../../themes/store.injectable"; import themeStoreInjectable from "../../../themes/store.injectable";
import type { GetDetailsUrl } from "../../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../../kube-detail-params/get-details-url.injectable";
export interface ReleaseDetailsProps { export interface ReleaseDetailsProps {
hideDetails(): void; hideDetails(): void;
@ -52,6 +54,8 @@ interface Dependencies {
createUpgradeChartTab: (release: HelmRelease) => void; createUpgradeChartTab: (release: HelmRelease) => void;
userSuppliedValuesAreShown: { toggle: () => void; value: boolean }; userSuppliedValuesAreShown: { toggle: () => void; value: boolean };
themeStore: ThemeStore; themeStore: ThemeStore;
apiManager: ApiManager;
getDetailsUrl: GetDetailsUrl;
} }
@observer @observer
@ -158,6 +162,8 @@ class NonInjectedReleaseDetails extends Component<ReleaseDetailsProps & Dependen
} }
renderResources(resources: KubeJsonApiData[]) { renderResources(resources: KubeJsonApiData[]) {
const { apiManager, getDetailsUrl } = this.props;
return ( return (
<div className="resources"> <div className="resources">
{ {
@ -288,5 +294,7 @@ export const ReleaseDetails = withInjectables<Dependencies, ReleaseDetailsProps>
updateRelease: di.inject(updateReleaseInjectable), updateRelease: di.inject(updateReleaseInjectable),
createUpgradeChartTab: di.inject(createUpgradeChartTabInjectable), createUpgradeChartTab: di.inject(createUpgradeChartTabInjectable),
themeStore: di.inject(themeStoreInjectable), themeStore: di.inject(themeStoreInjectable),
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
}), }),
}); });

View File

@ -9,19 +9,27 @@ import React from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import type { EndpointSubset, Endpoints, EndpointAddress } from "../../../common/k8s-api/endpoints"; import type { EndpointSubset, Endpoints, EndpointAddress } from "../../../common/k8s-api/endpoints";
import { Table, TableCell, TableHead, TableRow } from "../table"; import { Table, TableCell, TableHead, TableRow } from "../table";
import { apiManager } from "../../../common/k8s-api/api-manager"; import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { getDetailsUrl } from "../kube-detail-params";
import { autoBind } from "../../../common/utils"; import { autoBind } from "../../../common/utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
export interface EndpointSubsetListProps { export interface EndpointSubsetListProps {
subset: Required<EndpointSubset>; subset: Required<EndpointSubset>;
endpoint: Endpoints; endpoint: Endpoints;
} }
interface Dependencies {
apiManager: ApiManager;
getDetailsUrl: GetDetailsUrl;
}
@observer @observer
export class EndpointSubsetList extends React.Component<EndpointSubsetListProps> { class NonInjectedEndpointSubsetList extends React.Component<EndpointSubsetListProps & Dependencies> {
constructor(props: EndpointSubsetListProps) { constructor(props: EndpointSubsetListProps & Dependencies) {
super(props); super(props);
autoBind(this); autoBind(this);
} }
@ -68,7 +76,7 @@ export class EndpointSubsetList extends React.Component<EndpointSubsetListProps>
return undefined; return undefined;
} }
const { endpoint } = this.props; const { endpoint, getDetailsUrl, apiManager } = this.props;
return ( return (
<TableRow <TableRow
@ -166,3 +174,11 @@ export class EndpointSubsetList extends React.Component<EndpointSubsetListProps>
); );
} }
} }
export const EndpointSubsetList = withInjectables<Dependencies, EndpointSubsetListProps>(NonInjectedEndpointSubsetList, {
getProps: (di, props) => ({
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
}),
});

View File

@ -8,21 +8,26 @@ import "./pods.scss";
import React, { Fragment } from "react"; import React, { Fragment } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { podStore } from "./legacy-store";
import { eventStore } from "../+events/legacy-store";
import { KubeObjectListLayout } from "../kube-object-list-layout"; import { KubeObjectListLayout } from "../kube-object-list-layout";
import type { Pod } from "../../../common/k8s-api/endpoints"; import type { NodeApi, Pod } from "../../../common/k8s-api/endpoints";
import { nodeApi } from "../../../common/k8s-api/endpoints";
import { StatusBrick } from "../status-brick"; import { StatusBrick } from "../status-brick";
import { cssNames, getConvertedParts, object, stopPropagation } from "../../utils"; import { cssNames, getConvertedParts, object, stopPropagation } from "../../utils";
import startCase from "lodash/startCase"; import startCase from "lodash/startCase";
import kebabCase from "lodash/kebabCase"; import kebabCase from "lodash/kebabCase";
import { apiManager } from "../../../common/k8s-api/api-manager"; import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { Badge } from "../badge"; import { Badge } from "../badge";
import { getDetailsUrl } from "../kube-detail-params";
import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout"; import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout";
import { KubeObjectAge } from "../kube-object/age"; import { KubeObjectAge } from "../kube-object/age";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import type { EventStore } from "../+events/store";
import type { PodStore } from "./store";
import nodeApiInjectable from "../../../common/k8s-api/endpoints/node.api.injectable";
import eventStoreInjectable from "../+events/store.injectable";
import podStoreInjectable from "./store.injectable";
enum columnId { enum columnId {
name = "name", name = "name",
@ -36,8 +41,16 @@ enum columnId {
status = "status", status = "status",
} }
interface Dependencies {
getDetailsUrl: GetDetailsUrl;
apiManager: ApiManager;
eventStore: EventStore;
podStore: PodStore;
nodeApi: NodeApi;
}
@observer @observer
export class Pods extends React.Component { class NonInjectedPods extends React.Component<Dependencies> {
renderState<T extends string>(name: string, ready: boolean, key: string, data: Partial<Record<T, string | number>> | undefined) { renderState<T extends string>(name: string, ready: boolean, key: string, data: Partial<Record<T, string | number>> | undefined) {
return data && ( return data && (
<> <>
@ -87,6 +100,8 @@ export class Pods extends React.Component {
} }
render() { render() {
const { apiManager, getDetailsUrl, podStore, eventStore, nodeApi } = this.props;
return ( return (
<SiblingsInTabLayout> <SiblingsInTabLayout>
<KubeObjectListLayout <KubeObjectListLayout
@ -177,3 +192,14 @@ export class Pods extends React.Component {
); );
} }
} }
export const Pods = withInjectables<Dependencies>(NonInjectedPods, {
getProps: (di, props) => ({
...props,
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
nodeApi: di.inject(nodeApiInjectable),
eventStore: di.inject(eventStoreInjectable),
podStore: di.inject(podStoreInjectable),
}),
});

View File

@ -17,15 +17,18 @@ import { InfoPanel } from "../info-panel";
import * as resourceApplierApi from "../../../../common/k8s-api/endpoints/resource-applier.api"; import * as resourceApplierApi from "../../../../common/k8s-api/endpoints/resource-applier.api";
import { Notifications } from "../../notifications"; import { Notifications } from "../../notifications";
import logger from "../../../../common/logger"; import logger from "../../../../common/logger";
import { getDetailsUrl } from "../../kube-detail-params"; import type { ApiManager } from "../../../../common/k8s-api/api-manager";
import { apiManager } from "../../../../common/k8s-api/api-manager";
import { isString, prevDefault } from "../../../utils"; import { isString, prevDefault } from "../../../utils";
import { navigate } from "../../../navigation";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import createResourceTabStoreInjectable from "./store.injectable"; import createResourceTabStoreInjectable from "./store.injectable";
import createResourceTemplatesInjectable from "./create-resource-templates.injectable"; import createResourceTemplatesInjectable from "./create-resource-templates.injectable";
import { Spinner } from "../../spinner"; import { Spinner } from "../../spinner";
import type { GroupBase } from "react-select"; import type { GroupBase } from "react-select";
import type { Navigate } from "../../../navigation/navigate.injectable";
import type { GetDetailsUrl } from "../../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../../kube-detail-params/get-details-url.injectable";
import navigateInjectable from "../../../navigation/navigate.injectable";
export interface CreateResourceProps { export interface CreateResourceProps {
tab: DockTab; tab: DockTab;
@ -34,6 +37,9 @@ export interface CreateResourceProps {
interface Dependencies { interface Dependencies {
createResourceTemplates: IComputedValue<GroupBase<{ label: string; value: string }>[]>; createResourceTemplates: IComputedValue<GroupBase<{ label: string; value: string }>[]>;
createResourceTabStore: CreateResourceTabStore; createResourceTabStore: CreateResourceTabStore;
apiManager: ApiManager;
navigate: Navigate;
getDetailsUrl: GetDetailsUrl;
} }
@observer @observer
@ -63,6 +69,8 @@ class NonInjectedCreateResource extends React.Component<CreateResourceProps & De
}; };
create = async (): Promise<void> => { create = async (): Promise<void> => {
const { apiManager, getDetailsUrl, navigate } = this.props;
if (this.error || !this.data?.trim()) { if (this.error || !this.data?.trim()) {
// do not save when field is empty or there is an error // do not save when field is empty or there is an error
return; return;
@ -155,8 +163,11 @@ export const CreateResource = withInjectables<Dependencies, CreateResourceProps>
getPlaceholder: () => <Spinner center />, getPlaceholder: () => <Spinner center />,
getProps: async (di, props) => ({ getProps: async (di, props) => ({
...props,
createResourceTabStore: di.inject(createResourceTabStoreInjectable), createResourceTabStore: di.inject(createResourceTabStoreInjectable),
createResourceTemplates: await di.inject(createResourceTemplatesInjectable), createResourceTemplates: await di.inject(createResourceTemplatesInjectable),
...props, apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
navigate: di.inject(navigateInjectable),
}), }),
}); });

View File

@ -7,112 +7,126 @@ import React from "react";
import type { KubeMetaField } from "../../../common/k8s-api/kube-object"; import type { KubeMetaField } from "../../../common/k8s-api/kube-object";
import { KubeObject } from "../../../common/k8s-api/kube-object"; import { KubeObject } from "../../../common/k8s-api/kube-object";
import { DrawerItem, DrawerItemLabels } from "../drawer"; import { DrawerItem, DrawerItemLabels } from "../drawer";
import { apiManager } from "../../../common/k8s-api/api-manager"; import type { ApiManager } from "../../../common/k8s-api/api-manager";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { KubeObjectStatusIcon } from "../kube-object-status-icon"; import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { LocaleDate } from "../locale-date"; import { LocaleDate } from "../locale-date";
import { getDetailsUrl } from "../kube-detail-params";
import logger from "../../../common/logger"; import logger from "../../../common/logger";
import { KubeObjectAge } from "../kube-object/age"; import { KubeObjectAge } from "../kube-object/age";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import { observer } from "mobx-react";
import { withInjectables } from "@ogre-tools/injectable-react";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../common/k8s-api/api-manager/manager.injectable";
export interface KubeObjectMetaProps { export interface KubeObjectMetaProps {
object: KubeObject; object: KubeObject;
hideFields?: KubeMetaField[]; hideFields?: KubeMetaField[];
} }
export class KubeObjectMeta extends React.Component<KubeObjectMetaProps> { interface Dependencies {
static defaultHiddenFields: KubeMetaField[] = [ getDetailsUrl: GetDetailsUrl;
"uid", "resourceVersion", "selfLink", apiManager: ApiManager;
];
isHidden(field: KubeMetaField): boolean {
const { hideFields = KubeObjectMeta.defaultHiddenFields } = this.props;
return hideFields.includes(field);
}
render() {
const { object } = this.props;
if (!object) {
return null;
}
if (!(object instanceof KubeObject)) {
logger.error("[KubeObjectMeta]: passed object that is not an instanceof KubeObject", object);
return null;
}
const {
getNs, getLabels, getResourceVersion, selfLink, getAnnotations,
getFinalizers, getId, getName, metadata: { creationTimestamp },
} = object;
const ownerRefs = object.getOwnerRefs();
return (
<>
<DrawerItem name="Created" hidden={this.isHidden("creationTimestamp")}>
<KubeObjectAge object={object} compact={false} />
{" ago "}
{creationTimestamp && (
<>
(
<LocaleDate date={creationTimestamp} />
)
</>
)}
</DrawerItem>
<DrawerItem name="Name" hidden={this.isHidden("name")}>
{getName()}
<KubeObjectStatusIcon key="icon" object={object} />
</DrawerItem>
<DrawerItem name="Namespace" hidden={this.isHidden("namespace") || !getNs()}>
{getNs()}
</DrawerItem>
<DrawerItem name="UID" hidden={this.isHidden("uid")}>
{getId()}
</DrawerItem>
<DrawerItem name="Link" hidden={this.isHidden("selfLink")}>
{selfLink}
</DrawerItem>
<DrawerItem name="Resource Version" hidden={this.isHidden("resourceVersion")}>
{getResourceVersion()}
</DrawerItem>
<DrawerItemLabels
name="Labels"
labels={getLabels()}
hidden={this.isHidden("labels")}
/>
<DrawerItemLabels
name="Annotations"
labels={getAnnotations()}
hidden={this.isHidden("annotations")}
/>
<DrawerItemLabels
name="Finalizers"
labels={getFinalizers()}
hidden={this.isHidden("finalizers")}
/>
{ownerRefs?.length > 0 && (
<DrawerItem name="Controlled By" hidden={this.isHidden("ownerReferences")}>
{
ownerRefs.map(ref => {
const { name, kind } = ref;
const ownerDetailsUrl = getDetailsUrl(apiManager.lookupApiLink(ref, object));
return (
<p key={name}>
{kind}
{" "}
<Link to={ownerDetailsUrl}>{name}</Link>
</p>
);
})
}
</DrawerItem>
)}
</>
);
}
} }
const NonInjectedKubeObjectMeta = observer(({
apiManager,
getDetailsUrl,
object,
hideFields = [
"uid",
"resourceVersion",
"selfLink",
],
}: Dependencies & KubeObjectMetaProps) => {
if (!object) {
return null;
}
if (!(object instanceof KubeObject)) {
logger.error("[KubeObjectMeta]: passed object that is not an instanceof KubeObject", object);
return null;
}
const isHidden = (field: KubeMetaField) => hideFields.includes(field);
const {
getNs, getLabels, getResourceVersion, selfLink, getAnnotations,
getFinalizers, getId, getName, metadata: { creationTimestamp },
} = object;
const ownerRefs = object.getOwnerRefs();
return (
<>
<DrawerItem name="Created" hidden={isHidden("creationTimestamp")}>
<KubeObjectAge object={object} compact={false} />
{" ago "}
{creationTimestamp && (
<>
(
<LocaleDate date={creationTimestamp} />
)
</>
)}
</DrawerItem>
<DrawerItem name="Name" hidden={isHidden("name")}>
{getName()}
<KubeObjectStatusIcon key="icon" object={object} />
</DrawerItem>
<DrawerItem name="Namespace" hidden={isHidden("namespace") || !getNs()}>
{getNs()}
</DrawerItem>
<DrawerItem name="UID" hidden={isHidden("uid")}>
{getId()}
</DrawerItem>
<DrawerItem name="Link" hidden={isHidden("selfLink")}>
{selfLink}
</DrawerItem>
<DrawerItem name="Resource Version" hidden={isHidden("resourceVersion")}>
{getResourceVersion()}
</DrawerItem>
<DrawerItemLabels
name="Labels"
labels={getLabels()}
hidden={isHidden("labels")}
/>
<DrawerItemLabels
name="Annotations"
labels={getAnnotations()}
hidden={isHidden("annotations")}
/>
<DrawerItemLabels
name="Finalizers"
labels={getFinalizers()}
hidden={isHidden("finalizers")}
/>
{ownerRefs?.length > 0 && (
<DrawerItem name="Controlled By" hidden={isHidden("ownerReferences")}>
{
ownerRefs.map(ref => {
const { name, kind } = ref;
const ownerDetailsUrl = getDetailsUrl(apiManager.lookupApiLink(ref, object));
return (
<p key={name}>
{kind}
{" "}
<Link to={ownerDetailsUrl}>{name}</Link>
</p>
);
})
}
</DrawerItem>
)}
</>
);
});
export const KubeObjectMeta = withInjectables<Dependencies, KubeObjectMetaProps>(NonInjectedKubeObjectMeta, {
getProps: (di, props) => ({
...props,
getDetailsUrl: di.inject(getDetailsUrlInjectable),
apiManager: di.inject(apiManagerInjectable),
}),
});