mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 00:55:47 -06:00
114 lines
4.4 KiB
TypeScript
114 lines
4.4 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useEffect } from 'react';
|
|
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
|
import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
|
|
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
|
import { useDispatch } from 'app/types';
|
|
|
|
import { AlertmanagerChoice } from '../../../plugins/datasource/alertmanager/types';
|
|
|
|
import { alertmanagerApi } from './api/alertmanagerApi';
|
|
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
|
|
import { NoAlertManagerWarning } from './components/NoAlertManagerWarning';
|
|
import { AlertGroup } from './components/alert-groups/AlertGroup';
|
|
import { AlertGroupFilter } from './components/alert-groups/AlertGroupFilter';
|
|
import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName';
|
|
import { useAlertManagersByPermission } from './hooks/useAlertManagerSources';
|
|
import { useFilteredAmGroups } from './hooks/useFilteredAmGroups';
|
|
import { useGroupedAlerts } from './hooks/useGroupedAlerts';
|
|
import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector';
|
|
import { fetchAlertGroupsAction } from './state/actions';
|
|
import { NOTIFICATIONS_POLL_INTERVAL_MS } from './utils/constants';
|
|
import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
|
|
import { getFiltersFromUrlParams } from './utils/misc';
|
|
import { initialAsyncRequestState } from './utils/redux';
|
|
|
|
const AlertGroups = () => {
|
|
const { useGetAlertmanagerChoiceQuery } = alertmanagerApi;
|
|
|
|
const alertManagers = useAlertManagersByPermission('instance');
|
|
const [alertManagerSourceName] = useAlertManagerSourceName(alertManagers);
|
|
const dispatch = useDispatch();
|
|
const [queryParams] = useQueryParams();
|
|
const { groupBy = [] } = getFiltersFromUrlParams(queryParams);
|
|
const styles = useStyles2(getStyles);
|
|
|
|
const { currentData: alertmanagerChoice } = useGetAlertmanagerChoiceQuery();
|
|
|
|
const alertGroups = useUnifiedAlertingSelector((state) => state.amAlertGroups);
|
|
const {
|
|
loading,
|
|
error,
|
|
result: results = [],
|
|
} = alertGroups[alertManagerSourceName || ''] ?? initialAsyncRequestState;
|
|
|
|
const groupedAlerts = useGroupedAlerts(results, groupBy);
|
|
const filteredAlertGroups = useFilteredAmGroups(groupedAlerts);
|
|
|
|
const grafanaAmDeliveryDisabled =
|
|
alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME && alertmanagerChoice === AlertmanagerChoice.External;
|
|
|
|
useEffect(() => {
|
|
function fetchNotifications() {
|
|
if (alertManagerSourceName) {
|
|
dispatch(fetchAlertGroupsAction(alertManagerSourceName));
|
|
}
|
|
}
|
|
fetchNotifications();
|
|
const interval = setInterval(fetchNotifications, NOTIFICATIONS_POLL_INTERVAL_MS);
|
|
return () => {
|
|
clearInterval(interval);
|
|
};
|
|
}, [dispatch, alertManagerSourceName]);
|
|
|
|
if (!alertManagerSourceName) {
|
|
return (
|
|
<AlertingPageWrapper pageId="groups">
|
|
<NoAlertManagerWarning availableAlertManagers={alertManagers} />
|
|
</AlertingPageWrapper>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<AlertingPageWrapper pageId="groups">
|
|
<AlertGroupFilter groups={results} />
|
|
{loading && <LoadingPlaceholder text="Loading notifications" />}
|
|
{error && !loading && (
|
|
<Alert title={'Error loading notifications'} severity={'error'}>
|
|
{error.message || 'Unknown error'}
|
|
</Alert>
|
|
)}
|
|
|
|
{grafanaAmDeliveryDisabled && (
|
|
<Alert title="Grafana alerts are not delivered to Grafana Alertmanager">
|
|
Grafana is configured to send alerts to external alertmanagers only. No alerts are expected to be available
|
|
here for the selected Alertmanager.
|
|
</Alert>
|
|
)}
|
|
|
|
{results &&
|
|
filteredAlertGroups.map((group, index) => {
|
|
return (
|
|
<React.Fragment key={`${JSON.stringify(group.labels)}-group-${index}`}>
|
|
{((index === 1 && Object.keys(filteredAlertGroups[0].labels).length === 0) ||
|
|
(index === 0 && Object.keys(group.labels).length > 0)) && (
|
|
<p className={styles.groupingBanner}>Grouped by: {Object.keys(group.labels).join(', ')}</p>
|
|
)}
|
|
<AlertGroup alertManagerSourceName={alertManagerSourceName || ''} group={group} />
|
|
</React.Fragment>
|
|
);
|
|
})}
|
|
{results && !filteredAlertGroups.length && <p>No results.</p>}
|
|
</AlertingPageWrapper>
|
|
);
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
groupingBanner: css`
|
|
margin: ${theme.spacing(2, 0)};
|
|
`,
|
|
});
|
|
|
|
export default AlertGroups;
|