actions.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { AnyAction } from '@reduxjs/toolkit';
  2. import { Dispatch } from 'react';
  3. import { from, merge, of, Subscription, timer } from 'rxjs';
  4. import { catchError, finalize, mapTo, mergeMap, share, takeUntil } from 'rxjs/operators';
  5. import { deleteLibraryPanel as apiDeleteLibraryPanel, getLibraryPanels } from '../../state/api';
  6. import { initialLibraryPanelsViewState, initSearch, searchCompleted } from './reducer';
  7. type DispatchResult = (dispatch: Dispatch<AnyAction>) => void;
  8. interface SearchArgs {
  9. perPage: number;
  10. page: number;
  11. searchString: string;
  12. sortDirection?: string;
  13. panelFilter?: string[];
  14. folderFilter?: string[];
  15. currentPanelId?: string;
  16. }
  17. export function searchForLibraryPanels(args: SearchArgs): DispatchResult {
  18. return function (dispatch) {
  19. const subscription = new Subscription();
  20. const dataObservable = from(
  21. getLibraryPanels({
  22. searchString: args.searchString,
  23. perPage: args.perPage,
  24. page: args.page,
  25. excludeUid: args.currentPanelId,
  26. sortDirection: args.sortDirection,
  27. typeFilter: args.panelFilter,
  28. folderFilter: args.folderFilter,
  29. })
  30. ).pipe(
  31. mergeMap(({ perPage, elements: libraryPanels, page, totalCount }) =>
  32. of(searchCompleted({ libraryPanels, page, perPage, totalCount }))
  33. ),
  34. catchError((err) => {
  35. console.error(err);
  36. return of(searchCompleted({ ...initialLibraryPanelsViewState, page: args.page, perPage: args.perPage }));
  37. }),
  38. finalize(() => subscription.unsubscribe()), // make sure we unsubscribe
  39. share()
  40. );
  41. subscription.add(
  42. // If 50ms without a response dispatch a loading state
  43. // mapTo will translate the timer event into a loading state
  44. // takeUntil will cancel the timer emit when first response is received on the dataObservable
  45. merge(timer(50).pipe(mapTo(initSearch()), takeUntil(dataObservable)), dataObservable).subscribe(dispatch)
  46. );
  47. };
  48. }
  49. export function deleteLibraryPanel(uid: string, args: SearchArgs): DispatchResult {
  50. return async function (dispatch) {
  51. try {
  52. await apiDeleteLibraryPanel(uid);
  53. searchForLibraryPanels(args)(dispatch);
  54. } catch (e) {
  55. console.error(e);
  56. }
  57. };
  58. }
  59. export function asyncDispatcher(dispatch: Dispatch<AnyAction>) {
  60. return function (action: any) {
  61. if (action instanceof Function) {
  62. return action(dispatch);
  63. }
  64. return dispatch(action);
  65. };
  66. }