diff --git a/public/app/features/alerting/unified/Settings.test.tsx b/public/app/features/alerting/unified/Settings.test.tsx index 401b4b6fee7..d086ba7663d 100644 --- a/public/app/features/alerting/unified/Settings.test.tsx +++ b/public/app/features/alerting/unified/Settings.test.tsx @@ -1,5 +1,4 @@ import { screen, waitFor, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; import { render } from 'test/test-utils'; import { byRole, byTestId, byText } from 'testing-library-selector'; @@ -26,8 +25,9 @@ const ui = { statusReceiving: byText(/receiving grafana-managed alerts/i), statusNotReceiving: byText(/not receiving/i), - configurationDrawer: byRole('dialog', { name: 'Drawer title Internal Grafana Alertmanager' }), + configurationDrawer: byRole('dialog', { name: 'Drawer title Grafana built-in Alertmanager' }), editConfigurationButton: byRole('button', { name: /edit configuration/i }), + viewConfigurationButton: byRole('button', { name: /view configuration/i }), saveConfigurationButton: byRole('button', { name: /save/i }), enableButton: byRole('button', { name: 'Enable' }), @@ -54,7 +54,7 @@ describe('Alerting settings', () => { expect(ui.statusReceiving.get(ui.builtInAlertmanagerCard.get())).toBeInTheDocument(); - // check external altermanagers + // check external alertmanagers DataSourcesResponse.forEach((ds) => { // get the card for datasource const card = ui.alertmanagerCard(ds.name).get(); @@ -74,45 +74,36 @@ describe('Alerting settings', () => { }); it('should be able to view configuration', async () => { - render(); + const { user } = render(); // wait for loading to be done await waitFor(() => expect(ui.builtInAlertmanagerSection.get()).toBeInTheDocument()); // open configuration drawer const internalAMCard = ui.builtInAlertmanagerCard.get(); - const editInternal = ui.editConfigurationButton.get(internalAMCard); - await userEvent.click(editInternal); - - await waitFor(() => { - expect(ui.configurationDrawer.get()).toBeInTheDocument(); - }); - - await userEvent.click(ui.saveConfigurationButton.get()); - expect(ui.saveConfigurationButton.get()).toBeDisabled(); + await user.click(ui.viewConfigurationButton.get(internalAMCard)); + expect(await ui.configurationDrawer.find()).toBeInTheDocument(); - await waitFor(() => { - expect(ui.saveConfigurationButton.get()).toBeEnabled(); - }); + expect(ui.saveConfigurationButton.query()).not.toBeInTheDocument(); }); it('should be able to view versions', async () => { - render(); + const { user } = render(); // wait for loading to be done - await waitFor(() => expect(ui.builtInAlertmanagerSection.get()).toBeInTheDocument()); + expect(await ui.builtInAlertmanagerSection.find()).toBeInTheDocument(); // open configuration drawer const internalAMCard = ui.builtInAlertmanagerCard.get(); - const editInternal = ui.editConfigurationButton.get(internalAMCard); - await userEvent.click(editInternal); + await user.click(ui.viewConfigurationButton.get(internalAMCard)); + expect(await ui.configurationDrawer.find()).toBeInTheDocument(); await waitFor(() => { expect(ui.configurationDrawer.get()).toBeInTheDocument(); }); // click versions tab - await userEvent.click(ui.versionsTab.get()); + await user.click(ui.versionsTab.get()); await waitFor(() => { expect(screen.getByText(/last applied/i)).toBeInTheDocument(); diff --git a/public/app/features/alerting/unified/components/settings/AlertmanagerCard.tsx b/public/app/features/alerting/unified/components/settings/AlertmanagerCard.tsx index e0aa3eadf64..8499c8161cc 100644 --- a/public/app/features/alerting/unified/components/settings/AlertmanagerCard.tsx +++ b/public/app/features/alerting/unified/components/settings/AlertmanagerCard.tsx @@ -121,7 +121,11 @@ export function AlertmanagerCard({ {/* ⚠️ provisioned Data sources cannot have their "enable" / "disable" actions but we should still allow editing of the configuration */} {showActions ? ( <> diff --git a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.test.tsx b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.test.tsx index c629073d589..5c1592ca098 100644 --- a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.test.tsx +++ b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.test.tsx @@ -47,20 +47,11 @@ describe('Alerting Settings', () => { grantUserPermissions([AccessControlAction.AlertingNotificationsRead, AccessControlAction.AlertingInstanceRead]); }); - it('should be able to reset alertmanager config', async () => { + it('should not be able to reset alertmanager config', async () => { const onReset = jest.fn(); renderConfiguration('grafana', { onReset }); - await userEvent.click(await ui.resetButton.find()); - - await waitFor(() => { - expect(ui.resetConfirmButton.query()).toBeInTheDocument(); - }); - - await userEvent.click(ui.resetConfirmButton.get()); - - await waitFor(() => expect(onReset).toHaveBeenCalled()); - expect(onReset).toHaveBeenLastCalledWith('grafana'); + expect(ui.resetButton.query()).not.toBeInTheDocument(); }); it('should be able to cancel', async () => { @@ -100,4 +91,20 @@ describe('vanilla Alertmanager', () => { expect(ui.saveButton.get()).toBeInTheDocument(); expect(ui.resetButton.get()).toBeInTheDocument(); }); + + it('should be able to reset non-Grafana alertmanager config', async () => { + const onReset = jest.fn(); + renderConfiguration(PROVISIONED_MIMIR_ALERTMANAGER_UID, { onReset }); + + expect(ui.cancelButton.get()).toBeInTheDocument(); + expect(ui.saveButton.get()).toBeInTheDocument(); + expect(ui.resetButton.get()).toBeInTheDocument(); + + await userEvent.click(ui.resetButton.get()); + + await userEvent.click(ui.resetConfirmButton.get()); + + await waitFor(() => expect(onReset).toHaveBeenCalled()); + expect(onReset).toHaveBeenLastCalledWith(PROVISIONED_MIMIR_ALERTMANAGER_UID); + }); }); diff --git a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx index 05a02bcbec4..bd756fe9241 100644 --- a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx +++ b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx @@ -28,12 +28,12 @@ export default function AlertmanagerConfig({ alertmanagerName, onDismiss, onSave const { loading: isDeleting, error: deletingError } = useUnifiedAlertingSelector((state) => state.deleteAMConfig); const { loading: isSaving, error: savingError } = useUnifiedAlertingSelector((state) => state.saveAMConfig); const [showResetConfirmation, setShowResetConfirmation] = useState(false); + const isGrafanaManagedAlertmanager = alertmanagerName === GRAFANA_RULES_SOURCE_NAME; // ⚠️ provisioned data sources should not prevent the configuration from being edited const immutableDataSource = alertmanagerName ? isVanillaPrometheusAlertManagerDataSource(alertmanagerName) : false; - const readOnly = immutableDataSource; + const readOnly = immutableDataSource || isGrafanaManagedAlertmanager; - const isGrafanaManagedAlertmanager = alertmanagerName === GRAFANA_RULES_SOURCE_NAME; const styles = useStyles2(getStyles); const { @@ -128,12 +128,28 @@ export default function AlertmanagerConfig({ alertmanagerName, onDismiss, onSave ); } - const confirmationText = isGrafanaManagedAlertmanager - ? `Are you sure you want to reset configuration for the Grafana Alertmanager? Contact points and notification policies will be reset to their defaults.` - : `Are you sure you want to reset configuration for "${alertmanagerName}"? Contact points and notification policies will be reset to their defaults.`; + const confirmationText = t( + 'alerting.alertmanager-config.reset-confirmation', + 'Are you sure you want to reset configuration for "{{alertmanagerName}}"? Contact points and notification policies will be reset to their defaults.', + { alertmanagerName } + ); return (
+ {isGrafanaManagedAlertmanager && ( + + + The internal Grafana Alertmanager configuration cannot be manually changed. To change this configuration, + edit the individual resources through the UI. + + + )} {/* form error state */} {errors.configJSON && ( { setDataSourceName(dataSourceName); setOpen(true); @@ -33,14 +37,29 @@ export function useEditConfigurationDrawer() { } const isGrafanaAlertmanager = dataSourceName === GRAFANA_RULES_SOURCE_NAME; - const title = isGrafanaAlertmanager ? 'Internal Grafana Alertmanager' : dataSourceName; + const title = isGrafanaAlertmanager + ? t( + 'alerting.use-edit-configuration-drawer.drawer.internal-grafana-alertmanager-title', + 'Grafana built-in Alertmanager' + ) + : dataSourceName; + + const subtitle = readOnly + ? t( + 'alerting.use-edit-configuration-drawer.drawer.title-view-the-alertmanager-configuration', + 'View Alertmanager configuration' + ) + : t( + 'alerting.use-edit-configuration-drawer.drawer.title-edit-the-alertmanager-configuration', + 'Edit Alertmanager configuration' + ); // @todo check copy return ( ); - }, [open, dataSourceName, handleDismiss, activeTab, updateAlertmanagerSettings, resetAlertmanagerSettings]); + }, [open, dataSourceName, readOnly, handleDismiss, activeTab, updateAlertmanagerSettings, resetAlertmanagerSettings]); return [drawer, showConfiguration, handleDismiss] as const; } diff --git a/public/app/features/alerting/unified/components/settings/InternalAlertmanager.tsx b/public/app/features/alerting/unified/components/settings/InternalAlertmanager.tsx index add2e0f852d..b40619143f3 100644 --- a/public/app/features/alerting/unified/components/settings/InternalAlertmanager.tsx +++ b/public/app/features/alerting/unified/components/settings/InternalAlertmanager.tsx @@ -30,6 +30,7 @@ export default function InternalAlertmanager({ onEditConfiguration }: Props) { onEditConfiguration={handleEditConfiguration} onEnable={handleEnable} onDisable={handleDisable} + readOnly /> ); } diff --git a/public/app/features/alerting/unified/components/settings/VersionManager.tsx b/public/app/features/alerting/unified/components/settings/VersionManager.tsx index b5285d5f990..9a47437094e 100644 --- a/public/app/features/alerting/unified/components/settings/VersionManager.tsx +++ b/public/app/features/alerting/unified/components/settings/VersionManager.tsx @@ -94,11 +94,15 @@ const AlertmanagerConfigurationVersionManager = ({ } if (isLoading) { - return 'Loading...'; + return Loading...; } if (!historicalConfigs.length) { - return 'No previous configurations'; + return ( + + No previous configurations + + ); } // with this function we'll compute the diff with the previous version; that way the user can get some idea of how many lines where changed in each update that was applied diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index e7633b9d8a3..f01845beb3f 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -413,16 +413,21 @@ }, "alertmanager-card": { "disable": "Disable", + "edit-configuration": "Edit configuration", "enable": "Enable", "not-receiving-grafana-managed-alerts": "Not receiving Grafana managed alerts", "text-activation-in-progress": "Activation in progress", "text-failed-to-adopt-alertmanager": "Failed to adopt Alertmanager", "text-inconclusive": "Inconclusive", "text-receiving-grafanamanaged-alerts": "Receiving Grafana-managed alerts", - "title-alerting-settings": "Alerting settings" + "title-alerting-settings": "Alerting settings", + "view-configuration": "View configuration" }, "alertmanager-config": { + "gma-manual-configuration-description": "The internal Grafana Alertmanager configuration cannot be manually changed. To change this configuration, edit the individual resources through the UI.", + "gma-manual-configuration-is-not-supported": "Manual configuration changes not supported", "reset": "Reset", + "reset-confirmation": "Are you sure you want to reset configuration for \"{{alertmanagerName}}\"? Contact points and notification policies will be reset to their defaults.", "resetting-configuration-might-while": "Resetting configuration, this might take a while.", "title-failed-to-load-alertmanager-configuration": "Failed to load Alertmanager configuration", "title-oops-something-went-wrong": "Oops, something went wrong", @@ -435,6 +440,8 @@ "restore": "Restore", "text-latest": "Latest" }, + "loading": "Loading...", + "no-previous-configurations": "No previous configurations", "this-might-take-a-while": "This might take a while...", "title-failed-to-load-configuration-history": "Failed to load configuration history", "title-restore-version": "Restore version", @@ -2075,8 +2082,11 @@ }, "use-edit-configuration-drawer": { "drawer": { + "internal-grafana-alertmanager-title": "Grafana built-in Alertmanager", "label-json-model": "JSON Model", - "label-versions": "Versions" + "label-versions": "Versions", + "title-edit-the-alertmanager-configuration": "Edit Alertmanager configuration", + "title-view-the-alertmanager-configuration": "View Alertmanager configuration" } }, "use-edit-policy-modal": {