hooks.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { useEffect } from 'react';
  2. import { useDispatch, useSelector } from 'react-redux';
  3. import { PluginError } from '@grafana/data';
  4. import { sortPlugins, Sorters } from '../helpers';
  5. import { CatalogPlugin, PluginCatalogStoreState, PluginListDisplayMode } from '../types';
  6. import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions';
  7. import { setDisplayMode } from './reducer';
  8. import {
  9. find,
  10. selectAll,
  11. selectById,
  12. selectIsRequestPending,
  13. selectRequestError,
  14. selectIsRequestNotFetched,
  15. selectDisplayMode,
  16. selectPluginErrors,
  17. } from './selectors';
  18. type Filters = {
  19. query?: string;
  20. filterBy?: string;
  21. filterByType?: string;
  22. sortBy?: Sorters;
  23. };
  24. export const useGetAllWithFilters = ({
  25. query = '',
  26. filterBy = 'installed',
  27. filterByType = 'all',
  28. sortBy = Sorters.nameAsc,
  29. }: Filters) => {
  30. useFetchAll();
  31. const filtered = useSelector(find(query, filterBy, filterByType));
  32. const { isLoading, error } = useFetchStatus();
  33. const sortedAndFiltered = sortPlugins(filtered, sortBy);
  34. return {
  35. isLoading,
  36. error,
  37. plugins: sortedAndFiltered,
  38. };
  39. };
  40. export const useGetAll = (): CatalogPlugin[] => {
  41. useFetchAll();
  42. return useSelector(selectAll);
  43. };
  44. export const useGetSingle = (id: string): CatalogPlugin | undefined => {
  45. useFetchAll();
  46. useFetchDetails(id);
  47. return useSelector((state: PluginCatalogStoreState) => selectById(state, id));
  48. };
  49. export const useGetErrors = (): PluginError[] => {
  50. useFetchAll();
  51. return useSelector(selectPluginErrors);
  52. };
  53. export const useInstall = () => {
  54. const dispatch = useDispatch();
  55. return (id: string, version?: string, isUpdating?: boolean) => dispatch(install({ id, version, isUpdating }));
  56. };
  57. export const useUninstall = () => {
  58. const dispatch = useDispatch();
  59. return (id: string) => dispatch(uninstall(id));
  60. };
  61. export const useIsRemotePluginsAvailable = () => {
  62. const error = useSelector(selectRequestError(fetchRemotePlugins.typePrefix));
  63. return error === null;
  64. };
  65. export const useFetchStatus = () => {
  66. const isLoading = useSelector(selectIsRequestPending(fetchAll.typePrefix));
  67. const error = useSelector(selectRequestError(fetchAll.typePrefix));
  68. return { isLoading, error };
  69. };
  70. export const useFetchDetailsStatus = () => {
  71. const isLoading = useSelector(selectIsRequestPending(fetchDetails.typePrefix));
  72. const error = useSelector(selectRequestError(fetchDetails.typePrefix));
  73. return { isLoading, error };
  74. };
  75. export const useInstallStatus = () => {
  76. const isInstalling = useSelector(selectIsRequestPending(install.typePrefix));
  77. const error = useSelector(selectRequestError(install.typePrefix));
  78. return { isInstalling, error };
  79. };
  80. export const useUninstallStatus = () => {
  81. const isUninstalling = useSelector(selectIsRequestPending(uninstall.typePrefix));
  82. const error = useSelector(selectRequestError(uninstall.typePrefix));
  83. return { isUninstalling, error };
  84. };
  85. // Only fetches in case they were not fetched yet
  86. export const useFetchAll = () => {
  87. const dispatch = useDispatch();
  88. const isNotFetched = useSelector(selectIsRequestNotFetched(fetchAll.typePrefix));
  89. useEffect(() => {
  90. isNotFetched && dispatch(fetchAll());
  91. }, []); // eslint-disable-line
  92. };
  93. export const useFetchDetails = (id: string) => {
  94. const dispatch = useDispatch();
  95. const plugin = useSelector((state: PluginCatalogStoreState) => selectById(state, id));
  96. const isNotFetching = !useSelector(selectIsRequestPending(fetchDetails.typePrefix));
  97. const shouldFetch = isNotFetching && plugin && !plugin.details;
  98. useEffect(() => {
  99. shouldFetch && dispatch(fetchDetails(id));
  100. }, [plugin]); // eslint-disable-line
  101. };
  102. export const useDisplayMode = () => {
  103. const dispatch = useDispatch();
  104. const displayMode = useSelector(selectDisplayMode);
  105. return {
  106. displayMode,
  107. setDisplayMode: (v: PluginListDisplayMode) => dispatch(setDisplayMode(v)),
  108. };
  109. };