mirror of
https://github.com/grafana/grafana.git
synced 2025-09-20 07:06:08 +08:00

* Add new property to AlertmanagerConfig type * Implement fetching successfully applied configurations Added method to fetch them from the API and its corresponding action and reducer * Extract ConfigEditor as component to avoid code duplication * Display dropdown with valid configs upon error and allow to save them * Fix tests * Refactor to call new endpoint using RTK * Improve texts * Apply suggested refactor * Change constant casing * Only show config selector for Grafana AM * Remove ts-ignore * Move code together for simplicity * Remove invalid mock * Update endpoint and types based on backend changes * Rename property * Rename alermanager config property from backend changes * Disable editing old configurations Due to the latest backend changes, we no longer will provide the option to edit previous AM configurations in a textearea. Instead users will only be allowed to reset to a specific one with the same content. For this reason the textearea for old conf igurations is disabled and a different form action (not submit) is executed on the "reset config" button. The updateAlertManage rConfigAction is reset to its old functionality due to these changes. * Add id to AlertManagerCortexConfig type We'll need it to pass as a parameter to the new reset endpoint * Add new endpoint for resetting AM configs to an old version * Move the "Reset to selected configuration" button next to the drop-down * Add relative offset to configurations
147 lines
4.9 KiB
TypeScript
147 lines
4.9 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useEffect, useState, useMemo } from 'react';
|
|
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
|
import { Alert, useStyles2 } from '@grafana/ui';
|
|
import { useDispatch } from 'app/types';
|
|
|
|
import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName';
|
|
import { useAlertManagersByPermission } from '../../hooks/useAlertManagerSources';
|
|
import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector';
|
|
import {
|
|
deleteAlertManagerConfigAction,
|
|
fetchAlertManagerConfigAction,
|
|
updateAlertManagerConfigAction,
|
|
} from '../../state/actions';
|
|
import { GRAFANA_RULES_SOURCE_NAME, isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource';
|
|
import { initialAsyncRequestState } from '../../utils/redux';
|
|
import { AlertManagerPicker } from '../AlertManagerPicker';
|
|
|
|
import AlertmanagerConfigSelector, { ValidAmConfigOption } from './AlertmanagerConfigSelector';
|
|
import { ConfigEditor } from './ConfigEditor';
|
|
|
|
export interface FormValues {
|
|
configJSON: string;
|
|
}
|
|
|
|
export default function AlertmanagerConfig(): JSX.Element {
|
|
const dispatch = useDispatch();
|
|
const alertManagers = useAlertManagersByPermission('notification');
|
|
const [alertManagerSourceName, setAlertManagerSourceName] = useAlertManagerSourceName(alertManagers);
|
|
|
|
const [showConfirmDeleteAMConfig, setShowConfirmDeleteAMConfig] = useState(false);
|
|
const { loading: isDeleting } = useUnifiedAlertingSelector((state) => state.deleteAMConfig);
|
|
const { loading: isSaving } = useUnifiedAlertingSelector((state) => state.saveAMConfig);
|
|
|
|
const readOnly = alertManagerSourceName ? isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName) : false;
|
|
const styles = useStyles2(getStyles);
|
|
|
|
const configRequests = useUnifiedAlertingSelector((state) => state.amConfigs);
|
|
|
|
const [selectedAmConfig, setSelectedAmConfig] = useState<ValidAmConfigOption | undefined>();
|
|
|
|
const {
|
|
result: config,
|
|
loading: isLoadingConfig,
|
|
error: loadingError,
|
|
} = (alertManagerSourceName && configRequests[alertManagerSourceName]) || initialAsyncRequestState;
|
|
|
|
useEffect(() => {
|
|
if (alertManagerSourceName) {
|
|
dispatch(fetchAlertManagerConfigAction(alertManagerSourceName));
|
|
}
|
|
}, [alertManagerSourceName, dispatch]);
|
|
|
|
const resetConfig = () => {
|
|
if (alertManagerSourceName) {
|
|
dispatch(deleteAlertManagerConfigAction(alertManagerSourceName));
|
|
}
|
|
setShowConfirmDeleteAMConfig(false);
|
|
};
|
|
|
|
const defaultValues = useMemo(
|
|
(): FormValues => ({
|
|
configJSON: config ? JSON.stringify(config, null, 2) : '',
|
|
}),
|
|
[config]
|
|
);
|
|
|
|
const defaultValidValues = useMemo(
|
|
(): FormValues => ({
|
|
configJSON: selectedAmConfig ? JSON.stringify(selectedAmConfig.value, null, 2) : '',
|
|
}),
|
|
[selectedAmConfig]
|
|
);
|
|
|
|
const loading = isDeleting || isLoadingConfig || isSaving;
|
|
|
|
const onSubmit = (values: FormValues) => {
|
|
if (alertManagerSourceName && config) {
|
|
dispatch(
|
|
updateAlertManagerConfigAction({
|
|
newConfig: JSON.parse(values.configJSON),
|
|
oldConfig: config,
|
|
alertManagerSourceName,
|
|
successMessage: 'Alertmanager configuration updated.',
|
|
refetch: true,
|
|
})
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={styles.container}>
|
|
<AlertManagerPicker
|
|
current={alertManagerSourceName}
|
|
onChange={setAlertManagerSourceName}
|
|
dataSources={alertManagers}
|
|
/>
|
|
{loadingError && !loading && (
|
|
<>
|
|
<Alert
|
|
severity="error"
|
|
title="Your Alertmanager configuration is incorrect. These are the details of the error:"
|
|
>
|
|
{loadingError.message || 'Unknown error.'}
|
|
</Alert>
|
|
|
|
{alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME && (
|
|
<AlertmanagerConfigSelector
|
|
onChange={setSelectedAmConfig}
|
|
selectedAmConfig={selectedAmConfig}
|
|
defaultValues={defaultValidValues}
|
|
readOnly={true}
|
|
loading={loading}
|
|
onSubmit={onSubmit}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
{isDeleting && alertManagerSourceName !== GRAFANA_RULES_SOURCE_NAME && (
|
|
<Alert severity="info" title="Resetting Alertmanager configuration">
|
|
It might take a while...
|
|
</Alert>
|
|
)}
|
|
{alertManagerSourceName && config && (
|
|
<ConfigEditor
|
|
defaultValues={defaultValues}
|
|
onSubmit={(values) => onSubmit(values)}
|
|
readOnly={readOnly}
|
|
loading={loading}
|
|
alertManagerSourceName={alertManagerSourceName}
|
|
showConfirmDeleteAMConfig={showConfirmDeleteAMConfig}
|
|
onReset={() => setShowConfirmDeleteAMConfig(true)}
|
|
onConfirmReset={resetConfig}
|
|
onDismiss={() => setShowConfirmDeleteAMConfig(false)}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
container: css`
|
|
margin-bottom: ${theme.spacing(4)};
|
|
`,
|
|
});
|