AlertGroupAlertsTable.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { css } from '@emotion/css';
  2. import React, { useMemo } from 'react';
  3. import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
  4. import { useStyles2 } from '@grafana/ui';
  5. import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types';
  6. import { AlertLabels } from '../AlertLabels';
  7. import { DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';
  8. import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines';
  9. import { AmAlertStateTag } from '../silences/AmAlertStateTag';
  10. import { AlertDetails } from './AlertDetails';
  11. interface Props {
  12. alerts: AlertmanagerAlert[];
  13. alertManagerSourceName: string;
  14. }
  15. type AlertGroupAlertsTableColumnProps = DynamicTableColumnProps<AlertmanagerAlert>;
  16. type AlertGroupAlertsTableItemProps = DynamicTableItemProps<AlertmanagerAlert>;
  17. export const AlertGroupAlertsTable = ({ alerts, alertManagerSourceName }: Props) => {
  18. const styles = useStyles2(getStyles);
  19. const columns = useMemo(
  20. (): AlertGroupAlertsTableColumnProps[] => [
  21. {
  22. id: 'state',
  23. label: 'State',
  24. // eslint-disable-next-line react/display-name
  25. renderCell: ({ data: alert }) => (
  26. <>
  27. <AmAlertStateTag state={alert.status.state} />
  28. <span className={styles.duration}>
  29. for{' '}
  30. {intervalToAbbreviatedDurationString({
  31. start: new Date(alert.startsAt),
  32. end: new Date(alert.endsAt),
  33. })}
  34. </span>
  35. </>
  36. ),
  37. size: '220px',
  38. },
  39. {
  40. id: 'labels',
  41. label: 'Labels',
  42. // eslint-disable-next-line react/display-name
  43. renderCell: ({ data: { labels } }) => <AlertLabels className={styles.labels} labels={labels} />,
  44. size: 1,
  45. },
  46. ],
  47. [styles]
  48. );
  49. const items = useMemo(
  50. (): AlertGroupAlertsTableItemProps[] =>
  51. alerts.map((alert) => ({
  52. id: alert.fingerprint,
  53. data: alert,
  54. })),
  55. [alerts]
  56. );
  57. return (
  58. <div className={styles.tableWrapper} data-testid="alert-group-table">
  59. <DynamicTableWithGuidelines
  60. cols={columns}
  61. items={items}
  62. isExpandable={true}
  63. renderExpandedContent={({ data: alert }) => (
  64. <AlertDetails alert={alert} alertManagerSourceName={alertManagerSourceName} />
  65. )}
  66. />
  67. </div>
  68. );
  69. };
  70. const getStyles = (theme: GrafanaTheme2) => ({
  71. tableWrapper: css`
  72. margin-top: ${theme.spacing(3)};
  73. ${theme.breakpoints.up('md')} {
  74. margin-left: ${theme.spacing(4.5)};
  75. }
  76. `,
  77. duration: css`
  78. margin-left: ${theme.spacing(1)};
  79. font-size: ${theme.typography.bodySmall.fontSize};
  80. `,
  81. labels: css`
  82. padding-bottom: 0;
  83. `,
  84. });