1import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui'; 2import React, { FC, useEffect } from 'react'; 3import { useDispatch } from 'react-redux'; 4import { Redirect, Route, RouteChildrenProps, Switch, useLocation } from 'react-router-dom'; 5import { AlertingPageWrapper } from './components/AlertingPageWrapper'; 6import { AlertManagerPicker } from './components/AlertManagerPicker'; 7import { EditReceiverView } from './components/receivers/EditReceiverView'; 8import { EditTemplateView } from './components/receivers/EditTemplateView'; 9import { GlobalConfigForm } from './components/receivers/GlobalConfigForm'; 10import { NewReceiverView } from './components/receivers/NewReceiverView'; 11import { NewTemplateView } from './components/receivers/NewTemplateView'; 12import { ReceiversAndTemplatesView } from './components/receivers/ReceiversAndTemplatesView'; 13import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName'; 14import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; 15import { fetchAlertManagerConfigAction, fetchGrafanaNotifiersAction } from './state/actions'; 16import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; 17import { initialAsyncRequestState } from './utils/redux'; 18 19const Receivers: FC = () => { 20 const [alertManagerSourceName, setAlertManagerSourceName] = useAlertManagerSourceName(); 21 const dispatch = useDispatch(); 22 23 const location = useLocation(); 24 const isRoot = location.pathname.endsWith('/alerting/notifications'); 25 26 const configRequests = useUnifiedAlertingSelector((state) => state.amConfigs); 27 28 const { result: config, loading, error } = 29 (alertManagerSourceName && configRequests[alertManagerSourceName]) || initialAsyncRequestState; 30 const receiverTypes = useUnifiedAlertingSelector((state) => state.grafanaNotifiers); 31 32 const shouldLoadConfig = isRoot || !config; 33 34 useEffect(() => { 35 if (alertManagerSourceName && shouldLoadConfig) { 36 dispatch(fetchAlertManagerConfigAction(alertManagerSourceName)); 37 } 38 }, [alertManagerSourceName, dispatch, shouldLoadConfig]); 39 40 useEffect(() => { 41 if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME && !(receiverTypes.result || receiverTypes.loading)) { 42 dispatch(fetchGrafanaNotifiersAction()); 43 } 44 }, [alertManagerSourceName, dispatch, receiverTypes]); 45 46 const disableAmSelect = !isRoot; 47 48 if (!alertManagerSourceName) { 49 return <Redirect to="/alerting/notifications" />; 50 } 51 52 return ( 53 <AlertingPageWrapper pageId="receivers"> 54 <AlertManagerPicker 55 current={alertManagerSourceName} 56 disabled={disableAmSelect} 57 onChange={setAlertManagerSourceName} 58 /> 59 {error && !loading && ( 60 <Alert severity="error" title="Error loading Alertmanager config"> 61 {error.message || 'Unknown error.'} 62 </Alert> 63 )} 64 {loading && !config && <LoadingPlaceholder text="loading configuration..." />} 65 {config && !error && ( 66 <Switch> 67 <Route exact={true} path="/alerting/notifications"> 68 <ReceiversAndTemplatesView config={config} alertManagerName={alertManagerSourceName} /> 69 </Route> 70 <Route exact={true} path="/alerting/notifications/templates/new"> 71 <NewTemplateView config={config} alertManagerSourceName={alertManagerSourceName} /> 72 </Route> 73 <Route exact={true} path="/alerting/notifications/templates/:name/edit"> 74 {({ match }: RouteChildrenProps<{ name: string }>) => 75 match?.params.name && ( 76 <EditTemplateView 77 alertManagerSourceName={alertManagerSourceName} 78 config={config} 79 templateName={decodeURIComponent(match?.params.name)} 80 /> 81 ) 82 } 83 </Route> 84 <Route exact={true} path="/alerting/notifications/receivers/new"> 85 <NewReceiverView config={config} alertManagerSourceName={alertManagerSourceName} /> 86 </Route> 87 <Route exact={true} path="/alerting/notifications/receivers/:name/edit"> 88 {({ match }: RouteChildrenProps<{ name: string }>) => 89 match?.params.name && ( 90 <EditReceiverView 91 alertManagerSourceName={alertManagerSourceName} 92 config={config} 93 receiverName={decodeURIComponent(match?.params.name)} 94 /> 95 ) 96 } 97 </Route> 98 <Route exact={true} path="/alerting/notifications/global-config"> 99 <GlobalConfigForm config={config} alertManagerSourceName={alertManagerSourceName} /> 100 </Route> 101 </Switch> 102 )} 103 </AlertingPageWrapper> 104 ); 105}; 106 107export default withErrorBoundary(Receivers, { style: 'page' }); 108