UNPKG

addsearch-search-ui

Version:

JavaScript library to develop Search UIs for the web

217 lines (176 loc) 6.52 kB
import { AUTOCOMPLETE_FETCH_START, AUTOCOMPLETE_SUGGESTIONS_RESULTS, AUTOCOMPLETE_CUSTOM_FIELDS_RESULTS, AUTOCOMPLETE_SUGGESTIONS_CLEAR, AUTOCOMPLETE_CUSTOM_FIELDS_CLEAR, AUTOCOMPLETE_SEARCH_RESULTS, AUTOCOMPLETE_SEARCH_CLEAR, AUTOCOMPLETE_SHOW, AUTOCOMPLETE_HIDE, HIDE_AUTOMATICALLY, KEYBOARD_EVENT, ARROW_UP, ARROW_DOWN, SET_ACTIVE_SUGGESTION, SUGGESTIONS_JSON_KEY, AUTOCOMPLETE_HIDE_AND_DROP_RENDERING, CUSTOM_FIELDS_JSON_KEY } from '../actions/autocomplete'; const initialState = { pendingRequests: [], keyword: null, suggestions: [], customFields: [], activeSuggestionIndex: null, setSuggestionToSearchField: false, searchResults: {}, searchResultsStats: {}, hideAutomatically: true, visible: false }; export default function searchsuggestions(state = initialState, action) { switch (action.type) { case AUTOCOMPLETE_FETCH_START: // Add to pending requests let addPendingReq = [...state.pendingRequests]; if (addPendingReq.indexOf(action.jsonKey) === -1) { addPendingReq.push(action.jsonKey); } return Object.assign({}, state, { pendingRequests: addPendingReq, dropRendering: false }); case AUTOCOMPLETE_SUGGESTIONS_CLEAR: return Object.assign({}, state, { suggestions: [], activeSuggestionIndex: null }); case AUTOCOMPLETE_CUSTOM_FIELDS_CLEAR: return Object.assign({}, state, { customFields: [], activeSuggestionIndex: null }); case AUTOCOMPLETE_SUGGESTIONS_RESULTS: // Remove suggestion from pending requests let removePendingSuggestion = [...state.pendingRequests]; if (removePendingSuggestion.indexOf(SUGGESTIONS_JSON_KEY) !== -1) { removePendingSuggestion.splice(removePendingSuggestion.indexOf(SUGGESTIONS_JSON_KEY), 1); } return Object.assign({}, state, { keyword: action.keyword, pendingRequests: removePendingSuggestion, suggestions: action.results.suggestions, activeSuggestionIndex: null, visible: true }); case AUTOCOMPLETE_CUSTOM_FIELDS_RESULTS: // Remove suggestion from pending requests let removePendingCustomFields = [...state.pendingRequests]; if (removePendingCustomFields.indexOf(CUSTOM_FIELDS_JSON_KEY) !== -1) { removePendingCustomFields.splice(removePendingCustomFields.indexOf(CUSTOM_FIELDS_JSON_KEY), 1); } return Object.assign({}, state, { pendingRequests: removePendingCustomFields, customFields: action.results.autocomplete, activeSuggestionIndex: null, visible: true }); case AUTOCOMPLETE_SEARCH_CLEAR: return Object.assign({}, state, { keyword: '', pendingRequests: [], searchResults: {}, searchResultsStats: {} }); case AUTOCOMPLETE_SEARCH_RESULTS: const nextSearchResults = Object.assign({}, state.searchResults); nextSearchResults[action.jsonKey] = action.results.hits; const nextSearchResultsStats = Object.assign({}, state.searchResultsStats); // Append results in infinite scroll if (action.appendResults === true && state.searchResults[action.jsonKey]) { nextSearchResults[action.jsonKey] = [...state.searchResults[action.jsonKey], ...action.results.hits]; } // Not infinite scroll. Save stats (number of hits, processing time) for possible analytics usage else { if (!nextSearchResultsStats[action.jsonKey]) { nextSearchResultsStats[action.jsonKey] = {}; } nextSearchResultsStats[action.jsonKey].total_hits = action.results.total_hits; nextSearchResultsStats[action.jsonKey].processing_time_ms = action.results.processing_time_ms; } // Remove this search from pending requests let removePendingSearch = [...state.pendingRequests]; if (removePendingSearch.indexOf(action.jsonKey) !== -1) { removePendingSearch.splice(removePendingSearch.indexOf(action.jsonKey), 1); } return Object.assign({}, state, { keyword: action.keyword, pendingRequests: removePendingSearch, searchResults: nextSearchResults, searchResultsStats: nextSearchResultsStats, visible: true, appendResults: action.appendResults === true }); case AUTOCOMPLETE_HIDE: return Object.assign({}, state, { visible: false, activeSuggestionIndex: null }); case AUTOCOMPLETE_HIDE_AND_DROP_RENDERING: return Object.assign({}, state, { dropRendering: true, visible: false, activeSuggestionIndex: null }); case AUTOCOMPLETE_SHOW: return Object.assign({}, state, { visible: true }); case HIDE_AUTOMATICALLY: return Object.assign({}, state, { hideAutomatically: action.hideAutomatically }); case SET_ACTIVE_SUGGESTION: return Object.assign({}, state, { activeSuggestionIndex: action.index, setSuggestionToSearchField: action.setSuggestionToSearchField }); case KEYBOARD_EVENT: let nextActiveSuggestion = state.activeSuggestionIndex; let setSuggestionToSearchField = true; if (state.suggestions.length && state.customFields.length) { nextActiveSuggestion = null; setSuggestionToSearchField = false; } else { const source = state.suggestions.length ? 'suggestions' : 'customFields'; if (action.direction === ARROW_DOWN) { if (nextActiveSuggestion === null && state[source].length > 0) { nextActiveSuggestion = 0; } else if (nextActiveSuggestion === state[source].length-1) { nextActiveSuggestion = null; } else { nextActiveSuggestion = nextActiveSuggestion + 1; } } else if (action.direction === ARROW_UP) { if (nextActiveSuggestion === null && state[source].length > 0) { nextActiveSuggestion = state[source].length-1; } else if (nextActiveSuggestion === 0) { nextActiveSuggestion = null; } else { nextActiveSuggestion = nextActiveSuggestion - 1; } } } return Object.assign({}, state, { visible: true, activeSuggestionIndex: nextActiveSuggestion, setSuggestionToSearchField: true }); default: return state; } }