@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
98 lines (97 loc) • 4.95 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/*
* Copyright 2025 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { JSONPath } from 'jsonpath-plus';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import CustomResourceDefinition from '../../lib/k8s/crd';
import { localeDate } from '../../lib/util';
import { HoverInfoLabel, Link, ObjectEventList, SectionBox } from '../common';
import Empty from '../common/EmptyContent';
import Loader from '../common/Loader';
import { ConditionsTable, MainInfoSection, PageGrid } from '../common/Resource';
import DetailsViewSection from '../DetailsViewSection';
export default function CustomResourceDetailsFromURL() {
const params = useParams();
return _jsx(CustomResourceDetails, { ...params });
}
export function CustomResourceDetails({ crd: crdName, crName, namespace: ns, cluster, }) {
const { t } = useTranslation('glossary');
const [crd, error] = CustomResourceDefinition.useGet(crdName, undefined, { cluster });
const namespace = ns === '-' ? undefined : ns;
return !crd ? (!!error ? (_jsx(Empty, { color: "error", children: t('translation|Error getting custom resource definition {{ crdName }}: {{ errorMessage }}', {
crdName,
errorMessage: error.message,
}) })) : (_jsx(Loader, { title: t('translation|Loading custom resource details') }))) : (_jsx(CustomResourceDetailsRenderer, { crd: crd, crName: crName, namespace: namespace, cluster: cluster }));
}
function getExtraColumns(crd, apiVersion) {
const version = crd.jsonData.spec.versions.find(version => version.name === apiVersion);
return version?.additionalPrinterColumns;
}
function getExtraInfo(extraInfoSpec, item) {
const extraInfo = [];
extraInfoSpec.forEach(spec => {
// Skip creation date because we already show it by default
if (spec.jsonPath === '.metadata.creationTimestamp') {
return;
}
let value;
try {
// Extract the value from the json item
value = JSONPath({ path: '$' + spec.jsonPath, json: item });
}
catch (err) {
console.error(`Failed to get value from JSONPath ${spec.jsonPath} on CR item ${item}`);
return;
}
if (spec.type === 'date' && !!value) {
value = localeDate(new Date(value));
}
else {
// Make sure the value will be represented in string form (to account for
// e.g. cases where we may get an array).
value = value?.toString();
}
const desc = spec.description;
extraInfo.push({
name: spec.name,
value: !!desc ? _jsx(HoverInfoLabel, { label: value || '', hoverInfo: desc }) : value,
hide: value === '' || value === undefined,
});
});
return extraInfo;
}
function CustomResourceDetailsRenderer(props) {
const { crd, crName, namespace, cluster } = props;
const { t } = useTranslation('glossary');
const CRClass = React.useMemo(() => crd.makeCRClass(), [crd]);
const [item, error] = CRClass.useGet(crName, namespace, { cluster });
const apiVersion = item?.jsonData.apiVersion?.split('/')[1] || '';
const extraColumns = getExtraColumns(crd, apiVersion) || [];
return !item ? (!!error ? (_jsx(Empty, { color: "error", children: t('translation|Error getting custom resource {{ crName }}: {{ errorMessage }}', {
crName,
errorMessage: error.message,
}) })) : (_jsx(Loader, { title: t('translation|Loading custom resource details') }))) : (_jsxs(PageGrid, { children: [_jsx(MainInfoSection, { resource: item, extraInfo: [
{
name: t('glossary|Definition'),
value: (_jsx(Link, { routeName: "crd", params: {
name: crd.metadata.name,
}, activeCluster: crd.cluster, children: crd.metadata.name })),
},
...getExtraInfo(extraColumns, item.jsonData),
], backLink: "" }), item.jsonData.status?.conditions && (_jsx(SectionBox, { children: _jsx(ConditionsTable, { resource: item.jsonData, showLastUpdate: false }) })), _jsx(DetailsViewSection, { resource: item }), item && _jsx(ObjectEventList, { object: item })] }));
}