Files
Sonia Aguilar 3854be1fcb Alerting: Implement template preview for Grafana AlertManager (#65530)
* Add Preview template and payload editor to templates form

* Add TemplatePreview test and update css

* Preview errors for each template that is wrong

* Enable preview templating only for Grafana Alert Manager

* Use harcoded default payload instead of requesting it to the backend

* Update error response in the api definition

* Add spinner when loading result for preview

* Update api request followind DD changes

* Use pre instead of TextArea to render the preview

* Fix tests

* Add alert list editor

* Add start and end time for alert generator

* Add preview for data list added in the modal

* Update copies and move submit button in alert generator to the bottom

* Copy updates

* Refactor

* Use tab instead of button to preview

* Move payload editor next to the content

* Copy update

* Refactor

* Adress PR review comments

* Fix wrong json format throwing an exception when adding more data

* Use monaco editor for payload

* Only show text 'Preview for...'  when we have more than one define

* Fix some errors

* Update CollapseSection style

* Add tooltip for the Payload info icon explaining the available list of alert data fields in preview

* Set payload as invalid if it's not an array

* Fix test

* Update text in AlertTemplateDataTable

* Add separators to distinguish lines that belong to the preview

* Fix text

* Use subDays instead of addDays for substracting days
2023-04-28 17:05:45 +02:00

166 lines
4.0 KiB
TypeScript

import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { HoverCard } 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} flexGrow={1}>
<TemplateDataTable
caption={<h4 className={styles.header}>Template Data</h4>}
dataItems={GlobalTemplateData}
typeRenderer={(type) =>
type === '[]Alert' ? (
<HoverCard content={AlertTemplateDataTable}>
<div className={styles.interactiveType}>{type}</div>
</HoverCard>
) : type === 'KeyValue' ? (
<HoverCard content={<KeyValueTemplateDataTable />}>
<div className={styles.interactiveType}>{type}</div>
</HoverCard>
) : (
type
)
}
/>
</Stack>
);
}
const getTemplateDataDocsStyles = (theme: GrafanaTheme2) => ({
header: css`
color: ${theme.colors.text.primary};
span {
color: ${theme.colors.text.secondary};
font-size: ${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>
<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>
);
}
const getTemplateDataTableStyles = (theme: GrafanaTheme2) => ({
table: css`
border-collapse: collapse;
width: 100%;
caption {
caption-side: top;
}
td,
th {
padding: ${theme.spacing(1, 1)};
}
thead {
font-weight: ${theme.typography.fontWeightBold};
}
tbody tr:nth-child(2n + 1) {
background-color: ${theme.colors.background.secondary};
}
tbody td:nth-child(1) {
font-weight: ${theme.typography.fontWeightBold};
}
tbody td:nth-child(2) {
font-style: italic;
}
`,
});