-
Notifications
You must be signed in to change notification settings - Fork 43
/
reducer.ts
124 lines (111 loc) · 3.56 KB
/
reducer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { createSelector } from "reselect";
import shallowEqual from "shallow-equal/objects";
import { BooksModuleType } from "modules/books/reducers/reducer";
import { HASH_CHANGED, SET_GRID_VIEW, SET_BASIC_LIST_VIEW, GRID_VIEW, BASIC_LIST_VIEW } from "./actionNames";
const initialState = {
view: "",
hashFilters: {} as typeof defaultSearchValuesHash
};
export type BookSearchType = typeof initialState;
export function bookSearchReducer(state = initialState, action): BookSearchType {
switch (action.type) {
case SET_BASIC_LIST_VIEW:
return { ...state, view: BASIC_LIST_VIEW };
case SET_GRID_VIEW:
return { ...state, view: GRID_VIEW };
case HASH_CHANGED:
let { filters } = action;
if (!shallowEqual(filters, state.hashFilters)) {
return { ...state, hashFilters: filters };
}
return { ...state };
}
return state;
}
export type TagOrSubject = {
_id: string;
name: string;
};
export type LookupHashType = {
[str: string]: TagOrSubject;
};
const defaultSearchValuesHash = {
search: "",
subjects: "",
tags: "",
searchChildSubjects: "",
author: "",
publisher: "",
pages: "",
pagesOperator: "",
page: 1,
pageSize: 50,
isRead: "",
noSubjects: "",
sort: "_id",
sortDirection: "desc",
userId: ""
};
export const selectSelectedSubjects = createSelector(
(state: BooksModuleType) => state.booksModule.bookSearch,
(state: BooksModuleType) => state.app.subjectHash,
(filters, hash) => projectSelectedItems(filters.hashFilters.subjects, hash)
);
export const selectSelectedTags = createSelector(
(state: BooksModuleType) => state.booksModule.bookSearch,
(state: BooksModuleType) => state.app.tagHash,
(filters, hash) => {
return projectSelectedItems(filters.hashFilters.tags, hash);
}
);
function projectSelectedItems(ids: string = "", hash): TagOrSubject[] {
return ids
.split("-")
.map(_id => (_id ? hash[_id] : null))
.filter(res => res);
}
export const selectCurrentSearch = createSelector(
(state: BooksModuleType) => state.booksModule.bookSearch,
selectSelectedSubjects,
selectSelectedTags,
(bookSearch, subjects, tags) => {
let filters = bookSearch.hashFilters;
let tagsHashValue = bookSearch.hashFilters.tags;
let subjectsHashValue = bookSearch.hashFilters.subjects;
return Object.assign({}, defaultSearchValuesHash, filters, {
selectedSubjects: subjects,
selectedTags: tags,
tagIds: tagsHashValue ? tagsHashValue.split("-") : [],
subjectIds: subjectsHashValue ? subjectsHashValue.split("-") : []
});
}
);
export const selectBookSearchState = createSelector(
selectCurrentSearch,
(state: BooksModuleType) => state.booksModule.bookSearch,
(currentSearch, bookSearch) => {
let filtersHash = { ...bookSearch.hashFilters };
delete filtersHash.sort;
delete filtersHash.sortDirection;
delete filtersHash.userId;
return {
...currentSearch,
anyActiveFilters: !!Object.keys(filtersHash).filter(k => k != "page").length,
activeFilterCount: Object.keys(filtersHash).filter(k => k != "page").length,
bindableSortValue: `${currentSearch.sort}|${currentSearch.sortDirection}`
};
}
);
export const selectBookSearchUiView = createSelector(
(state: BooksModuleType) => state.app,
(state: BooksModuleType) => state.booksModule.bookSearch,
(app, bookSearch) => {
let view = bookSearch.view,
isGridView = view == GRID_VIEW || (!view && app.showingDesktop),
isBasicList = view == BASIC_LIST_VIEW || (!view && app.showingMobile);
return {
isGridView,
isBasicList
};
}
);