@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
139 lines (138 loc) • 6.38 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 { Icon } from '@iconify/react';
import { grey } from '@mui/material/colors';
import Grid from '@mui/material/Grid';
import { alpha, useTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import { forwardRef, useEffect, useState } from 'react';
import { localeDate, timeAgo } from '../../lib/util';
import { LightTooltip, TooltipIcon } from './Tooltip';
export function InfoLabel(props) {
const { name, value = null } = props;
return (_jsxs(Grid, { container: true, item: true, spacing: 2, justifyContent: "flex-start", alignItems: "flex-start", children: [_jsxs(Grid, { item: true, xs: true, sx: {
textAlign: 'right',
flex: '0 0 200px',
}, children: [_jsx(NameLabel, { children: name }), ' '] }), _jsx(Grid, { item: true, xs: true, children: value !== null ? _jsx(ValueLabel, { children: value }) : props.children })] }));
}
export function NameLabel(props) {
return (_jsx(Typography, { sx: theme => ({
color: theme.palette.text.secondary,
fontSize: theme.typography.pxToRem(16),
textAlign: 'right',
}), component: "span", children: props.children }));
}
export function ValueLabel(props) {
return (_jsx(Typography, { sx: theme => ({
color: theme.palette.text.primary,
fontSize: theme.typography.pxToRem(16),
wordBreak: 'break-word',
}), component: "span", children: props.children }));
}
export const StatusLabel = forwardRef((props, ref) => {
const { status, sx, className = '', ...other } = props;
const theme = useTheme();
const statuses = ['success', 'warning', 'error'];
const isLight = theme.palette.mode === 'light';
const base = statuses.includes(status) ? theme.palette[status] : grey;
const baseColor = base[800] ?? base.main;
let params = {};
if (status === '') {
params = {
backgroundColor: theme.palette.background.muted,
color: theme.palette.text.primary,
borderColor: theme.palette.divider,
};
}
else if (isLight) {
const bg = baseColor;
const fg = status === 'warning' ? '#000000ff' : theme.palette.getContrastText(bg);
params = {
backgroundColor: bg,
color: fg,
borderColor: 'transparent',
};
}
else {
params = {
backgroundColor: alpha(baseColor, 0.2),
color: base[200],
borderColor: alpha(base[400], 0.5),
};
}
return (_jsx(Typography, { ref: ref, sx: {
border: '1px solid',
...params,
fontSize: theme.typography.pxToRem(14),
paddingLeft: theme.spacing(1),
paddingRight: theme.spacing(1),
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
display: 'inline-flex',
whiteSpace: 'nowrap',
alignItems: 'normal',
gap: theme.spacing(0.5),
borderRadius: theme.shape.borderRadius + 'px',
...sx,
}, className: className, component: "span", ...other }));
});
export function makeStatusLabel(label, successStatusName) {
return (_jsx(StatusLabel, { status: label === successStatusName ? 'success' : 'error', children: label }));
}
export function HeaderLabel(props) {
const { value, label, tooltip } = props;
return (_jsxs(Grid, { container: true, alignItems: "center", direction: "column", children: [_jsxs(Grid, { item: true, children: [_jsx(Typography, { sx: {
textAlign: 'center',
fontSize: '1.2em',
flexGrow: 1,
fontWeight: 'bold',
}, display: "inline", children: label }), !!tooltip && _jsx(TooltipIcon, { children: tooltip })] }), _jsx(Grid, { item: true, container: true, alignItems: "center", justifyContent: "center", children: _jsx(Grid, { item: true, children: _jsx(Typography, { sx: {
fontSize: '3rem;',
}, children: value }) }) })] }));
}
export function HoverInfoLabel(props) {
const { label, hoverInfo, icon = null, iconProps = {}, labelProps, iconPosition = 'end' } = props;
const labelFirst = iconPosition === 'end';
return (_jsx(LightTooltip, { title: hoverInfo || '', children: _jsxs(Typography, { sx: {
display: 'inline-flex',
whiteSpace: 'nowrap',
}, ...labelProps, children: [labelFirst && label, hoverInfo && (_jsx(Icon, { icon: icon || 'mdi:information-outline', width: "1rem", height: "1rem", style: {
marginRight: '0.2rem',
marginLeft: '0.2rem',
alignSelf: 'center',
}, ...iconProps })), !labelFirst && label] }) }));
}
export function DateLabel(props) {
const { date, format = 'brief', iconProps = {} } = props;
return (_jsx(HoverInfoLabel, { label: _jsx(TimeAgo, { date: date, format: format }), hoverInfo: localeDate(date), icon: "mdi:calendar", iconProps: iconProps }));
}
/**
* Shows time passed since given date
* Automatically refreshes
*/
function TimeAgo({ date, format }) {
const [formattedDate, setFormattedDate] = useState(() => timeAgo(date, { format }));
useEffect(() => {
const id = setInterval(() => {
const newFormattedDate = timeAgo(date, { format });
setFormattedDate(newFormattedDate);
}, 1000);
return () => clearInterval(id);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return formattedDate;
}