mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fix alertmanager query param when returning to silences list (#80021)
* Add alertmanager query param when returning to silences list. Sync query and storage alertmanager param * Remove unused imports
This commit is contained in:
parent
9cdd519e53
commit
6fd0ae0474
@ -15,6 +15,8 @@ import { SilenceState } from '../../../plugins/datasource/alertmanager/types';
|
||||
import Silences from './Silences';
|
||||
import { createOrUpdateSilence, fetchAlerts, fetchSilences } from './api/alertmanager';
|
||||
import { grantUserPermissions, mockAlertmanagerAlert, mockDataSource, MockDataSourceSrv, mockSilence } from './mocks';
|
||||
import { AlertmanagerProvider } from './state/AlertmanagerContext';
|
||||
import { setupDataSources } from './testSetup/datasources';
|
||||
import { parseMatchers } from './utils/alertmanager';
|
||||
import { DataSourceType } from './utils/datasource';
|
||||
|
||||
@ -37,7 +39,9 @@ const renderSilences = (location = '/alerting/silences/') => {
|
||||
|
||||
return render(
|
||||
<TestProvider>
|
||||
<Silences />
|
||||
<AlertmanagerProvider accessType="instance">
|
||||
<Silences />
|
||||
</AlertmanagerProvider>
|
||||
</TestProvider>
|
||||
);
|
||||
};
|
||||
@ -218,7 +222,7 @@ describe('Silence edit', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
setUserLogged(true);
|
||||
setDataSourceSrv(new MockDataSourceSrv(dataSources));
|
||||
setupDataSources(dataSources.am);
|
||||
});
|
||||
|
||||
it('Should not render createdBy if user is logged in and has a name', async () => {
|
||||
@ -325,4 +329,32 @@ describe('Silence edit', () => {
|
||||
},
|
||||
TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
'silences page should contain alertmanager parameter after creating a silence',
|
||||
async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
renderSilences(`${baseUrlPath}?alertmanager=Alertmanager`);
|
||||
await waitFor(() => expect(ui.editor.durationField.query()).not.toBeNull());
|
||||
|
||||
await user.type(ui.editor.matcherName.getAll()[0], 'foo');
|
||||
await user.type(ui.editor.matcherOperatorSelect.getAll()[0], '=');
|
||||
await user.type(ui.editor.matcherValue.getAll()[0], 'bar');
|
||||
|
||||
await user.click(ui.editor.submit.get());
|
||||
|
||||
await waitFor(() =>
|
||||
expect(mocks.api.createOrUpdateSilence).toHaveBeenCalledWith(
|
||||
'Alertmanager',
|
||||
expect.objectContaining({
|
||||
matchers: [{ isEqual: true, isRegex: false, name: 'foo', value: 'bar' }],
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(locationService.getSearch().get('alertmanager')).toBe('Alertmanager');
|
||||
},
|
||||
TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import store from 'app/core/store';
|
||||
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
|
||||
|
||||
import { useAlertManagersByPermission } from '../hooks/useAlertManagerSources';
|
||||
import { useURLSearchParams } from '../hooks/useURLSearchParams';
|
||||
import { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from '../utils/constants';
|
||||
import {
|
||||
AlertManagerDataSource,
|
||||
@ -30,7 +30,7 @@ interface Props extends React.PropsWithChildren {
|
||||
}
|
||||
|
||||
const AlertmanagerProvider = ({ children, accessType, alertmanagerSourceName }: Props) => {
|
||||
const [queryParams, updateQueryParams] = useQueryParams();
|
||||
const [queryParams, updateQueryParams] = useURLSearchParams();
|
||||
const allAvailableAlertManagers = useAlertManagersByPermission(accessType);
|
||||
const availableAlertManagers = allAvailableAlertManagers.availableInternalDataSources.concat(
|
||||
allAvailableAlertManagers.availableExternalDataSources
|
||||
@ -44,7 +44,7 @@ const AlertmanagerProvider = ({ children, accessType, alertmanagerSourceName }:
|
||||
|
||||
if (selectedAlertManager === GRAFANA_RULES_SOURCE_NAME) {
|
||||
store.delete(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY);
|
||||
updateQueryParams({ [ALERTMANAGER_NAME_QUERY_KEY]: null });
|
||||
updateQueryParams({ [ALERTMANAGER_NAME_QUERY_KEY]: undefined });
|
||||
} else {
|
||||
store.set(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, selectedAlertManager);
|
||||
updateQueryParams({ [ALERTMANAGER_NAME_QUERY_KEY]: selectedAlertManager });
|
||||
@ -53,10 +53,19 @@ const AlertmanagerProvider = ({ children, accessType, alertmanagerSourceName }:
|
||||
[availableAlertManagers, updateQueryParams]
|
||||
);
|
||||
|
||||
const sourceFromQuery = queryParams[ALERTMANAGER_NAME_QUERY_KEY];
|
||||
const sourceFromQuery = queryParams.get(ALERTMANAGER_NAME_QUERY_KEY);
|
||||
const sourceFromStore = store.get(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY);
|
||||
const defaultSource = GRAFANA_RULES_SOURCE_NAME;
|
||||
|
||||
// This overrides AM in the store to be in sync with the one in the URL
|
||||
// When the user uses multiple tabs with different AMs, the store will be changing all the time
|
||||
// It's safest to always use URLs with alertmanager query param
|
||||
React.useEffect(() => {
|
||||
if (sourceFromQuery && sourceFromQuery !== sourceFromStore) {
|
||||
store.set(ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, sourceFromQuery);
|
||||
}
|
||||
}, [sourceFromQuery, sourceFromStore]);
|
||||
|
||||
// queryParam > localStorage > default
|
||||
const desiredAlertmanager = alertmanagerSourceName ?? sourceFromQuery ?? sourceFromStore ?? defaultSource;
|
||||
const selectedAlertmanager = isAlertManagerAvailable(availableAlertManagers, desiredAlertmanager)
|
||||
|
@ -575,7 +575,7 @@ export const createOrUpdateSilenceAction = createAsyncThunk<void, UpdateSilenceA
|
||||
(async () => {
|
||||
await createOrUpdateSilence(alertManagerSourceName, payload);
|
||||
if (exitOnSave) {
|
||||
locationService.push('/alerting/silences');
|
||||
locationService.push(makeAMLink('/alerting/silences', alertManagerSourceName));
|
||||
}
|
||||
})()
|
||||
),
|
||||
|
@ -105,7 +105,7 @@ export function makeAMLink(path: string, alertManagerName?: string, options?: UR
|
||||
const search = new URLSearchParams(options);
|
||||
|
||||
if (alertManagerName) {
|
||||
search.append(ALERTMANAGER_NAME_QUERY_KEY, alertManagerName);
|
||||
search.set(ALERTMANAGER_NAME_QUERY_KEY, alertManagerName);
|
||||
}
|
||||
return `${path}?${search.toString()}`;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user