2020-04-01 06:13:27 +03:00
|
|
|
import { ThunkDispatch } from 'redux-thunk';
|
|
|
|
import { AnyAction } from 'redux';
|
|
|
|
import { State } from '../types/redux';
|
|
|
|
import { currentBackend } from '../backend';
|
|
|
|
import { getIntegrationProvider } from '../integrations';
|
|
|
|
import { selectIntegration } from '../reducers';
|
|
|
|
import { EntryValue } from '../valueObjects/Entry';
|
2020-05-18 09:52:06 +02:00
|
|
|
import { List } from 'immutable';
|
2016-12-07 15:44:07 -02:00
|
|
|
|
|
|
|
/*
|
2019-09-24 22:16:09 +02:00
|
|
|
* Constant Declarations
|
2016-12-07 15:44:07 -02:00
|
|
|
*/
|
|
|
|
export const SEARCH_ENTRIES_REQUEST = 'SEARCH_ENTRIES_REQUEST';
|
|
|
|
export const SEARCH_ENTRIES_SUCCESS = 'SEARCH_ENTRIES_SUCCESS';
|
|
|
|
export const SEARCH_ENTRIES_FAILURE = 'SEARCH_ENTRIES_FAILURE';
|
|
|
|
|
2016-12-29 17:18:24 -02:00
|
|
|
export const QUERY_REQUEST = 'INIT_QUERY';
|
|
|
|
export const QUERY_SUCCESS = 'QUERY_OK';
|
|
|
|
export const QUERY_FAILURE = 'QUERY_ERROR';
|
2016-12-07 15:44:07 -02:00
|
|
|
|
|
|
|
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple Action Creators (Internal)
|
|
|
|
* We still need to export them for tests
|
|
|
|
*/
|
2020-05-18 09:52:06 +02:00
|
|
|
export function searchingEntries(searchTerm: string, searchCollections: string[], page: number) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
|
|
|
type: SEARCH_ENTRIES_REQUEST,
|
2020-05-18 09:52:06 +02:00
|
|
|
payload: { searchTerm, searchCollections, page },
|
2016-12-07 15:44:07 -02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-05-18 09:52:06 +02:00
|
|
|
export function searchSuccess(
|
|
|
|
searchTerm: string,
|
|
|
|
searchCollections: string[],
|
|
|
|
entries: EntryValue[],
|
|
|
|
page: number,
|
|
|
|
) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
|
|
|
type: SEARCH_ENTRIES_SUCCESS,
|
|
|
|
payload: {
|
|
|
|
searchTerm,
|
2020-05-18 09:52:06 +02:00
|
|
|
searchCollections,
|
2016-12-07 15:44:07 -02:00
|
|
|
entries,
|
|
|
|
page,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-01 06:13:27 +03:00
|
|
|
export function searchFailure(searchTerm: string, error: Error) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
|
|
|
type: SEARCH_ENTRIES_FAILURE,
|
|
|
|
payload: {
|
|
|
|
searchTerm,
|
|
|
|
error,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-01 06:13:27 +03:00
|
|
|
export function querying(
|
|
|
|
namespace: string,
|
|
|
|
collection: string,
|
|
|
|
searchFields: string[],
|
|
|
|
searchTerm: string,
|
|
|
|
) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
|
|
|
type: QUERY_REQUEST,
|
|
|
|
payload: {
|
2016-12-29 17:18:24 -02:00
|
|
|
namespace,
|
2016-12-07 15:44:07 -02:00
|
|
|
collection,
|
|
|
|
searchFields,
|
|
|
|
searchTerm,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-01 06:13:27 +03:00
|
|
|
type Response = {
|
|
|
|
entries: EntryValue[];
|
|
|
|
pagination: number;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function querySuccess(
|
|
|
|
namespace: string,
|
|
|
|
collection: string,
|
|
|
|
searchFields: string[],
|
|
|
|
searchTerm: string,
|
|
|
|
response: Response,
|
|
|
|
) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
|
|
|
type: QUERY_SUCCESS,
|
|
|
|
payload: {
|
2016-12-29 17:18:24 -02:00
|
|
|
namespace,
|
2016-12-07 15:44:07 -02:00
|
|
|
collection,
|
|
|
|
searchFields,
|
|
|
|
searchTerm,
|
|
|
|
response,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-04-01 06:13:27 +03:00
|
|
|
export function queryFailure(
|
|
|
|
namespace: string,
|
|
|
|
collection: string,
|
|
|
|
searchFields: string[],
|
|
|
|
searchTerm: string,
|
|
|
|
error: Error,
|
|
|
|
) {
|
2016-12-07 15:44:07 -02:00
|
|
|
return {
|
2020-02-13 10:48:02 +01:00
|
|
|
type: QUERY_FAILURE,
|
2016-12-07 15:44:07 -02:00
|
|
|
payload: {
|
2016-12-29 17:18:24 -02:00
|
|
|
namespace,
|
2016-12-07 15:44:07 -02:00
|
|
|
collection,
|
|
|
|
searchFields,
|
|
|
|
searchTerm,
|
|
|
|
error,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Exported simple Action Creators
|
|
|
|
*/
|
|
|
|
|
|
|
|
export function clearSearch() {
|
|
|
|
return { type: SEARCH_CLEAR };
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Exported Thunk Action Creators
|
|
|
|
*/
|
|
|
|
|
|
|
|
// SearchEntries will search for complete entries in all collections.
|
2020-05-18 09:52:06 +02:00
|
|
|
export function searchEntries(
|
|
|
|
searchTerm: string,
|
|
|
|
searchCollections: string[] | null = null,
|
|
|
|
page = 0,
|
|
|
|
) {
|
2020-04-01 06:13:27 +03:00
|
|
|
return (dispatch: ThunkDispatch<State, {}, AnyAction>, getState: () => State) => {
|
2016-12-07 15:44:07 -02:00
|
|
|
const state = getState();
|
2020-04-01 06:13:27 +03:00
|
|
|
const { search } = state;
|
2018-06-11 19:03:43 -07:00
|
|
|
const backend = currentBackend(state.config);
|
2020-05-18 09:52:06 +02:00
|
|
|
const allCollections = searchCollections || state.collections.keySeq().toArray();
|
2018-08-07 14:46:54 -06:00
|
|
|
const collections = allCollections.filter(collection =>
|
2020-04-01 06:13:27 +03:00
|
|
|
selectIntegration(state, collection as string, 'search'),
|
2018-08-07 14:46:54 -06:00
|
|
|
);
|
2020-04-01 06:13:27 +03:00
|
|
|
const integration = selectIntegration(state, collections[0] as string, 'search');
|
|
|
|
|
|
|
|
// avoid duplicate searches
|
|
|
|
if (
|
|
|
|
search.get('isFetching') === true &&
|
|
|
|
search.get('term') === searchTerm &&
|
2020-05-18 09:52:06 +02:00
|
|
|
search.get('collections') !== null &&
|
|
|
|
List(allCollections).equals(search.get('collections') as List<string>) &&
|
2020-04-01 06:13:27 +03:00
|
|
|
// if an integration doesn't exist, 'page' is not used
|
|
|
|
(search.get('page') === page || !integration)
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2020-05-18 09:52:06 +02:00
|
|
|
dispatch(searchingEntries(searchTerm, allCollections as string[], page));
|
2018-06-11 19:03:43 -07:00
|
|
|
|
|
|
|
const searchPromise = integration
|
2018-08-07 14:46:54 -06:00
|
|
|
? getIntegrationProvider(state.integrations, backend.getToken, integration).search(
|
|
|
|
collections,
|
|
|
|
searchTerm,
|
|
|
|
page,
|
|
|
|
)
|
2020-05-18 09:52:06 +02:00
|
|
|
: backend.search(
|
|
|
|
state.collections
|
|
|
|
.filter((_, key: string) => allCollections.indexOf(key) !== -1)
|
|
|
|
.valueSeq()
|
|
|
|
.toArray(),
|
|
|
|
searchTerm,
|
|
|
|
);
|
2018-06-11 19:03:43 -07:00
|
|
|
|
|
|
|
return searchPromise.then(
|
2020-04-01 06:13:27 +03:00
|
|
|
(response: Response) =>
|
2020-05-18 09:52:06 +02:00
|
|
|
dispatch(
|
|
|
|
searchSuccess(
|
|
|
|
searchTerm,
|
|
|
|
allCollections as string[],
|
|
|
|
response.entries,
|
|
|
|
response.pagination,
|
|
|
|
),
|
|
|
|
),
|
2020-04-01 06:13:27 +03:00
|
|
|
(error: Error) => dispatch(searchFailure(searchTerm, error)),
|
2018-06-11 19:03:43 -07:00
|
|
|
);
|
2016-12-07 15:44:07 -02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Instead of searching for complete entries, query will search for specific fields
|
|
|
|
// in specific collections and return raw data (no entries).
|
2020-04-01 06:13:27 +03:00
|
|
|
export function query(
|
|
|
|
namespace: string,
|
|
|
|
collectionName: string,
|
|
|
|
searchFields: string[],
|
|
|
|
searchTerm: string,
|
|
|
|
) {
|
|
|
|
return (dispatch: ThunkDispatch<State, {}, AnyAction>, getState: () => State) => {
|
2018-06-11 19:03:43 -07:00
|
|
|
dispatch(querying(namespace, collectionName, searchFields, searchTerm));
|
|
|
|
|
2016-12-07 15:44:07 -02:00
|
|
|
const state = getState();
|
2018-06-11 19:03:43 -07:00
|
|
|
const backend = currentBackend(state.config);
|
|
|
|
const integration = selectIntegration(state, collectionName, 'search');
|
2018-08-07 14:46:54 -06:00
|
|
|
const collection = state.collections.find(
|
|
|
|
collection => collection.get('name') === collectionName,
|
|
|
|
);
|
2018-06-11 19:03:43 -07:00
|
|
|
|
|
|
|
const queryPromise = integration
|
2018-08-07 14:46:54 -06:00
|
|
|
? getIntegrationProvider(state.integrations, backend.getToken, integration).searchBy(
|
|
|
|
searchFields.map(f => `data.${f}`),
|
|
|
|
collectionName,
|
|
|
|
searchTerm,
|
|
|
|
)
|
2018-06-11 19:03:43 -07:00
|
|
|
: backend.query(collection, searchFields, searchTerm);
|
|
|
|
|
|
|
|
return queryPromise.then(
|
2020-04-01 06:13:27 +03:00
|
|
|
(response: Response) =>
|
2018-08-07 14:46:54 -06:00
|
|
|
dispatch(querySuccess(namespace, collectionName, searchFields, searchTerm, response)),
|
2020-04-01 06:13:27 +03:00
|
|
|
(error: Error) =>
|
|
|
|
dispatch(queryFailure(namespace, collectionName, searchFields, searchTerm, error)),
|
2018-06-11 19:03:43 -07:00
|
|
|
);
|
2016-12-07 15:44:07 -02:00
|
|
|
};
|
|
|
|
}
|