CloudRules.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { css } from '@emotion/css';
  2. import pluralize from 'pluralize';
  3. import React, { FC, useMemo } from 'react';
  4. import { GrafanaTheme2 } from '@grafana/data';
  5. import { LoadingPlaceholder, useStyles2 } from '@grafana/ui';
  6. import { CombinedRuleNamespace } from 'app/types/unified-alerting';
  7. import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
  8. import { getRulesDataSources, getRulesSourceName } from '../../utils/datasource';
  9. import { RulesGroup } from './RulesGroup';
  10. interface Props {
  11. namespaces: CombinedRuleNamespace[];
  12. expandAll: boolean;
  13. }
  14. export const CloudRules: FC<Props> = ({ namespaces, expandAll }) => {
  15. const styles = useStyles2(getStyles);
  16. const dsConfigs = useUnifiedAlertingSelector((state) => state.dataSources);
  17. const rules = useUnifiedAlertingSelector((state) => state.promRules);
  18. const rulesDataSources = useMemo(getRulesDataSources, []);
  19. const dataSourcesLoading = useMemo(
  20. () => rulesDataSources.filter((ds) => rules[ds.name]?.loading || dsConfigs[ds.name]?.loading),
  21. [rules, dsConfigs, rulesDataSources]
  22. );
  23. return (
  24. <section className={styles.wrapper}>
  25. <div className={styles.sectionHeader}>
  26. <h5>Mimir / Cortex / Loki</h5>
  27. {dataSourcesLoading.length ? (
  28. <LoadingPlaceholder
  29. className={styles.loader}
  30. text={`Loading rules from ${dataSourcesLoading.length} ${pluralize('source', dataSourcesLoading.length)}`}
  31. />
  32. ) : (
  33. <div />
  34. )}
  35. </div>
  36. {namespaces.map((namespace) => {
  37. const { groups, rulesSource } = namespace;
  38. return groups.map((group) => (
  39. <RulesGroup
  40. group={group}
  41. key={`${getRulesSourceName(rulesSource)}-${name}-${group.name}`}
  42. namespace={namespace}
  43. expandAll={expandAll}
  44. />
  45. ));
  46. })}
  47. {namespaces?.length === 0 && !!rulesDataSources.length && <p>No rules found.</p>}
  48. {!rulesDataSources.length && <p>There are no Prometheus or Loki datas sources configured.</p>}
  49. </section>
  50. );
  51. };
  52. const getStyles = (theme: GrafanaTheme2) => ({
  53. loader: css`
  54. margin-bottom: 0;
  55. `,
  56. sectionHeader: css`
  57. display: flex;
  58. justify-content: space-between;
  59. `,
  60. wrapper: css`
  61. margin-bottom: ${theme.v1.spacing.xl};
  62. `,
  63. });