Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search refactor [WIP] #143

Merged
merged 40 commits into from
Jul 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c720c7f
[store] Add a identifier notion to the search store.
pierr Jun 26, 2015
6333ff0
[identifier] Add an identifier check.
pierr Jun 26, 2015
8064c45
[search] Remove store definition
pierr Jun 26, 2015
58a3dbe
[advanced-search] Add the store for the page.
pierr Jun 26, 2015
f22b46a
[quick-search] Add the store for the page quick search.
pierr Jun 26, 2015
17b79e5
[store] Add the index.
pierr Jun 26, 2015
e67456c
[definition] Remove search definition from entity definition.
pierr Jun 26, 2015
75dcece
[built-in-store] Update the built-in storE.
pierr Jun 26, 2015
fac1470
[search] fix built in store
pierr Jun 26, 2015
5e2be4c
[query store] Remove it
pierr Jun 26, 2015
ddead88
[action-builder] Add the action builder without implementation.
pierr Jun 26, 2015
a7e3323
[search] Update index
pierr Jun 26, 2015
b89b32a
[action-builder] Implement update query and scopt.
pierr Jun 26, 2015
0c6d686
[search] Add a search action and update builder to take a config.
pierr Jun 26, 2015
2fdaf4a
[search-action] Add questions?
pierr Jun 26, 2015
ec7ea3f
[search-action] Add the documentation on what we espect.
pierr Jun 26, 2015
e708820
[move] search action into a directory
pierr Jun 26, 2015
b663e89
[search-action] Fix ducplicate
pierr Jun 26, 2015
6f0fc3a
[builder]
pierr Jun 26, 2015
8eba29b
[parser]
pierr Jun 26, 2015
5455821
[search action] Fix error between options and config
Bernardstanislas Jun 28, 2015
8f9e8a9
[search-action] Add a comment
Bernardstanislas Jun 28, 2015
3a0838b
[search] Add builder and parser function.
pierr Jun 29, 2015
cf86c3a
[action-builder] Add update properties.
pierr Jun 29, 2015
67abe7c
[search-store] Add a search store to unify the value access.
pierr Jun 29, 2015
8d35fed
[search builder] Simplify builder.
pierr Jun 29, 2015
dead40f
[search parser] Simplify parser.
pierr Jun 29, 2015
8bd6f8b
[search] Simplify action builder$
pierr Jun 29, 2015
d8fad6e
[] Update search action
pierr Jun 29, 2015
213a8a6
[search store] fix require.
pierr Jun 29, 2015
33e517b
[search action] Finish the parse response
pierr Jun 29, 2015
16f88ce
[search] doc and scoped and fix wrong getSearchOptions
pierr Jun 29, 2015
e9ba5a0
[search-action] Add default group key
Bernardstanislas Jun 30, 2015
c45dc6e
[search] Add log function.
Bernardstanislas Jun 30, 2015
099fee8
[search-store] Fix identifier.
Bernardstanislas Jun 30, 2015
1d42ddb
[search-parser] Add missing results
Bernardstanislas Jun 30, 2015
42682ba
Style
Bernardstanislas Jun 30, 2015
0aad5bc
[search-store] Remove getter
Bernardstanislas Jun 30, 2015
702c888
[quick-search-store] Add missing property, the facets (used for group…
Bernardstanislas Jul 1, 2015
17d21e8
Merge branch 'master' into search-refactor
Bernardstanislas Jul 1, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions definition/entity/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ var checkIsObject = require('../../util/object/check');
*/
const SEPARATOR = ".";

/**
* Definition of the search informations.
* @type {object}
*/
var searchDefinition = require('../../store/search/definition');
/**
* Container for the application entities.
* @type {object}
Expand Down Expand Up @@ -68,7 +63,6 @@ function getFieldConfiguration(fieldPath, customFieldConf){
return _getNode(fieldPath, customFieldConf).toJS();
}

setEntityConfiguration(searchDefinition);

module.exports = {
getEntityConfiguration: getEntityConfiguration,
Expand Down
54 changes: 54 additions & 0 deletions search/action-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
let dispatcher = require('../dispatcher');
let searchAction = require('./search-action');
const NB_SEARCH_ELEMENT = 50;

/**
* Builded search action.
* @param {object} options - The options used to build the service, it should have the following structure:
* ```javascript
* {
* identifier: string: should be 'ADVANCED_SEARCH' or 'QUICK_SEARCH'
* service:{
* scoped: "function which launch the scope search"
* unScoped: "function whoch launch the unscoped search"
* }
* getSearchOptions a function which get the associated search store value
* nbSearchElement: number of elements to request on each search.
* }
* ```
* @return {function} - The builded search action.
*/
module.exports = function(config){
config = config || {};
if(!config.identifier){
console.warn('Your action should have an identifier');
}
if(!config.service){
console.warn('Your action should have a service');
}
if(!config.getSearchOptions){
console.warn('Your action should have a search options getter.');
}
if(!config.nbSearchElement){
config.nbSearchElement = NB_SEARCH_ELEMENT;
}
return {
/**
* Build the search for the identifier scope.
* @return {function} The search function for the given identifier.
*/
search: searchAction(config),
/**
* Update the query for the identifier scope.
* @param {string} value - The query value
* @return {function} The update query function for the given identifier.
*/
updateProperties(value){
return dispatcher.handleViewAction({
data: value,
type: 'update',
identifier: config.identifier
});
}
};
};
10 changes: 5 additions & 5 deletions search/built-in-store.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var SearchStore = require('../store/search');
var QueryStore = require('../store/query');
let AdvancedSearchStore = require('../store/search/advanced-search');
let QuickSearchStore = require('../store/search/quick-search');

module.exports = {
searchStore: new SearchStore(),
queryStore: new QueryStore()
};
quickSearchStore: new QuickSearchStore(),
advancedSearchStore: new AdvancedSearchStore()
};
21 changes: 10 additions & 11 deletions search/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
let dispatcher = require('../dispatcher');
module.exports = {
builtInStore: require('./built-in-store'),
/*
* Dispatch the change of the query value, with the callerId information.
*/
changeQuery(queryValue, callerId){
dispatcher.handleViewAction({data: {query: queryValue}, type: 'update', callerId: callerId});
},
/*
* Dispatch the change of the scope value, with the callerId information.
*/
changeScope(scopeValue, callerId){
dispatcher.handleViewAction({data: {scope: scopeValue}, type: 'update', callerId: callerId});
/**
* Action builder
*/
actionBuilder: require('./action-builder'),
log(){
let builtInStore = require('./built-in-store');
console.info('---------------------------');
console.info('QuickSearch', builtInStore.quickSearchStore.value);
console.info('AdvancedSearch', builtInStore.advancedSearchStore.value);
console.info('---------------------------');
}
};
50 changes: 50 additions & 0 deletions search/search-action/builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
let keys = require('lodash/object/keys');
let _buildFacets = (facets) => {
return keys(facets).map((selectedFacetKey) => {
let selectedFacet = facets[selectedFacetKey];
return {
key: selectedFacetKey,
value: selectedFacet.key
};
});
};

/**
* Build sort infotmation.
* @param {object} sortConf - The sort configuration.
* @return {object} - The builded sort configuration.
*/
let _buildOrderAndSort = (sortConf) => {
return {
sortFieldName: sortConf.sortBy,
sortDesc: !sortConf.sortAsc
}
};



let _buildPagination = (opts) => {
let resultsKeys = keys(opts.results);
if(opts.isScroll && resultsKeys.length === 1){
let key = resultsKeys[0];
let previousRes = opts.results[key];
if(previousRes.length < opts.totalCount){
return {
top: opts.nbSearchElement,
skip: previousRes.length
};
//Else should not be called.
console.warn('This should not happen.')
};
} else {
return {
skip: 0,
top: opts.nbSearchElement || 0
}
}
};
module.exports = {
pagination: _buildPagination,
orderAndSort: _buildOrderAndSort,
facets: _buildFacets
};
73 changes: 73 additions & 0 deletions search/search-action/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//Dependencies.
let assign = require('object-assign');
let _builder = require('./builder');
let _parser = require('./parser');
const ALL = 'ALL';
const STAR = '*';


/**
* Search action generated from the config.
* @param {object} config - Action configuration.
* @return {function} - The generated action from the congig.
*/
module.exports = function(config){
/**
* Dispatch the results on the search store
* @param {object} data - The data to dispatch.
*/
let _dispatchResult = (data) => {
Focus.dispatcher.handleServerAction({
data,
type: 'update',
identifier: config.identifier
});
};

/**
* Build search action.
* @param {Boolean} isScroll - Is the action result from a scrolling.
*/
return function searchAction(isScroll){
//Read search options from the accessor define in the config.
let {
scope, query, selectedFacets,
groupingKey, sortBy, sortAsc,
results, totalCount
} = config.getSearchOptions();

//Number of element to search on each search.
let nbSearchElement = config.nbSearchElement;
//Process the query if empty.
if(!query || query === ''){
query = STAR;
}
//Build URL data.
let urlData = assign(
_builder.pagination({results, totalCount, isScroll, nbSearchElement}),
_builder.orderAndSort({sortBy, sortAsc})
);
//Build body data.
let postData = {
criteria: {scope, query},
facets: selectedFacets ? _builder.facets(selectedFacets) : [],
group: groupingKey || ''
};
//Different call depending on the scope.
if(scope === ALL){
//Call the search action.
config.service.unscoped({urlData: urlData, data: postData})
.then(_parser.unscopedResponse)
.then(_dispatchResult);
}else{
//The component which call the serice should be know if it has all the data.
config.service.scoped({urlData: urlData, data: postData})
.then((response)=>{
return _parser.scopedResponse(
response,
{isScroll, scope, results}
);
}).then(_dispatchResult);
}
};
};
44 changes: 44 additions & 0 deletions search/search-action/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//Requirements

let keys = require('lodash/object/keys');

let _parseFacets = (facets) => {
return keys(facets).reduce((formattedFacets, serverFacetKey) => {
let serverFacetData = facets[serverFacetKey];
formattedFacets[serverFacetKey] = keys(serverFacetData).reduce((facetData, serverFacetItemKey) => {
let serverFacetItemValue = serverFacetData[serverFacetItemKey];
facetData[serverFacetItemKey] = {
label: serverFacetItemKey,
count: serverFacetItemValue
};
return facetData;
}, {});
return formattedFacets;
}, {});
};
let _parseUnscopedResponse = (data) => {
return ({
results: data.groups,
facets: _parseFacets(data.facets),
totalCount: data.totalCount
});
};

let _parseScopedResponse = (data, context) => {
//Scroll can only happen when there is an ungroupSearch
if(context.isScroll){
let resultsKeys = keys(context.results);
let key = resultsKeys[0];
//Concat previous data with incoming data.
data.list = [...context.results[key], ...data.list];
}
return ({
results: data.groups || {[context.scope]: data.list},
facets: _parseFacets(data.facets),
totalCount: data.totalCount
});
};
module.exports = {
unscopedResponse: _parseUnscopedResponse,
scopedResponse: _parseScopedResponse
};
Loading