UNPKG

decap-cms-core

Version:

Decap CMS core application, see decap-cms package for the main distribution.

149 lines (142 loc) 4.71 kB
import isEqual from 'lodash/isEqual'; import { currentBackend } from '../backend'; import { getIntegrationProvider } from '../integrations'; import { selectIntegration } from '../reducers'; /* * Constant Declarations */ export const SEARCH_ENTRIES_REQUEST = 'SEARCH_ENTRIES_REQUEST'; export const SEARCH_ENTRIES_SUCCESS = 'SEARCH_ENTRIES_SUCCESS'; export const SEARCH_ENTRIES_FAILURE = 'SEARCH_ENTRIES_FAILURE'; export const QUERY_REQUEST = 'QUERY_REQUEST'; export const QUERY_SUCCESS = 'QUERY_SUCCESS'; export const QUERY_FAILURE = 'QUERY_FAILURE'; export const SEARCH_CLEAR = 'SEARCH_CLEAR'; export const CLEAR_REQUESTS = 'CLEAR_REQUESTS'; /* * Simple Action Creators (Internal) * We still need to export them for tests */ export function searchingEntries(searchTerm, searchCollections, page) { return { type: SEARCH_ENTRIES_REQUEST, payload: { searchTerm, searchCollections, page } }; } export function searchSuccess(entries, page) { return { type: SEARCH_ENTRIES_SUCCESS, payload: { entries, page } }; } export function searchFailure(error) { return { type: SEARCH_ENTRIES_FAILURE, payload: { error } }; } export function querying(searchTerm, request) { return { type: QUERY_REQUEST, payload: { searchTerm, request } }; } export function querySuccess(namespace, hits) { return { type: QUERY_SUCCESS, payload: { namespace, hits } }; } export function queryFailure(error) { return { type: QUERY_FAILURE, payload: { error } }; } /* * Exported simple Action Creators */ export function clearSearch() { return { type: SEARCH_CLEAR }; } export function clearRequests() { return { type: CLEAR_REQUESTS }; } /* * Exported Thunk Action Creators */ // SearchEntries will search for complete entries in all collections. export function searchEntries(searchTerm, searchCollections, page = 0) { return async (dispatch, getState) => { const state = getState(); const { search } = state; const backend = currentBackend(state.config); const allCollections = searchCollections || state.collections.keySeq().toArray(); const collections = allCollections.filter(collection => selectIntegration(state, collection, 'search')); const integration = selectIntegration(state, collections[0], 'search'); // avoid duplicate searches if (search.isFetching && search.term === searchTerm && isEqual(allCollections, search.collections) && ( // if an integration doesn't exist, 'page' is not used search.page === page || !integration)) { return; } dispatch(searchingEntries(searchTerm, allCollections, page)); const searchPromise = integration ? getIntegrationProvider(state.integrations, backend.getToken, integration).search(collections, searchTerm, page) : backend.search(state.collections.filter((_, key) => allCollections.indexOf(key) !== -1).valueSeq().toArray(), searchTerm); try { const response = await searchPromise; return dispatch(searchSuccess(response.entries, response.pagination)); } catch (error) { return dispatch(searchFailure(error)); } }; } // Instead of searching for complete entries, query will search for specific fields // in specific collections and return raw data (no entries). export function query(namespace, collectionName, searchFields, searchTerm, file, limit) { return async (dispatch, getState) => { const state = getState(); const backend = currentBackend(state.config); const integration = selectIntegration(state, collectionName, 'search'); const collection = state.collections.find(collection => collection.get('name') === collectionName); dispatch(clearRequests()); const queryIdentifier = `${collectionName}-${searchFields.join()}-${searchTerm}-${file}-${limit}`; const queuedQueryPromise = state.search.requests.find(({ id }) => id == queryIdentifier); const queryPromise = queuedQueryPromise ? queuedQueryPromise.queryResponse : integration ? getIntegrationProvider(state.integrations, backend.getToken, integration).searchBy(searchFields.map(f => `data.${f}`), collectionName, searchTerm) : backend.query(collection, searchFields, searchTerm, file, limit); dispatch(querying(searchTerm, queuedQueryPromise ? undefined : { id: queryIdentifier, expires: new Date(new Date().getTime() + 10 * 1000), queryResponse: queryPromise })); try { const response = await queryPromise; return dispatch(querySuccess(namespace, response.hits)); } catch (error) { return dispatch(queryFailure(error)); } }; }