import { DashboardSection, SearchAction } from '../types'; import { getFlattenedSections, getLookupField, markSelected } from '../utils'; import { FETCH_ITEMS, FETCH_RESULTS, TOGGLE_SECTION, MOVE_SELECTION_DOWN, MOVE_SELECTION_UP, SEARCH_START, FETCH_ITEMS_START, } from './actionTypes'; export interface DashboardsSearchState { results: DashboardSection[]; loading: boolean; selectedIndex: number; /** Used for first time page load */ initialLoading: boolean; } export const dashboardsSearchState: DashboardsSearchState = { results: [], loading: true, initialLoading: true, selectedIndex: 0, }; export const searchReducer = (state: DashboardsSearchState, action: SearchAction) => { switch (action.type) { case SEARCH_START: if (!state.loading) { return { ...state, loading: true }; } return state; case FETCH_RESULTS: { const results = action.payload; // Highlight the first item ('Starred' folder) if (results.length > 0) { results[0].selected = true; } return { ...state, results, loading: false, initialLoading: false }; } case TOGGLE_SECTION: { const section = action.payload; const lookupField = getLookupField(section.title); return { ...state, results: state.results.map((result: DashboardSection) => { if (section[lookupField] === result[lookupField]) { return { ...result, expanded: !result.expanded }; } return result; }), }; } case FETCH_ITEMS: { const { section, items } = action.payload; return { ...state, itemsFetching: false, results: state.results.map((result: DashboardSection) => { if (section.id === result.id) { return { ...result, items, itemsFetching: false }; } return result; }), }; } case FETCH_ITEMS_START: { const id = action.payload; if (id) { return { ...state, results: state.results.map((result) => (result.id === id ? { ...result, itemsFetching: true } : result)), }; } return state; } case MOVE_SELECTION_DOWN: { const flatIds = getFlattenedSections(state.results); if (state.selectedIndex < flatIds.length - 1) { const newIndex = state.selectedIndex + 1; const selectedId = flatIds[newIndex]; return { ...state, selectedIndex: newIndex, results: markSelected(state.results, selectedId), }; } return state; } case MOVE_SELECTION_UP: if (state.selectedIndex > 0) { const flatIds = getFlattenedSections(state.results); const newIndex = state.selectedIndex - 1; const selectedId = flatIds[newIndex]; return { ...state, selectedIndex: newIndex, results: markSelected(state.results, selectedId), }; } return state; default: return state; } };