grafana/public/app/features/plugins/admin/state/hooks.ts
Sonia Aguilar e219e2a834
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
2022-12-21 14:46:55 +01:00

156 lines
4.3 KiB
TypeScript

import { useEffect } from 'react';
import { PluginError } from '@grafana/data';
import { useDispatch, useSelector } from 'app/types';
import { sortPlugins, Sorters } from '../helpers';
import { CatalogPlugin, PluginListDisplayMode } from '../types';
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall, fetchAllLocal } from './actions';
import { setDisplayMode } from './reducer';
import {
find,
selectAll,
selectById,
selectIsRequestPending,
selectRequestError,
selectIsRequestNotFetched,
selectDisplayMode,
selectPluginErrors,
} from './selectors';
type Filters = {
query?: string; // Note: this will be an escaped regex string as it comes from `FilterInput`
filterBy?: string;
filterByType?: string;
sortBy?: Sorters;
};
export const useGetAllWithFilters = ({
query = '',
filterBy = 'installed',
filterByType = 'all',
sortBy = Sorters.nameAsc,
}: Filters) => {
useFetchAll();
const filtered = useSelector(find(query, filterBy, filterByType));
const { isLoading, error } = useFetchStatus();
const sortedAndFiltered = sortPlugins(filtered, sortBy);
return {
isLoading,
error,
plugins: sortedAndFiltered,
};
};
export const useGetAll = (): CatalogPlugin[] => {
useFetchAll();
return useSelector(selectAll);
};
export const useGetSingle = (id: string): CatalogPlugin | undefined => {
useFetchAll();
useFetchDetails(id);
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();
return useSelector(selectPluginErrors);
};
export const useInstall = () => {
const dispatch = useDispatch();
return (id: string, version?: string, isUpdating?: boolean) => dispatch(install({ id, version, isUpdating }));
};
export const useUninstall = () => {
const dispatch = useDispatch();
return (id: string) => dispatch(uninstall(id));
};
export const useIsRemotePluginsAvailable = () => {
const error = useSelector(selectRequestError(fetchRemotePlugins.typePrefix));
return error === null;
};
export const useFetchStatus = () => {
const isLoading = useSelector(selectIsRequestPending(fetchAll.typePrefix));
const error = useSelector(selectRequestError(fetchAll.typePrefix));
return { isLoading, error };
};
export const useFetchDetailsStatus = () => {
const isLoading = useSelector(selectIsRequestPending(fetchDetails.typePrefix));
const error = useSelector(selectRequestError(fetchDetails.typePrefix));
return { isLoading, error };
};
export const useInstallStatus = () => {
const isInstalling = useSelector(selectIsRequestPending(install.typePrefix));
const error = useSelector(selectRequestError(install.typePrefix));
return { isInstalling, error };
};
export const useUninstallStatus = () => {
const isUninstalling = useSelector(selectIsRequestPending(uninstall.typePrefix));
const error = useSelector(selectRequestError(uninstall.typePrefix));
return { isUninstalling, error };
};
// Only fetches in case they were not fetched yet
export const useFetchAll = () => {
const dispatch = useDispatch();
const isNotFetched = useSelector(selectIsRequestNotFetched(fetchAll.typePrefix));
useEffect(() => {
isNotFetched && dispatch(fetchAll());
}, []); // 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));
const isNotFetching = !useSelector(selectIsRequestPending(fetchDetails.typePrefix));
const shouldFetch = isNotFetching && plugin && !plugin.details;
useEffect(() => {
shouldFetch && dispatch(fetchDetails(id));
}, [plugin]); // eslint-disable-line
};
export const useDisplayMode = () => {
const dispatch = useDispatch();
const displayMode = useSelector(selectDisplayMode);
return {
displayMode,
setDisplayMode: (v: PluginListDisplayMode) => dispatch(setDisplayMode(v)),
};
};