mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix rendering of boolean values in CRDs (#1087)
* Fix rendering of boolean values in CRDs - add optional special casing for boolean values in DrawerItems and TableRows since React (imo annoying fashion) does not render boolean values by default. - add a spinner on the sidebar for when the CRD menu is expeanded but the entries have not been loaded yet. - Add ability to double click a Badge to expand, also make it so that Badges highligh all text on first click. Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
dd90dcb7f0
commit
a78bbb5f6c
15 files changed
+167
-101
No files matched your search
@@ -12,67 +12,83 @@ import { KubeObjectDetailsProps } from "../kube-object";
|
||||
import { crdStore } from "./crd.store";
|
||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||
import { Input } from "../input";
|
||||
import { CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
||||
import { AdditionalPrinterColumnsV1, CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
||||
|
||||
interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
|
||||
}
|
||||
|
||||
function CrdColumnValue({ value }: { value: any[] | {} | string }) {
|
||||
function convertSpecValue(value: any): any {
|
||||
if (Array.isArray(value)) {
|
||||
return <>{value.map((item, index) => <CrdColumnValue key={index} value={item} />)}</>
|
||||
return value.map(convertSpecValue)
|
||||
}
|
||||
if (typeof(value) === 'object') return (
|
||||
<Input
|
||||
readOnly
|
||||
multiLine
|
||||
theme="round-black"
|
||||
className="box grow"
|
||||
value={JSON.stringify(value, null, 2)}
|
||||
/>
|
||||
);
|
||||
return <span>{value}</span>;
|
||||
|
||||
if (typeof value === "object") {
|
||||
return (
|
||||
<Input
|
||||
readOnly
|
||||
multiLine
|
||||
theme="round-black"
|
||||
className="box grow"
|
||||
value={JSON.stringify(value, null, 2)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
@observer
|
||||
export class CrdResourceDetails extends React.Component<Props> {
|
||||
@computed get crd() {
|
||||
return crdStore.getByObject(this.props.object);
|
||||
}
|
||||
|
||||
renderAdditionalColumns(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
|
||||
return columns.map(({ name, jsonPath: jp }) => (
|
||||
<DrawerItem key={name} name={name} renderBoolean>
|
||||
{convertSpecValue(jsonPath.value(crd, jp.slice(1)))}
|
||||
</DrawerItem>
|
||||
))
|
||||
}
|
||||
|
||||
renderStatus(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
|
||||
const showStatus = !columns.find(column => column.name == "Status") && crd.status?.conditions;
|
||||
if (!showStatus) {
|
||||
return null
|
||||
}
|
||||
|
||||
const conditions = crd.status.conditions
|
||||
.filter(({ type, reason }) => type || reason)
|
||||
.map(({ type, reason, message, status }) => ({ kind: type || reason, message, status }))
|
||||
.map(({ kind, message, status }, index) => (
|
||||
<Badge
|
||||
key={kind + index} label={kind}
|
||||
className={cssNames({ disabled: status === "False" }, kind.toLowerCase())}
|
||||
tooltip={message}
|
||||
/>
|
||||
))
|
||||
|
||||
return (
|
||||
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
|
||||
{conditions}
|
||||
</DrawerItem>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { object } = this.props;
|
||||
const { crd } = this;
|
||||
if (!object || !crd) return null;
|
||||
const { props: { object }, crd } = this;
|
||||
if (!object || !crd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const className = cssNames("CrdResourceDetails", crd.getResourceKind());
|
||||
const extraColumns = crd.getPrinterColumns();
|
||||
const showStatus = !extraColumns.find(column => column.name == "Status") && object.status?.conditions;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<KubeObjectMeta object={object}/>
|
||||
{extraColumns.map(column => {
|
||||
const { name } = column;
|
||||
const value = jsonPath.query(object, (column.jsonPath).slice(1));
|
||||
return (
|
||||
<DrawerItem key={name} name={name}>
|
||||
<CrdColumnValue value={value} />
|
||||
</DrawerItem>
|
||||
)
|
||||
})}
|
||||
{showStatus && (
|
||||
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
|
||||
{object.status.conditions.map((condition, index) => {
|
||||
const { type, reason, message, status } = condition;
|
||||
const kind = type || reason;
|
||||
if (!kind) return null;
|
||||
return (
|
||||
<Badge
|
||||
key={kind + index} label={kind}
|
||||
className={cssNames({ disabled: status === "False" }, kind.toLowerCase())}
|
||||
tooltip={message}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</DrawerItem>
|
||||
)}
|
||||
<KubeObjectMeta object={object} />
|
||||
{this.renderAdditionalColumns(object, extraColumns)}
|
||||
{this.renderStatus(object, extraColumns)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,11 +56,11 @@ export class CrdResources extends React.Component<Props> {
|
||||
[sortBy.age]: (item: KubeObject) => item.metadata.creationTimestamp,
|
||||
}
|
||||
extraColumns.forEach(column => {
|
||||
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.query(item, column.jsonPath.slice(1))
|
||||
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.value(item, column.jsonPath.slice(1))
|
||||
})
|
||||
const ListView = KubeObjectListLayout;
|
||||
|
||||
return (
|
||||
<ListView
|
||||
<KubeObjectListLayout
|
||||
className="CrdResources"
|
||||
isClusterScoped={!isNamespaced}
|
||||
store={store}
|
||||
@@ -85,9 +85,10 @@ export class CrdResources extends React.Component<Props> {
|
||||
renderTableContents={(crdInstance: KubeObject) => [
|
||||
crdInstance.getName(),
|
||||
isNamespaced && crdInstance.getNs(),
|
||||
...extraColumns.map(column => {
|
||||
return jsonPath.query(crdInstance, (column.jsonPath).slice(1))
|
||||
}),
|
||||
...extraColumns.map(column => ({
|
||||
renderBoolean: true,
|
||||
children: jsonPath.value(crdInstance, column.jsonPath.slice(1)),
|
||||
})),
|
||||
crdInstance.getAge(),
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user