dashboardSearch.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { DashboardSection, SearchAction } from '../types';
  2. import { getFlattenedSections, getLookupField, markSelected } from '../utils';
  3. import {
  4. FETCH_ITEMS,
  5. FETCH_RESULTS,
  6. TOGGLE_SECTION,
  7. MOVE_SELECTION_DOWN,
  8. MOVE_SELECTION_UP,
  9. SEARCH_START,
  10. FETCH_ITEMS_START,
  11. } from './actionTypes';
  12. export interface DashboardsSearchState {
  13. results: DashboardSection[];
  14. loading: boolean;
  15. selectedIndex: number;
  16. /** Used for first time page load */
  17. initialLoading: boolean;
  18. }
  19. export const dashboardsSearchState: DashboardsSearchState = {
  20. results: [],
  21. loading: true,
  22. initialLoading: true,
  23. selectedIndex: 0,
  24. };
  25. export const searchReducer = (state: DashboardsSearchState, action: SearchAction) => {
  26. switch (action.type) {
  27. case SEARCH_START:
  28. if (!state.loading) {
  29. return { ...state, loading: true };
  30. }
  31. return state;
  32. case FETCH_RESULTS: {
  33. const results = action.payload;
  34. // Highlight the first item ('Starred' folder)
  35. if (results.length > 0) {
  36. results[0].selected = true;
  37. }
  38. return { ...state, results, loading: false, initialLoading: false };
  39. }
  40. case TOGGLE_SECTION: {
  41. const section = action.payload;
  42. const lookupField = getLookupField(section.title);
  43. return {
  44. ...state,
  45. results: state.results.map((result: DashboardSection) => {
  46. if (section[lookupField] === result[lookupField]) {
  47. return { ...result, expanded: !result.expanded };
  48. }
  49. return result;
  50. }),
  51. };
  52. }
  53. case FETCH_ITEMS: {
  54. const { section, items } = action.payload;
  55. return {
  56. ...state,
  57. itemsFetching: false,
  58. results: state.results.map((result: DashboardSection) => {
  59. if (section.id === result.id) {
  60. return { ...result, items, itemsFetching: false };
  61. }
  62. return result;
  63. }),
  64. };
  65. }
  66. case FETCH_ITEMS_START: {
  67. const id = action.payload;
  68. if (id) {
  69. return {
  70. ...state,
  71. results: state.results.map((result) => (result.id === id ? { ...result, itemsFetching: true } : result)),
  72. };
  73. }
  74. return state;
  75. }
  76. case MOVE_SELECTION_DOWN: {
  77. const flatIds = getFlattenedSections(state.results);
  78. if (state.selectedIndex < flatIds.length - 1) {
  79. const newIndex = state.selectedIndex + 1;
  80. const selectedId = flatIds[newIndex];
  81. return {
  82. ...state,
  83. selectedIndex: newIndex,
  84. results: markSelected(state.results, selectedId),
  85. };
  86. }
  87. return state;
  88. }
  89. case MOVE_SELECTION_UP:
  90. if (state.selectedIndex > 0) {
  91. const flatIds = getFlattenedSections(state.results);
  92. const newIndex = state.selectedIndex - 1;
  93. const selectedId = flatIds[newIndex];
  94. return {
  95. ...state,
  96. selectedIndex: newIndex,
  97. results: markSelected(state.results, selectedId),
  98. };
  99. }
  100. return state;
  101. default:
  102. return state;
  103. }
  104. };