2025-04-01 10:38:02 +09:00

168 lines
4.0 KiB
TypeScript

import { css } from '@emotion/css';
import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack, useStyles2 } from '@grafana/ui';
import { PopupCard } from '../HoverCard';
import {
AlertTemplateData,
GlobalTemplateData,
KeyValueCodeSnippet,
KeyValueTemplateFunctions,
TemplateDataItem,
} from './TemplateData';
export function TemplateDataDocs() {
const styles = useStyles2(getTemplateDataDocsStyles);
const AlertTemplateDataTable = (
<TemplateDataTable
caption={
<h4 className={styles.header}>
Alert template data <span>Available only when in the context of an Alert (e.g. inside .Alerts loop)</span>
</h4>
}
dataItems={AlertTemplateData}
/>
);
return (
<Stack gap={2}>
<TemplateDataTable
caption={
<h4 className={styles.header}>
Notification template data <span>Available in the context of a notification.</span>{' '}
</h4>
}
dataItems={GlobalTemplateData}
typeRenderer={(type) =>
type === '[]Alert' ? (
<PopupCard content={AlertTemplateDataTable}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
) : type === 'KeyValue' ? (
<PopupCard content={<KeyValueTemplateDataTable />}>
<div className={styles.interactiveType}>{type}</div>
</PopupCard>
) : (
type
)
}
/>
</Stack>
);
}
export const getTemplateDataDocsStyles = (theme: GrafanaTheme2) => ({
header: css({
color: theme.colors.text.primary,
span: {
color: theme.colors.text.secondary,
fontSize: theme.typography.bodySmall.fontSize,
},
}),
interactiveType: css({
color: theme.colors.text.link,
}),
});
interface TemplateDataTableProps {
dataItems: TemplateDataItem[];
caption?: JSX.Element | string;
typeRenderer?: (type: TemplateDataItem['type']) => React.ReactNode;
}
export function TemplateDataTable({ dataItems, caption, typeRenderer }: TemplateDataTableProps) {
const styles = useStyles2(getTemplateDataTableStyles);
return (
<table className={styles.table}>
{caption && <caption>{caption}</caption>}
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{dataItems.map(({ name, type, notes }, index) => (
<tr key={index}>
<td>{name}</td>
<td>{typeRenderer ? typeRenderer(type) : type}</td>
<td>{notes}</td>
</tr>
))}
</tbody>
</table>
);
}
function KeyValueTemplateDataTable() {
const tableStyles = useStyles2(getTemplateDataTableStyles);
return (
<div>
KeyValue is a set of key/value string pairs that represent labels and annotations.
<pre>
<code>{KeyValueCodeSnippet}</code>
</pre>
<table className={tableStyles.table}>
<caption>Key-value methods</caption>
<thead>
<tr>
<th>Name</th>
<th>Arguments</th>
<th>Returns</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{KeyValueTemplateFunctions.map(({ name, args, returns, notes }) => (
<tr key={name}>
<td>{name}</td>
<td>{args}</td>
<td>{returns}</td>
<td>{notes}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export const getTemplateDataTableStyles = (theme: GrafanaTheme2) => ({
table: css({
borderCollapse: 'collapse',
width: '100%',
caption: {
captionSide: 'top',
},
'td, th': {
padding: theme.spacing(1, 1),
},
thead: {
fontWeight: theme.typography.fontWeightBold,
},
'tbody tr:nth-child(2n + 1)': {
backgroundColor: theme.colors.background.secondary,
},
'tbody td:nth-child(1)': {
fontWeight: theme.typography.fontWeightBold,
},
'tbody td:nth-child(2)': {
fontStyle: 'italic',
},
}),
});