diff --git a/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx b/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx index ba2c13b7828..41d2e2831ad 100644 --- a/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx +++ b/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; import { sortBy } from 'lodash'; import React, { useEffect, useMemo } from 'react'; +import { useEffectOnce } from 'react-use'; import { GrafanaTheme2, PanelProps } from '@grafana/data'; +import { TimeRangeUpdatedEvent } from '@grafana/runtime'; import { Alert, BigValue, @@ -19,7 +21,7 @@ import alertDef from 'app/features/alerting/state/alertDef'; import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector'; import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions'; import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; -import { Annotation, RULE_LIST_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants'; +import { Annotation } from 'app/features/alerting/unified/utils/constants'; import { getAllRulesSourceNames, GRAFANA_DATASOURCE_NAME, @@ -27,6 +29,7 @@ import { } from 'app/features/alerting/unified/utils/datasource'; import { flattenRules, getFirstActiveAt } from 'app/features/alerting/unified/utils/rules'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { DashboardModel } from 'app/features/dashboard/state'; import { useDispatch, AccessControlAction } from 'app/types'; import { PromRuleWithLocation } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; @@ -48,13 +51,19 @@ export function UnifiedAlertList(props: PanelProps) { props.options.stateFilter.inactive = undefined; // now disable inactive }, [props.options.stateFilter]); + let dashboard: DashboardModel | undefined = undefined; + + useEffectOnce(() => { + dashboard = getDashboardSrv().getCurrent(); + }); + useEffect(() => { dispatch(fetchAllPromRulesAction()); - const interval = setInterval(() => dispatch(fetchAllPromRulesAction()), RULE_LIST_POLL_INTERVAL_MS); + const sub = dashboard?.events.subscribe(TimeRangeUpdatedEvent, () => dispatch(fetchAllPromRulesAction())); return () => { - clearInterval(interval); + sub?.unsubscribe(); }; - }, [dispatch]); + }, [dispatch, dashboard]); const promRulesRequests = useUnifiedAlertingSelector((state) => state.promRules); diff --git a/public/app/plugins/panel/alertlist/UnifiedalertList.test.tsx b/public/app/plugins/panel/alertlist/UnifiedalertList.test.tsx new file mode 100644 index 00000000000..ed2a5cc6a94 --- /dev/null +++ b/public/app/plugins/panel/alertlist/UnifiedalertList.test.tsx @@ -0,0 +1,85 @@ +import { render } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { getDefaultTimeRange, LoadingState, PanelProps, FieldConfigSource } from '@grafana/data'; +import { TimeRangeUpdatedEvent } from '@grafana/runtime'; +import { DashboardSrv, setDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { configureStore } from 'app/store/configureStore'; + +import { UnifiedAlertList } from './UnifiedAlertList'; +import { UnifiedAlertListOptions, SortOrder, GroupMode, ViewMode } from './types'; + +jest.mock('app/features/alerting/unified/api/alertmanager'); + +const defaultOptions: UnifiedAlertListOptions = { + maxItems: 2, + sortOrder: SortOrder.AlphaAsc, + dashboardAlerts: true, + groupMode: GroupMode.Default, + groupBy: [''], + alertName: 'test', + showInstances: false, + folder: { id: 1, title: 'test folder' }, + stateFilter: { firing: true, pending: false, noData: false, normal: true, error: false }, + alertInstanceLabelFilter: '', + datasource: 'Alertmanager', + viewMode: ViewMode.List, +}; + +const defaultProps: PanelProps = { + data: { state: LoadingState.Done, series: [], timeRange: getDefaultTimeRange() }, + id: 1, + timeRange: getDefaultTimeRange(), + timeZone: 'utc', + options: defaultOptions, + eventBus: { + subscribe: jest.fn(), + getStream: jest.fn(), + publish: jest.fn(), + removeAllListeners: jest.fn(), + newScopedBus: jest.fn(), + }, + fieldConfig: {} as unknown as FieldConfigSource, + height: 400, + onChangeTimeRange: jest.fn(), + onFieldConfigChange: jest.fn(), + onOptionsChange: jest.fn(), + renderCounter: 1, + replaceVariables: jest.fn(), + title: 'Alert groups test', + transparent: false, + width: 320, +}; + +const dashboard = { + id: 1, + formatDate: (time: number) => new Date(time).toISOString(), + events: { + subscribe: jest.fn(), + }, +}; + +const renderPanel = (options: UnifiedAlertListOptions = defaultOptions) => { + const store = configureStore(); + + const dashSrv: unknown = { getCurrent: () => dashboard }; + setDashboardSrv(dashSrv as DashboardSrv); + + defaultProps.options = options; + const props = { ...defaultProps }; + + return render( + + + + ); +}; + +describe('UnifiedAlertList', () => { + it('subscribes to the dashboard refresh interval', async () => { + await renderPanel(); + expect(dashboard.events.subscribe).toHaveBeenCalledTimes(1); + expect(dashboard.events.subscribe.mock.calls[0][0]).toEqual(TimeRangeUpdatedEvent); + }); +});