PromExemplarField.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { css, cx } from '@emotion/css';
  2. import React, { useEffect, useState } from 'react';
  3. import { usePrevious } from 'react-use';
  4. import { GrafanaTheme2 } from '@grafana/data';
  5. import { IconButton, InlineLabel, Tooltip, useStyles2 } from '@grafana/ui';
  6. import { PrometheusDatasource } from '../datasource';
  7. import { PromQuery } from '../types';
  8. interface Props {
  9. onChange: (exemplar: boolean) => void;
  10. datasource: PrometheusDatasource;
  11. query: PromQuery;
  12. 'data-testid'?: string;
  13. }
  14. export function PromExemplarField({ datasource, onChange, query, ...rest }: Props) {
  15. const [error, setError] = useState<string | null>(null);
  16. const styles = useStyles2(getStyles);
  17. const prevError = usePrevious(error);
  18. useEffect(() => {
  19. if (!datasource.exemplarsAvailable) {
  20. setError('Exemplars for this query are not available');
  21. onChange(false);
  22. } else if (query.instant && !query.range) {
  23. setError('Exemplars are not available for instant queries');
  24. onChange(false);
  25. } else {
  26. setError(null);
  27. // If error is cleared, we want to change exemplar to true
  28. if (prevError && !error) {
  29. onChange(true);
  30. }
  31. }
  32. }, [datasource.exemplarsAvailable, query.instant, query.range, onChange, prevError, error]);
  33. const iconButtonStyles = cx(
  34. {
  35. [styles.activeIcon]: !!query.exemplar,
  36. },
  37. styles.eyeIcon
  38. );
  39. return (
  40. <InlineLabel width="auto" data-testid={rest['data-testid']}>
  41. <Tooltip content={error ?? ''}>
  42. <div className={styles.iconWrapper}>
  43. Exemplars
  44. <IconButton
  45. name="eye"
  46. tooltip={!!query.exemplar ? 'Disable query with exemplars' : 'Enable query with exemplars'}
  47. disabled={!!error}
  48. className={iconButtonStyles}
  49. onClick={() => {
  50. onChange(!query.exemplar);
  51. }}
  52. />
  53. </div>
  54. </Tooltip>
  55. </InlineLabel>
  56. );
  57. }
  58. function getStyles(theme: GrafanaTheme2) {
  59. return {
  60. eyeIcon: css`
  61. margin-left: ${theme.spacing(2)};
  62. `,
  63. activeIcon: css`
  64. color: ${theme.colors.primary.main};
  65. `,
  66. iconWrapper: css`
  67. display: flex;
  68. align-items: center;
  69. `,
  70. };
  71. }