parent
f33e9f2bbc
commit
76613316fa
@ -0,0 +1,35 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import filterCollection from 'Utilities/Array/filterCollection';
|
||||||
|
import sortCollection from 'Utilities/Array/sortCollection';
|
||||||
|
import createCustomFiltersSelector from './createCustomFiltersSelector';
|
||||||
|
|
||||||
|
function createBooksClientSideCollectionSelector(uiSection) {
|
||||||
|
return createSelector(
|
||||||
|
(state) => _.get(state, 'books'),
|
||||||
|
(state) => _.get(state, 'authors'),
|
||||||
|
(state) => _.get(state, uiSection),
|
||||||
|
createCustomFiltersSelector('books', uiSection),
|
||||||
|
(bookState, authorState, uiSectionState = {}, customFilters) => {
|
||||||
|
const state = Object.assign({}, bookState, uiSectionState, { customFilters });
|
||||||
|
|
||||||
|
const books = state.items;
|
||||||
|
for (const book of books) {
|
||||||
|
book.author = authorState.items[authorState.itemMap[book.authorId]];
|
||||||
|
}
|
||||||
|
|
||||||
|
const filtered = filterCollection(books, state);
|
||||||
|
const sorted = sortCollection(filtered, state);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...bookState,
|
||||||
|
...uiSectionState,
|
||||||
|
customFilters,
|
||||||
|
items: sorted,
|
||||||
|
totalItems: state.items.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createBooksClientSideCollectionSelector;
|
@ -0,0 +1,14 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
function createCustomFiltersSelector(type, alternateType) {
|
||||||
|
return createSelector(
|
||||||
|
(state) => state.customFilters.items,
|
||||||
|
(customFilters) => {
|
||||||
|
return customFilters.filter((customFilter) => {
|
||||||
|
return customFilter.type === type || customFilter.type === alternateType;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createCustomFiltersSelector;
|
@ -0,0 +1,72 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { filterTypePredicates, filterTypes } from 'Helpers/Props';
|
||||||
|
import findSelectedFilters from 'Utilities/Filter/findSelectedFilters';
|
||||||
|
|
||||||
|
function filterCollection(items, state) {
|
||||||
|
const {
|
||||||
|
selectedFilterKey,
|
||||||
|
filters,
|
||||||
|
customFilters,
|
||||||
|
filterPredicates
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
if (!selectedFilterKey) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedFilters = findSelectedFilters(selectedFilterKey, filters, customFilters);
|
||||||
|
|
||||||
|
return _.filter(items, (item) => {
|
||||||
|
let i = 0;
|
||||||
|
let accepted = true;
|
||||||
|
|
||||||
|
while (accepted && i < selectedFilters.length) {
|
||||||
|
const {
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
type = filterTypes.EQUAL
|
||||||
|
} = selectedFilters[i];
|
||||||
|
|
||||||
|
if (filterPredicates && filterPredicates.hasOwnProperty(key)) {
|
||||||
|
const predicate = filterPredicates[key];
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (
|
||||||
|
type === filterTypes.NOT_CONTAINS ||
|
||||||
|
type === filterTypes.NOT_EQUAL
|
||||||
|
) {
|
||||||
|
accepted = value.every((v) => predicate(item, v, type));
|
||||||
|
} else {
|
||||||
|
accepted = value.some((v) => predicate(item, v, type));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
accepted = predicate(item, value, type);
|
||||||
|
}
|
||||||
|
} else if (item.hasOwnProperty(key)) {
|
||||||
|
const predicate = filterTypePredicates[type];
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (
|
||||||
|
type === filterTypes.NOT_CONTAINS ||
|
||||||
|
type === filterTypes.NOT_EQUAL
|
||||||
|
) {
|
||||||
|
accepted = value.every((v) => predicate(item[key], v));
|
||||||
|
} else {
|
||||||
|
accepted = value.some((v) => predicate(item[key], v));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
accepted = predicate(item[key], value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Default to false if the filter can't be tested
|
||||||
|
accepted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accepted;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default filterCollection;
|
@ -0,0 +1,42 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { sortDirections } from 'Helpers/Props';
|
||||||
|
|
||||||
|
function getSortClause(sortKey, sortDirection, sortPredicates) {
|
||||||
|
if (sortPredicates && sortPredicates.hasOwnProperty(sortKey)) {
|
||||||
|
return function(item) {
|
||||||
|
return sortPredicates[sortKey](item, sortDirection);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(item) {
|
||||||
|
return item[sortKey];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortCollection(items, state) {
|
||||||
|
const {
|
||||||
|
sortKey,
|
||||||
|
sortDirection,
|
||||||
|
sortPredicates,
|
||||||
|
secondarySortKey,
|
||||||
|
secondarySortDirection
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
const clauses = [];
|
||||||
|
const orders = [];
|
||||||
|
|
||||||
|
clauses.push(getSortClause(sortKey, sortDirection, sortPredicates));
|
||||||
|
orders.push(sortDirection === sortDirections.ASCENDING ? 'asc' : 'desc');
|
||||||
|
|
||||||
|
if (secondarySortKey &&
|
||||||
|
secondarySortDirection &&
|
||||||
|
(sortKey !== secondarySortKey ||
|
||||||
|
sortDirection !== secondarySortDirection)) {
|
||||||
|
clauses.push(getSortClause(secondarySortKey, secondarySortDirection, sortPredicates));
|
||||||
|
orders.push(secondarySortDirection === sortDirections.ASCENDING ? 'asc' : 'desc');
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.orderBy(items, clauses, orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default sortCollection;
|
Loading…
Reference in new issue