GroupByWithLoading.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { isEmpty, uniq } from 'lodash';
  2. import React, { FC, useEffect, useMemo } from 'react';
  3. import { useDispatch } from 'react-redux';
  4. import { SelectableValue } from '@grafana/data';
  5. import { Icon, MultiSelect } from '@grafana/ui';
  6. import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector';
  7. import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions';
  8. import { getAllRulesSourceNames } from 'app/features/alerting/unified/utils/datasource';
  9. import {
  10. isAsyncRequestMapSliceFulfilled,
  11. isAsyncRequestMapSlicePending,
  12. } from 'app/features/alerting/unified/utils/redux';
  13. import { AlertingRule } from 'app/types/unified-alerting';
  14. import { PromRuleType } from 'app/types/unified-alerting-dto';
  15. import { isPrivateLabel } from './util';
  16. interface Props {
  17. id: string;
  18. defaultValue: SelectableValue<string>;
  19. onChange: (keys: string[]) => void;
  20. }
  21. export const GroupBy: FC<Props> = (props) => {
  22. const { onChange, id, defaultValue } = props;
  23. const dispatch = useDispatch();
  24. useEffect(() => {
  25. dispatch(fetchAllPromRulesAction());
  26. }, [dispatch]);
  27. const promRulesByDatasource = useUnifiedAlertingSelector((state) => state.promRules);
  28. const rulesDataSourceNames = useMemo(getAllRulesSourceNames, []);
  29. const allRequestsReady = isAsyncRequestMapSliceFulfilled(promRulesByDatasource);
  30. const loading = isAsyncRequestMapSlicePending(promRulesByDatasource);
  31. const labels = useMemo(() => {
  32. if (isEmpty(promRulesByDatasource)) {
  33. return [];
  34. }
  35. if (!allRequestsReady) {
  36. return [];
  37. }
  38. const allLabels = rulesDataSourceNames
  39. .flatMap((datasource) => promRulesByDatasource[datasource].result ?? [])
  40. .flatMap((rules) => rules.groups)
  41. .flatMap((group) => group.rules.filter((rule): rule is AlertingRule => rule.type === PromRuleType.Alerting))
  42. .flatMap((rule) => rule.alerts ?? [])
  43. .map((alert) => Object.keys(alert.labels ?? {}))
  44. .flatMap((labels) => labels.filter(isPrivateLabel));
  45. return uniq(allLabels);
  46. }, [allRequestsReady, promRulesByDatasource, rulesDataSourceNames]);
  47. return (
  48. <MultiSelect<string>
  49. id={id}
  50. isLoading={loading}
  51. defaultValue={defaultValue}
  52. aria-label={'group by label keys'}
  53. placeholder="Group by"
  54. prefix={<Icon name={'tag-alt'} />}
  55. onChange={(items) => {
  56. onChange(items.map((item) => item.value ?? ''));
  57. }}
  58. options={labels.map<SelectableValue>((key) => ({
  59. label: key,
  60. value: key,
  61. }))}
  62. />
  63. );
  64. };