Alerting: Recognise & change UI for OnCall notification policy + contact point (#60259)

* Identify and show onCall contact points with a badge in case the plugin is installed

* Add onCall logo for onCall contact points Badge

* Refactor and make Grafana App Receiver type more generic, not only for onCall type

* Show onCall notification policy in the specific routing table with special onCall badge

* Fix tests

* Move onCall badge to the type column in contact points view table

* Fix typos and remove onCallIntegrations from tagTypes in alertingApi

* Fetch only local plugins instead of all (external are not needed) and don't fetch plugin details

* Use directly useGetOnCallIntegrationsQuery and more PR review suggestions

* Move onCall contact point to the top in the drop-down,  in the notification policy view

* Add PR review requested changes
This commit is contained in:
Sonia Aguilar
2022-12-21 14:46:55 +01:00
committed by GitHub
parent c537d3699c
commit e219e2a834
22 changed files with 282 additions and 40 deletions

View File

@@ -15,8 +15,8 @@ import {
uninstallPlugin,
} from '../api';
import { STATE_PREFIX } from '../constants';
import { mergeLocalsAndRemotes, updatePanels } from '../helpers';
import { CatalogPlugin, RemotePlugin } from '../types';
import { mapLocalToCatalog, mergeLocalsAndRemotes, updatePanels } from '../helpers';
import { CatalogPlugin, RemotePlugin, LocalPlugin } from '../types';
export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, thunkApi) => {
try {
@@ -33,6 +33,15 @@ export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, t
}
});
export const fetchAllLocal = createAsyncThunk(`${STATE_PREFIX}/fetchAllLocal`, async (_, thunkApi) => {
try {
const localPlugins = await getLocalPlugins();
return localPlugins.map((plugin: LocalPlugin) => mapLocalToCatalog(plugin));
} catch (e) {
return thunkApi.rejectWithValue('Unknown error.');
}
});
export const fetchRemotePlugins = createAsyncThunk<RemotePlugin[], void, { rejectValue: RemotePlugin[] }>(
`${STATE_PREFIX}/fetchRemotePlugins`,
async (_, thunkApi) => {

View File

@@ -6,7 +6,7 @@ import { useDispatch, useSelector } from 'app/types';
import { sortPlugins, Sorters } from '../helpers';
import { CatalogPlugin, PluginListDisplayMode } from '../types';
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions';
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall, fetchAllLocal } from './actions';
import { setDisplayMode } from './reducer';
import {
find,
@@ -58,6 +58,11 @@ export const useGetSingle = (id: string): CatalogPlugin | undefined => {
return useSelector((state) => selectById(state, id));
};
export const useGetSingleLocalWithoutDetails = (id: string): CatalogPlugin | undefined => {
useFetchAllLocal();
return useSelector((state) => selectById(state, id));
};
export const useGetErrors = (): PluginError[] => {
useFetchAll();
@@ -118,6 +123,16 @@ export const useFetchAll = () => {
}, []); // eslint-disable-line
};
// Only fetches in case they were not fetched yet
export const useFetchAllLocal = () => {
const dispatch = useDispatch();
const isNotFetched = useSelector(selectIsRequestNotFetched(fetchAllLocal.typePrefix));
useEffect(() => {
isNotFetched && dispatch(fetchAllLocal());
}, []); // eslint-disable-line
};
export const useFetchDetails = (id: string) => {
const dispatch = useDispatch();
const plugin = useSelector((state) => selectById(state, id));

View File

@@ -5,7 +5,15 @@ import { PanelPlugin } from '@grafana/data';
import { STATE_PREFIX } from '../constants';
import { CatalogPlugin, PluginListDisplayMode, ReducerState, RequestStatus } from '../types';
import { fetchAll, fetchDetails, install, uninstall, loadPluginDashboards, panelPluginLoaded } from './actions';
import {
fetchAll,
fetchDetails,
install,
uninstall,
loadPluginDashboards,
panelPluginLoaded,
fetchAllLocal,
} from './actions';
export const pluginsAdapter = createEntityAdapter<CatalogPlugin>();
@@ -54,6 +62,10 @@ const slice = createSlice({
.addCase(fetchAll.fulfilled, (state, action) => {
pluginsAdapter.upsertMany(state.items, action.payload);
})
// Fetch All local
.addCase(fetchAllLocal.fulfilled, (state, action) => {
pluginsAdapter.upsertMany(state.items, action.payload);
})
// Fetch Details
.addCase(fetchDetails.fulfilled, (state, action) => {
pluginsAdapter.updateOne(state.items, action.payload);