mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
1 parent
e810eab39f
commit
b7974827d2
786 files changed
+14567
-24066
No files matched your search
@@ -0,0 +1,3 @@
|
||||
export * from "./kube-object-details"
|
||||
export * from "./kube-object-list-layout"
|
||||
export * from "./kube-object-menu"
|
||||
@@ -0,0 +1,3 @@
|
||||
.KubeObjectDetails {
|
||||
z-index: $zIndex-drawer + 1 !important;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import "./kube-object-details.scss"
|
||||
|
||||
import React from "react"
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { computed, observable, reaction } from "mobx";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { getDetails, hideDetails } from "../../navigation";
|
||||
import { Drawer } from "../drawer";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { Spinner } from "../spinner";
|
||||
import { apiManager, ApiComponents } from "../../api/api-manager";
|
||||
import { crdStore } from "../+custom-resources/crd.store";
|
||||
import { CrdResourceDetails, CrdResourceMenu } from "../+custom-resources";
|
||||
|
||||
export interface KubeObjectDetailsProps<T = KubeObject> {
|
||||
className?: string;
|
||||
object: T;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class KubeObjectDetails extends React.Component {
|
||||
@observable isLoading = false;
|
||||
@observable.ref loadingError: React.ReactNode;
|
||||
|
||||
@computed get path() {
|
||||
return getDetails()
|
||||
}
|
||||
|
||||
@computed get object() {
|
||||
const store = apiManager.getStore(this.path);
|
||||
if (store) {
|
||||
return store.getByPath(this.path);
|
||||
}
|
||||
}
|
||||
|
||||
@computed get isCrdInstance() {
|
||||
return !!crdStore.getByObject(this.object);
|
||||
}
|
||||
|
||||
@disposeOnUnmount
|
||||
loader = reaction(() => [
|
||||
this.path,
|
||||
this.object, // resource might be updated via watch-event or from already opened details
|
||||
crdStore.items.length, // crd stores initialized after loading
|
||||
], async () => {
|
||||
this.loadingError = ""
|
||||
const { path, object } = this;
|
||||
if (!object) {
|
||||
const store = apiManager.getStore(path);
|
||||
if (store) {
|
||||
this.isLoading = true
|
||||
try {
|
||||
await store.loadFromPath(path)
|
||||
} catch (err) {
|
||||
this.loadingError = <Trans>Resource loading has failed: <b>{err.toString()}</b></Trans>
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
render() {
|
||||
const { object, isLoading, loadingError, isCrdInstance } = this;
|
||||
const isOpen = !!(object || isLoading || loadingError);
|
||||
let title = "";
|
||||
let apiComponents: ApiComponents;
|
||||
if (object) {
|
||||
const { kind, getName, selfLink } = object;
|
||||
title = `${kind}: ${getName()}`;
|
||||
apiComponents = apiManager.getViews(selfLink);
|
||||
if (isCrdInstance && !apiComponents.Details) {
|
||||
apiComponents.Details = CrdResourceDetails
|
||||
apiComponents.Menu = CrdResourceMenu
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Drawer
|
||||
className="KubeObjectDetails flex column"
|
||||
open={isOpen}
|
||||
title={title}
|
||||
toolbar={apiComponents && apiComponents.Menu && <apiComponents.Menu object={object} toolbar/>}
|
||||
onClose={hideDetails}
|
||||
>
|
||||
{isLoading && <Spinner center/>}
|
||||
{loadingError && <div className="box center">{loadingError}</div>}
|
||||
{apiComponents && apiComponents.Details && <apiComponents.Details object={object}/>}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
import { computed } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { cssNames } from "../../utils";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { getSelectedDetails, showDetails } from "../../navigation";
|
||||
import { ItemListLayout, ItemListLayoutProps } from "../item-object-list/item-list-layout";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
|
||||
export interface KubeObjectListLayoutProps extends ItemListLayoutProps {
|
||||
store: KubeObjectStore;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutProps> {
|
||||
@computed get selectedItem() {
|
||||
return this.props.store.getByPath(getSelectedDetails());
|
||||
}
|
||||
|
||||
onDetails = (item: KubeObject) => {
|
||||
if (this.props.onDetails) {
|
||||
this.props.onDetails(item);
|
||||
}
|
||||
else {
|
||||
showDetails(item.selfLink);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, ...layoutProps } = this.props;
|
||||
return (
|
||||
<ItemListLayout
|
||||
{...layoutProps}
|
||||
className={cssNames("KubeObjectListLayout", className)}
|
||||
detailsItem={this.selectedItem}
|
||||
onDetails={this.onDetails}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from "react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { autobind, cssNames } from "../../utils";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { editResourceTab } from "../dock/edit-resource.store";
|
||||
import { MenuActions, MenuActionsProps } from "../menu/menu-actions";
|
||||
import { hideDetails } from "../../navigation";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
export interface KubeObjectMenuProps<T extends KubeObject = any> extends MenuActionsProps {
|
||||
object: T;
|
||||
editable?: boolean;
|
||||
removable?: boolean;
|
||||
}
|
||||
|
||||
export class KubeObjectMenu extends React.Component<KubeObjectMenuProps> {
|
||||
get store() {
|
||||
const { object } = this.props;
|
||||
if (!object) return;
|
||||
return apiManager.getStore(object.selfLink);
|
||||
}
|
||||
|
||||
get isEditable() {
|
||||
const { editable } = this.props;
|
||||
return editable !== undefined ? editable : !!(this.store && this.store.update);
|
||||
}
|
||||
|
||||
get isRemovable() {
|
||||
const { removable } = this.props;
|
||||
return removable !== undefined ? removable : !!(this.store && this.store.remove);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
async update() {
|
||||
hideDetails();
|
||||
editResourceTab(this.props.object);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
async remove() {
|
||||
hideDetails();
|
||||
const { object, removeAction } = this.props;
|
||||
if (removeAction) await removeAction();
|
||||
else await this.store.remove(object);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
renderRemoveMessage() {
|
||||
const { object } = this.props;
|
||||
const resourceKind = object.kind;
|
||||
const resourceName = object.getName();
|
||||
return (
|
||||
<p><Trans>Remove {resourceKind} <b>{resourceName}</b>?</Trans></p>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { remove, update, renderRemoveMessage, isEditable, isRemovable } = this;
|
||||
const { className, object, editable, removable, ...menuProps } = this.props;
|
||||
return (
|
||||
<MenuActions
|
||||
className={cssNames("KubeObjectMenu", className)}
|
||||
updateAction={isEditable ? update : undefined}
|
||||
removeAction={isRemovable ? remove : undefined}
|
||||
removeConfirmationMessage={renderRemoveMessage}
|
||||
{...menuProps}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import React from "react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { IKubeMetaField, KubeObject } from "../../api/kube-object";
|
||||
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||
import { WorkloadKubeObject } from "../../api/workload-kube-object";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import { lookupApiLink } from "../../api/kube-api";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export interface Props {
|
||||
object: KubeObject;
|
||||
hideFields?: IKubeMetaField[];
|
||||
}
|
||||
|
||||
export class KubeObjectMeta extends React.Component<Props> {
|
||||
static defaultHiddenFields: IKubeMetaField[] = [
|
||||
"uid", "resourceVersion", "selfLink"
|
||||
];
|
||||
|
||||
isHidden(field: IKubeMetaField): boolean {
|
||||
const { hideFields = KubeObjectMeta.defaultHiddenFields } = this.props;
|
||||
return hideFields.includes(field);
|
||||
}
|
||||
|
||||
render() {
|
||||
const object = this.props.object
|
||||
const {
|
||||
getName, getNs, getLabels, getResourceVersion, selfLink,
|
||||
getAnnotations, getFinalizers, getId, getAge,
|
||||
metadata: { creationTimestamp },
|
||||
} = object;
|
||||
|
||||
const ownerRefs = object.getOwnerRefs();
|
||||
return (
|
||||
<>
|
||||
<DrawerItem name={<Trans>Created</Trans>} hidden={this.isHidden("creationTimestamp")}>
|
||||
{getAge(true, false)} <Trans>ago</Trans> ({creationTimestamp})
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Name</Trans>} hidden={this.isHidden("name")}>
|
||||
{getName()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Namespace</Trans>} hidden={this.isHidden("namespace") || !getNs()}>
|
||||
{getNs()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>UID</Trans>} hidden={this.isHidden("uid")}>
|
||||
{getId()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Link</Trans>} hidden={this.isHidden("selfLink")}>
|
||||
{selfLink}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Resource Version</Trans>} hidden={this.isHidden("resourceVersion")}>
|
||||
{getResourceVersion()}
|
||||
</DrawerItem>
|
||||
<DrawerItemLabels
|
||||
name={<Trans>Labels</Trans>}
|
||||
labels={getLabels()}
|
||||
hidden={this.isHidden("labels")}
|
||||
/>
|
||||
<DrawerItemLabels
|
||||
name={<Trans>Annotations</Trans>}
|
||||
labels={getAnnotations()}
|
||||
hidden={this.isHidden("annotations")}
|
||||
/>
|
||||
<DrawerItemLabels
|
||||
name={<Trans>Finalizers</Trans>}
|
||||
labels={getFinalizers()}
|
||||
hidden={this.isHidden("finalizers")}
|
||||
/>
|
||||
{ownerRefs && ownerRefs.length > 0 &&
|
||||
<DrawerItem name={<Trans>Controlled By</Trans>} hidden={this.isHidden("ownerReferences")}>
|
||||
{
|
||||
ownerRefs.map(ref => {
|
||||
const { name, kind } = ref;
|
||||
const ownerDetailsUrl = getDetailsUrl(lookupApiLink(ref, object));
|
||||
return (
|
||||
<p key={name}>
|
||||
{kind} <Link to={ownerDetailsUrl}>{name}</Link>
|
||||
</p>
|
||||
);
|
||||
})
|
||||
}
|
||||
</DrawerItem>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user