@zengenti/contensis-react-base 3.0.0-beta.8 → 3.0.0-beta.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +1 -1
  2. package/cjs/{App-e3200f18.js → App-5a34ea98.js} +228 -181
  3. package/cjs/App-5a34ea98.js.map +1 -0
  4. package/cjs/{RouteLoader-df3de0cb.js → RouteLoader-2675e1c9.js} +31 -23
  5. package/cjs/RouteLoader-2675e1c9.js.map +1 -0
  6. package/cjs/{ToJs-697ace9f.js → ToJs-a9a8522b.js} +39 -34
  7. package/cjs/ToJs-a9a8522b.js.map +1 -0
  8. package/cjs/{actions-a24bf46e.js → actions-8dc9e8de.js} +5 -4
  9. package/cjs/actions-8dc9e8de.js.map +1 -0
  10. package/cjs/client.js +22 -44
  11. package/cjs/client.js.map +1 -1
  12. package/cjs/contensis-react-base.js +3955 -135
  13. package/cjs/contensis-react-base.js.map +1 -1
  14. package/cjs/forms.js +547 -580
  15. package/cjs/forms.js.map +1 -1
  16. package/cjs/{fromJSLeaveImmer-c00d597f.js → fromJSLeaveImmer-e74c673c.js} +2 -16
  17. package/cjs/fromJSLeaveImmer-e74c673c.js.map +1 -0
  18. package/cjs/{login-bc55ee33.js → login-6b9de6a1.js} +92 -55
  19. package/cjs/login-6b9de6a1.js.map +1 -0
  20. package/cjs/{reducers-fde41d6b.js → reducers-3a4f8971.js} +26 -25
  21. package/cjs/reducers-3a4f8971.js.map +1 -0
  22. package/cjs/redux.js +6 -5
  23. package/cjs/redux.js.map +1 -1
  24. package/cjs/routing.js +5 -4
  25. package/cjs/routing.js.map +1 -1
  26. package/cjs/sagas-594b5ecd.js +2090 -0
  27. package/cjs/sagas-594b5ecd.js.map +1 -0
  28. package/cjs/search.js +296 -1915
  29. package/cjs/search.js.map +1 -1
  30. package/cjs/{selectors-0ec95076.js → selectors-656da4b7.js} +8 -3
  31. package/cjs/selectors-656da4b7.js.map +1 -0
  32. package/cjs/setCachingHeaders-ee619bdf.js +12 -0
  33. package/cjs/setCachingHeaders-ee619bdf.js.map +1 -0
  34. package/cjs/user.js +21 -12
  35. package/cjs/user.js.map +1 -1
  36. package/cjs/util.js +17 -17
  37. package/cjs/util.js.map +1 -1
  38. package/cjs/{version-4f0f5fa6.js → version-330551f5.js} +34 -22
  39. package/cjs/version-330551f5.js.map +1 -0
  40. package/cjs/{version-be0c7b7a.js → version-eba6d09b.js} +2 -2
  41. package/{esm/version-ad2ec52c.js.map → cjs/version-eba6d09b.js.map} +1 -1
  42. package/esm/{App-f9e7d03b.js → App-a973f962.js} +228 -182
  43. package/esm/App-a973f962.js.map +1 -0
  44. package/esm/{RouteLoader-027215f2.js → RouteLoader-f607a134.js} +31 -23
  45. package/esm/RouteLoader-f607a134.js.map +1 -0
  46. package/esm/{ToJs-46761960.js → ToJs-4e02a04d.js} +38 -32
  47. package/esm/ToJs-4e02a04d.js.map +1 -0
  48. package/esm/{actions-b949ef5c.js → actions-180948dd.js} +5 -4
  49. package/esm/actions-180948dd.js.map +1 -0
  50. package/esm/client.js +24 -27
  51. package/esm/client.js.map +1 -1
  52. package/esm/contensis-react-base.js +3953 -134
  53. package/esm/contensis-react-base.js.map +1 -1
  54. package/esm/forms.js +547 -583
  55. package/esm/forms.js.map +1 -1
  56. package/esm/{fromJSLeaveImmer-392af4e3.js → fromJSLeaveImmer-0114ffcf.js} +2 -16
  57. package/esm/fromJSLeaveImmer-0114ffcf.js.map +1 -0
  58. package/esm/{login-6eab4c94.js → login-508cac0f.js} +92 -55
  59. package/esm/login-508cac0f.js.map +1 -0
  60. package/esm/{reducers-d6c0edb1.js → reducers-8e5d6232.js} +26 -25
  61. package/esm/reducers-8e5d6232.js.map +1 -0
  62. package/esm/redux.js +8 -7
  63. package/esm/redux.js.map +1 -1
  64. package/esm/routing.js +5 -4
  65. package/esm/routing.js.map +1 -1
  66. package/esm/sagas-1f2b2aa0.js +2000 -0
  67. package/esm/sagas-1f2b2aa0.js.map +1 -0
  68. package/esm/search.js +252 -1856
  69. package/esm/search.js.map +1 -1
  70. package/esm/{selectors-8fca7fb2.js → selectors-a5e5835b.js} +9 -6
  71. package/esm/selectors-a5e5835b.js.map +1 -0
  72. package/esm/setCachingHeaders-d49060e1.js +10 -0
  73. package/esm/setCachingHeaders-d49060e1.js.map +1 -0
  74. package/esm/user.js +23 -14
  75. package/esm/user.js.map +1 -1
  76. package/esm/util.js +17 -17
  77. package/esm/util.js.map +1 -1
  78. package/esm/{version-ad2ec52c.js → version-2485e2fb.js} +2 -2
  79. package/{cjs/version-be0c7b7a.js.map → esm/version-2485e2fb.js.map} +1 -1
  80. package/esm/{version-612d9ef0.js → version-c776a92b.js} +33 -22
  81. package/esm/version-c776a92b.js.map +1 -0
  82. package/models/app/pages/VersionInfo/components/VersionInfo.d.ts +1 -1
  83. package/models/forms/index.d.ts +3 -1
  84. package/models/index.d.ts +1 -0
  85. package/models/redux/appstate.d.ts +5 -10
  86. package/models/redux/sagas/navigation.d.ts +1 -1
  87. package/models/redux/selectors/navigation.d.ts +2 -1
  88. package/models/routing/components/RouteLoader.d.ts +2 -19
  89. package/models/routing/redux/actions.d.ts +1 -1
  90. package/models/routing/redux/selectors.d.ts +1 -1
  91. package/models/routing/routes.d.ts +9 -3
  92. package/models/routing/util/expressions.d.ts +3 -2
  93. package/models/routing/util/queries.d.ts +1 -1
  94. package/models/search/containers/withListing.d.ts +1 -1
  95. package/models/search/containers/withSearch.d.ts +1 -1
  96. package/models/search/hooks/useFacets.hook.d.ts +3 -0
  97. package/models/search/hooks/useListing.hook.d.ts +3 -0
  98. package/models/search/hooks/useMinilist.hook.d.ts +2 -9
  99. package/models/search/index.d.ts +6 -2
  100. package/models/search/models/Queries.d.ts +8 -5
  101. package/models/search/models/Search.d.ts +60 -28
  102. package/models/search/models/SearchActions.d.ts +9 -5
  103. package/models/search/models/SearchProps.d.ts +52 -7
  104. package/models/search/models/SearchState.d.ts +5 -1
  105. package/models/search/models/index.d.ts +3 -1
  106. package/models/search/redux/actions.d.ts +5 -2
  107. package/models/search/redux/reducers.d.ts +230 -314
  108. package/models/search/redux/sagas.d.ts +11 -7
  109. package/models/search/redux/selectors.d.ts +21 -24
  110. package/models/search/redux/util.d.ts +1 -0
  111. package/models/search/search/ContensisDeliveryApi.d.ts +1 -0
  112. package/models/search/search/expressions.d.ts +5 -8
  113. package/models/search/{redux → search}/queries.d.ts +0 -0
  114. package/models/search/search/util.d.ts +14 -0
  115. package/models/search/transformations/entry-to-filteritem.mapper.d.ts +2 -1
  116. package/models/search/transformations/filter-to-filterexpression.mapper.d.ts +6 -0
  117. package/models/search/transformations/filters-to-filterexpressions.mapper.d.ts +3 -0
  118. package/models/search/transformations/index.d.ts +3 -0
  119. package/models/search/transformations/queryParams-to-customapi.mapper.d.ts +3 -0
  120. package/models/search/transformations/state-to-searchuri.d.ts +2 -13
  121. package/models/server/features/linkdepth-api/LinkDepthSearchService.d.ts +24 -0
  122. package/models/server/features/linkdepth-api/QueryLevelResults.d.ts +50 -0
  123. package/models/server/features/linkdepth-api/api.d.ts +12 -0
  124. package/models/server/features/linkdepth-api/events-api.config.d.ts +37 -0
  125. package/models/server/features/linkdepth-api/search.d.ts +31 -0
  126. package/models/server/features/linkdepth-api/util.d.ts +11 -0
  127. package/models/server/middleware/bundleManipulation.d.ts +2 -1
  128. package/models/server/util/bundles.d.ts +17 -21
  129. package/models/server/util/getVersionInfo.d.ts +1 -0
  130. package/models/server/util/headers.d.ts +3 -2
  131. package/models/user/components/Login.d.ts +1 -2
  132. package/models/user/components/LoginForm.d.ts +1 -2
  133. package/models/user/hocs/withLogin.d.ts +4 -2
  134. package/models/user/hocs/withRegistration.d.ts +2 -0
  135. package/models/user/hooks/useLogin.d.ts +5 -3
  136. package/models/user/redux/reducers.d.ts +4 -5
  137. package/models/user/redux/sagas/login.d.ts +11 -8
  138. package/models/user/redux/selectors.d.ts +12 -6
  139. package/models/user/util/LoginHelper.class.d.ts +4 -3
  140. package/models/util/ContensisDeliveryApi.d.ts +4 -4
  141. package/models/util/json-mapper.d.ts +9 -3
  142. package/models/util/merge.d.ts +1 -0
  143. package/package.json +60 -55
  144. package/CHANGELOG.md +0 -293
  145. package/cjs/App-e3200f18.js.map +0 -1
  146. package/cjs/RouteLoader-df3de0cb.js.map +0 -1
  147. package/cjs/ToJs-697ace9f.js.map +0 -1
  148. package/cjs/actions-a24bf46e.js.map +0 -1
  149. package/cjs/fromJSLeaveImmer-c00d597f.js.map +0 -1
  150. package/cjs/login-bc55ee33.js.map +0 -1
  151. package/cjs/reducers-fde41d6b.js.map +0 -1
  152. package/cjs/selectors-0ec95076.js.map +0 -1
  153. package/cjs/version-4f0f5fa6.js.map +0 -1
  154. package/esm/App-f9e7d03b.js.map +0 -1
  155. package/esm/RouteLoader-027215f2.js.map +0 -1
  156. package/esm/ToJs-46761960.js.map +0 -1
  157. package/esm/actions-b949ef5c.js.map +0 -1
  158. package/esm/fromJSLeaveImmer-392af4e3.js.map +0 -1
  159. package/esm/login-6eab4c94.js.map +0 -1
  160. package/esm/reducers-d6c0edb1.js.map +0 -1
  161. package/esm/selectors-8fca7fb2.js.map +0 -1
  162. package/esm/version-612d9ef0.js.map +0 -1
  163. package/models/search/transformations/filters-to-filterexpression.d.ts +0 -1
  164. package/models/search/transformations/filters-to-filterexpression.mapper.d.ts +0 -2
  165. package/models/server/features/caching/cacheHashing.d.ts +0 -1
  166. package/package-lock.json +0 -14093
package/cjs/search.js CHANGED
@@ -4,46 +4,26 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
6
  var reactRedux = require('react-redux');
7
- var mapJson = require('jsonpath-mapper');
8
- var log = require('loglevel');
9
- var effects = require('@redux-saga/core/effects');
10
- var contensisDeliveryApi = require('contensis-delivery-api');
11
- var queryString = require('query-string');
12
- var contensisCoreApi = require('contensis-core-api');
13
- var merge = require('deepmerge');
7
+ var sagas = require('./sagas-594b5ecd.js');
8
+ require('jsonpath-mapper');
14
9
  var reselect = require('reselect');
10
+ var merge = require('deepmerge');
11
+ require('query-string');
15
12
  var immer = require('immer');
16
13
  var equals = require('deep-equal');
14
+ require('contensis-core-api');
15
+ require('loglevel');
16
+ require('@redux-saga/core/effects');
17
+ require('contensis-delivery-api');
17
18
 
18
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
19
20
 
20
- function _interopNamespace(e) {
21
- if (e && e.__esModule) return e;
22
- var n = Object.create(null);
23
- if (e) {
24
- Object.keys(e).forEach(function (k) {
25
- if (k !== 'default') {
26
- var d = Object.getOwnPropertyDescriptor(e, k);
27
- Object.defineProperty(n, k, d.get ? d : {
28
- enumerable: true,
29
- get: function () { return e[k]; }
30
- });
31
- }
32
- });
33
- }
34
- n["default"] = e;
35
- return Object.freeze(n);
36
- }
37
-
38
21
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
39
- var mapJson__default = /*#__PURE__*/_interopDefaultLegacy(mapJson);
40
- var log__namespace = /*#__PURE__*/_interopNamespace(log);
41
- var queryString__default = /*#__PURE__*/_interopDefaultLegacy(queryString);
42
22
  var merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);
43
23
  var equals__default = /*#__PURE__*/_interopDefaultLegacy(equals);
44
24
 
45
25
  /* eslint-disable import/default */
46
- const toJS$1 = WrappedComponent => wrappedComponentProps => {
26
+ const toJS = WrappedComponent => wrappedComponentProps => {
47
27
  const KEY = 0;
48
28
  const VALUE = 1;
49
29
  const propsJS = Object.entries(wrappedComponentProps).reduce((newProps, wrappedComponentProp) => {
@@ -55,448 +35,8 @@ const toJS$1 = WrappedComponent => wrappedComponentProps => {
55
35
  return /*#__PURE__*/React__default["default"].createElement(WrappedComponent, propsJS);
56
36
  };
57
37
 
58
- const ACTION_PREFIX = '@SEARCH/';
59
- const APPLY_CONFIG = `${ACTION_PREFIX}APPLY_CONFIG`;
60
- const CLEAR_FILTERS = `${ACTION_PREFIX}CLEAR_FILTERS`;
61
- const DO_SEARCH = `${ACTION_PREFIX}DO_SEARCH`;
62
- const EXECUTE_SEARCH = `${ACTION_PREFIX}EXECUTE_SEARCH`;
63
- const EXECUTE_SEARCH_ERROR = `${ACTION_PREFIX}EXECUTE_SEARCH_ERROR`;
64
- const EXECUTE_SEARCH_PRELOAD = `${ACTION_PREFIX}EXECUTE_SEARCH_PRELOAD`;
65
- const LOAD_FILTERS = `${ACTION_PREFIX}LOAD_FILTERS`;
66
- const LOAD_FILTERS_COMPLETE = `${ACTION_PREFIX}LOAD_FILTERS_COMPLETE`;
67
- const LOAD_FILTERS_ERROR = `${ACTION_PREFIX}LOAD_FILTERS_ERROR`;
68
- const SET_FEATURED_ENTRIES = `${ACTION_PREFIX}SET_FEATURED_ENTRIES`;
69
- const SET_ROUTE_FILTERS = `${ACTION_PREFIX}SET_ROUTE_FILTERS`;
70
- const SET_SEARCH_FILTERS = `${ACTION_PREFIX}SET_SEARCH_FILTERS`;
71
- const SET_SEARCH_ENTRIES = `${ACTION_PREFIX}SET_SEARCH_ENTRIES`;
72
- const SET_SELECTED_FILTER = `${ACTION_PREFIX}SET_SELECTED_FILTER`;
73
- const UPDATE_CURRENT_FACET = `${ACTION_PREFIX}UPDATE_CURRENT_FACET`;
74
- const UPDATE_CURRENT_TAB = `${ACTION_PREFIX}UPDATE_CURRENT_TAB`;
75
- const UPDATE_SORT_ORDER = `${ACTION_PREFIX}UPDATE_SORT_ORDER`;
76
- const UPDATE_PAGE_INDEX = `${ACTION_PREFIX}UPDATE_PAGE_INDEX`;
77
- const UPDATE_SEARCH_TERM = `${ACTION_PREFIX}UPDATE_SEARCH_TERM`;
78
- const UPDATE_SELECTED_FILTERS = `${ACTION_PREFIX}UPDATE_SELECTED_FILTERS`;
79
-
80
- var types = /*#__PURE__*/Object.freeze({
81
- __proto__: null,
82
- APPLY_CONFIG: APPLY_CONFIG,
83
- CLEAR_FILTERS: CLEAR_FILTERS,
84
- DO_SEARCH: DO_SEARCH,
85
- EXECUTE_SEARCH: EXECUTE_SEARCH,
86
- EXECUTE_SEARCH_ERROR: EXECUTE_SEARCH_ERROR,
87
- EXECUTE_SEARCH_PRELOAD: EXECUTE_SEARCH_PRELOAD,
88
- LOAD_FILTERS: LOAD_FILTERS,
89
- LOAD_FILTERS_COMPLETE: LOAD_FILTERS_COMPLETE,
90
- LOAD_FILTERS_ERROR: LOAD_FILTERS_ERROR,
91
- SET_FEATURED_ENTRIES: SET_FEATURED_ENTRIES,
92
- SET_ROUTE_FILTERS: SET_ROUTE_FILTERS,
93
- SET_SEARCH_FILTERS: SET_SEARCH_FILTERS,
94
- SET_SEARCH_ENTRIES: SET_SEARCH_ENTRIES,
95
- SET_SELECTED_FILTER: SET_SELECTED_FILTER,
96
- UPDATE_CURRENT_FACET: UPDATE_CURRENT_FACET,
97
- UPDATE_CURRENT_TAB: UPDATE_CURRENT_TAB,
98
- UPDATE_SORT_ORDER: UPDATE_SORT_ORDER,
99
- UPDATE_PAGE_INDEX: UPDATE_PAGE_INDEX,
100
- UPDATE_SEARCH_TERM: UPDATE_SEARCH_TERM,
101
- UPDATE_SELECTED_FILTERS: UPDATE_SELECTED_FILTERS
102
- });
103
-
104
- const withMappers = (action, mappers) => {
105
- return { ...action,
106
- mappers
107
- };
108
- }; // export const withMappers2 = (actionFunc, args, mappers) => {
109
- // return () => ({ ...actionFunc(args), mappers });
110
- // };
111
-
112
- const triggerSearch = ({
113
- config,
114
- context,
115
- debug,
116
- defaultLang,
117
- excludeIds,
118
- facet,
119
- mapper,
120
- params
121
- }) => {
122
- return {
123
- type: DO_SEARCH,
124
- config,
125
- context,
126
- debug,
127
- defaultLang,
128
- excludeIds,
129
- facet,
130
- mapper,
131
- params
132
- };
133
- };
134
- const initListing = ({
135
- context,
136
- facet,
137
- mapper,
138
- params
139
- }) => {
140
- return {
141
- type: SET_ROUTE_FILTERS,
142
- context,
143
- facet,
144
- mapper,
145
- params
146
- };
147
- };
148
- const navigate = (path, state) => {
149
- return {
150
- type: '@ROUTING/_SET_ROUTE',
151
- path,
152
- state
153
- };
154
- };
155
- const clearFilters$1 = () => {
156
- return {
157
- type: CLEAR_FILTERS
158
- };
159
- };
160
- const updatePageIndex$1 = pageIndex => {
161
- return {
162
- type: UPDATE_PAGE_INDEX,
163
- pageIndex
164
- };
165
- };
166
- const updateCurrentFacet$1 = facet => {
167
- return {
168
- type: UPDATE_CURRENT_FACET,
169
- facet
170
- };
171
- };
172
- const updateCurrentTab$1 = id => {
173
- return {
174
- type: UPDATE_CURRENT_TAB,
175
- id
176
- };
177
- };
178
- const updateSearchTerm$1 = term => {
179
- return {
180
- type: UPDATE_SEARCH_TERM,
181
- term
182
- };
183
- };
184
- const updateSelectedFilters = (filter, key) => {
185
- return {
186
- type: UPDATE_SELECTED_FILTERS,
187
- filter,
188
- key
189
- };
190
- };
191
- const updateSortOrder$1 = (orderBy, facet) => {
192
- return {
193
- type: UPDATE_SORT_ORDER,
194
- orderBy,
195
- facet
196
- };
197
- };
198
-
199
- var actions = /*#__PURE__*/Object.freeze({
200
- __proto__: null,
201
- withMappers: withMappers,
202
- triggerSearch: triggerSearch,
203
- initListing: initListing,
204
- navigate: navigate,
205
- clearFilters: clearFilters$1,
206
- updatePageIndex: updatePageIndex$1,
207
- updateCurrentFacet: updateCurrentFacet$1,
208
- updateCurrentTab: updateCurrentTab$1,
209
- updateSearchTerm: updateSearchTerm$1,
210
- updateSelectedFilters: updateSelectedFilters,
211
- updateSortOrder: updateSortOrder$1
212
- });
213
-
214
- let Context$1; // export type Context = 'facets' | 'listings' | 'minilist';
215
-
216
- (function (Context) {
217
- Context["facets"] = "facets";
218
- Context["listings"] = "listings";
219
- Context["minilist"] = "minilist";
220
- })(Context$1 || (Context$1 = {}));
221
-
222
- // or replace with a stub function for non-immutable gets
223
-
224
- const makeFromJS = (returnType = globalThis.STATE_TYPE || 'immutable') => {
225
- var _immutable, _immutable2;
226
-
227
- return returnType === 'immutable' ? ((_immutable = globalThis.immutable) === null || _immutable === void 0 ? void 0 : _immutable.fromJSOrdered) || ((_immutable2 = globalThis.immutable) === null || _immutable2 === void 0 ? void 0 : _immutable2.fromJS) || (v => v) : v => v;
228
- };
229
-
230
- const getImmutableOrJS = (state, stateKey, fallbackValue, returnType = globalThis.STATE_TYPE || 'immutable') => {
231
- // Find a fromJS function from global that is dynamically loaded in createStore
232
- // or replace with a stub function for non-immutable gets
233
- const fromJS = makeFromJS(returnType);
234
-
235
- if (state && 'get' in state && typeof state.get === 'function' && 'getIn' in state && typeof state.getIn === 'function' && 'toJS' in state && typeof state.toJS === 'function') {
236
- if (Array.isArray(stateKey)) return fromJS(state.getIn(stateKey, fallbackValue));
237
- return fromJS(state.get(stateKey, fallbackValue));
238
- }
239
-
240
- if (Array.isArray(stateKey) && state && typeof state === 'object') {
241
- const result = mapJson.jpath(stateKey.join('.'), state);
242
- if (typeof result === 'undefined') return fallbackValue;
243
- return result;
244
- }
245
-
246
- const result = state && typeof state === 'object' ? state[stateKey] : undefined;
247
- if (typeof result === 'undefined') return fallbackValue;
248
- return result;
249
- };
250
-
251
- const getSearchContext = state => getImmutableOrJS(state, ['search', 'context'], Context$1.facets);
252
- const getCurrent = (state, context = Context$1.facets) => context === Context$1.facets ? getCurrentFacet(state) : getCurrentListing(state);
253
- const getCurrentFacet = state => getImmutableOrJS(state, ['search', 'currentFacet']);
254
- const getCurrentListing = state => getImmutableOrJS(state, ['search', 'currentListing']);
255
- const getCurrentTab = state => getImmutableOrJS(state, ['search', Context$1.facets, getCurrentFacet(state), 'tabId'], 0);
256
- const getFacets = (state, returnType) => getImmutableOrJS(state, ['search', Context$1.facets], {}, returnType);
257
- const getTabFacets = state => Object.fromEntries(Object.entries(getFacets(state, 'js')).filter(([key]) => getImmutableOrJS(getFacets(state), [key, 'tabId'], 0) === getCurrentTab(state)));
258
- const getFacetTitles = state => Object.entries(getFacets(state, 'js')).map(([key, facet = {}]) => {
259
- var _facet$pagingInfo;
260
-
261
- return {
262
- key,
263
- title: facet.title,
264
- totalCount: (_facet$pagingInfo = facet.pagingInfo) === null || _facet$pagingInfo === void 0 ? void 0 : _facet$pagingInfo.totalCount
265
- };
266
- });
267
- const getFacet = (state, facetName = '', context = Context$1.facets, returnType) => {
268
- const currentFacet = facetName || getCurrentFacet(state);
269
- return getImmutableOrJS(state, ['search', context, currentFacet], {}, returnType);
270
- };
271
- const getListing = (state, listing = '') => {
272
- const currentListing = listing || getCurrentListing(state);
273
- return getImmutableOrJS(state, ['search', Context$1.listings, currentListing], {});
274
- };
275
- const getFilters = (state, facet, context = Context$1.facets, returnType) => {
276
- return getImmutableOrJS(state, ['search', context, facet || getCurrent(state, context), 'filters'], {}, returnType);
277
- };
278
- const getRenderableFilters = (state, facet = '', context = Context$1.facets) => Object.fromEntries(Object.entries(getFilters(state, facet, context, 'js')).filter(([, f = {}]) => typeof f.renderable !== 'boolean' ? true : f.renderable));
279
- const getFiltersToLoad = (state, facet, context = Context$1.facets, returnType) => {
280
- const filters = getFilters(state, facet, context, returnType);
281
- const loadedFilters = Object.entries(filters).map(([key, f = {}]) => [key, (f.items || []).filter(i => {
282
- const title = i === null || i === void 0 ? void 0 : i.title;
283
- return typeof title !== 'undefined' && !!title;
284
- }).length > 0 && (f.isError || false) === false]);
285
- return loadedFilters.map(([filterKey, isLoaded]) => !isLoaded ? filterKey : null).filter(f => !!f);
286
- }; // We lowercase the filter key unless it's an ISO date string where the T must be uppercase
287
-
288
- const getSelectedFilters = (state, facet = '', context = Context$1.facets, returnType) => {
289
- const filters = getFilters(state, facet, context, 'js');
290
- const isoDateRegex = RegExp(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d/);
291
- const selectedFilters = Object.fromEntries(Object.entries(filters).map(([key, filter = {}]) => [key, (filter.items || []).filter(item => !!(item.isSelected || false)).map(item => {
292
- const key = (item === null || item === void 0 ? void 0 : item.key) || '';
293
- const isIsoDate = isoDateRegex.test(key);
294
- return isIsoDate ? key : key.toLowerCase();
295
- })]));
296
- const fromJS = makeFromJS(returnType);
297
- return fromJS(selectedFilters);
298
- };
299
- const getResults = (state, current = '', context = Context$1.facets, returnType) => {
300
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'results'], [], returnType);
301
- };
302
- const getIsInternalPaging = (state, current, context = Context$1.facets) => {
303
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'queryParams', 'internalPaging'], false);
304
- };
305
- const getIsLoaded = (state, context = Context$1.facets, facet) => {
306
- return !!getImmutableOrJS(state, ['search', context, facet || getCurrent(state, context), 'queryDuration'], 0);
307
- };
308
- const getIsLoading = (state, context = Context$1.facets, facet) => {
309
- return getImmutableOrJS(state, ['search', context, facet || getCurrent(state, context), 'entries', 'isLoading']);
310
- };
311
- const getIsSsr = state => getImmutableOrJS(state, ['search', 'config', 'ssr'], false);
312
- const getFeaturedResults = (state, current = '', context = Context$1.facets) => {
313
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'featuredResults'], []);
314
- };
315
- const getPaging = (state, current = '', context = Context$1.facets, returnType) => {
316
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo'], {}, returnType);
317
- };
318
- const getPageIndex = (state, current = '', context = Context$1.facets) => {
319
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo', 'pageIndex']);
320
- };
321
- const getPrevPageIndex = (state, current = '', context = Context$1.facets) => {
322
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo', 'prevPageIndex']);
323
- };
324
- const getPageIsLoading = (state, current = '', context = Context$1.facets) => {
325
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo', 'isLoading']);
326
- };
327
- const getPagesLoaded = (state, current = '', context = Context$1.facets) => {
328
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo', 'pagesLoaded'], [], 'js');
329
- };
330
- const getTotalCount = (state, current = '', context = Context$1.facets) => {
331
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'pagingInfo', 'totalCount']);
332
- };
333
- const getSearchTerm = state => getImmutableOrJS(state, ['search', 'term']);
334
- const getSearchTabs = (state, returnType) => getImmutableOrJS(state, ['search', 'tabs'], [], returnType);
335
- const getQueryParams = (state, current = '', context = Context$1.facets) => {
336
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'queryParams'], {}, 'js');
337
- };
338
- const getQueryParameter = ({
339
- state,
340
- facet,
341
- context = Context$1.facets
342
- }, key, ifnull = null) => {
343
- return getImmutableOrJS(getQueryParams(state, facet, context), key, ifnull, 'js');
344
- };
345
- const getCustomApi = (state, current, context = Context$1.facets, returnType) => {
346
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'customApi'], null, returnType);
347
- };
348
- const getCustomEnv = (state, current, context = Context$1.facets) => {
349
- return getImmutableOrJS(state, ['search', context, current || getCurrent(state, context), 'env']);
350
- };
351
- const getTabsAndFacets = (state, returnType) => {
352
- const tabs = getSearchTabs(state, 'js');
353
- const facets = getFacets(state, 'js');
354
- const tabsAndFacets = (tabs || []).map((tab = {}) => {
355
- const fieldsToCount = tab.totalCount;
356
- let countFields;
357
- if (typeof fieldsToCount === 'string') countFields = [[fieldsToCount]];
358
- const thisTabFacets = Object.entries(facets).filter(([key]) => getImmutableOrJS(facets, [key, 'tabId'], 0) === tab.id);
359
- const thisTabTotal = thisTabFacets.map(([facetName, facet = {}]) => {
360
- if (!countFields || countFields.find((f = []) => (f === null || f === void 0 ? void 0 : f[0]) === facetName)) return getImmutableOrJS(facet, ['pagingInfo', 'totalCount']);
361
- return 0;
362
- }).reduce((a, b) => a + b, 0);
363
- return { ...tab,
364
- [Context$1.facets]: Object.fromEntries(thisTabFacets),
365
- totalCount: thisTabTotal
366
- };
367
- });
368
- const fromJS = makeFromJS(returnType);
369
- return fromJS(tabsAndFacets);
370
- };
371
- const getSearchTotalCount = state => {
372
- const tabsAndFacets = getTabsAndFacets(state, 'js');
373
- const wholeSearchTotal = tabsAndFacets.map((t = {}) => t.totalCount).reduce((a, b) => a + b, 0);
374
- return wholeSearchTotal;
375
- };
376
- const getFacetsTotalCount = state => {
377
- const facets = getFacets(state);
378
- const wholeSearchTotal = Object.entries(facets).map(([, t = {}]) => {
379
- var _t$pagingInfo;
380
-
381
- return ((_t$pagingInfo = t.pagingInfo) === null || _t$pagingInfo === void 0 ? void 0 : _t$pagingInfo.totalCount) || 0;
382
- }).reduce((a, b) => a + b, 0);
383
- return wholeSearchTotal;
384
- }; // An exported copy of the relevant selectors scoped by default to a facets context
385
-
386
- const selectFacets = {
387
- getCurrent: getCurrentFacet,
388
- getCurrentTab,
389
- getCustomApi,
390
- getCustomEnv,
391
- getFacet,
392
- getFacetTitles,
393
- getFacets,
394
- getFacetsTotalCount,
395
- getFeaturedResults,
396
- getFilters,
397
- getFiltersToLoad,
398
- getIsLoaded,
399
- getIsLoading,
400
- getPageIndex,
401
- getPageIsLoading,
402
- getPagesLoaded,
403
- getPaging,
404
- getQueryParams: (state, facet) => getQueryParams(state, facet, Context$1.facets),
405
- getQueryParameter: ({
406
- state,
407
- facet
408
- }, key, ifnull) => getQueryParameter({
409
- state,
410
- facet,
411
- context: Context$1.facets
412
- }, key, ifnull),
413
- getRenderableFilters,
414
- getResults,
415
- getTabFacets,
416
- getTabsAndFacets,
417
- getTotalCount,
418
- getSearchTabs,
419
- getSearchTerm,
420
- getSearchTotalCount,
421
- getSelectedFilters
422
- }; // An exported copy of the relevant selectors pre-scoped to a listing context
423
-
424
- const selectListing = {
425
- getCurrent: getCurrentListing,
426
- getFeaturedResults: (state, listing = '') => getFeaturedResults(state, listing, Context$1.listings),
427
- getFilters: (state, listing = '') => getFilters(state, listing, Context$1.listings),
428
- getFiltersToLoad: (state, listing = '') => getFiltersToLoad(state, listing, Context$1.listings),
429
- getListing,
430
- getIsLoaded: state => getIsLoaded(state, Context$1.listings),
431
- getIsLoading: state => getIsLoading(state, Context$1.listings),
432
- getPageIndex: (state, listing = '') => getPageIndex(state, listing, Context$1.listings),
433
- getPaging: (state, listing = '') => getPaging(state, listing, Context$1.listings),
434
- getPageIsLoading: (state, listing = '') => getPageIsLoading(state, listing, Context$1.listings),
435
- getPagesLoaded: (state, listing = '') => getPagesLoaded(state, listing, Context$1.listings),
436
- getQueryParams: (state, listing = '') => getQueryParams(state, listing, Context$1.listings),
437
- getQueryParameter: ({
438
- state,
439
- facet
440
- }, key, ifnull) => getQueryParameter({
441
- state,
442
- facet,
443
- context: Context$1.listings
444
- }, key, ifnull),
445
- getRenderableFilters: (state, listing = '') => getRenderableFilters(state, listing, Context$1.listings),
446
- getResults: (state, listing = '') => getResults(state, listing, Context$1.listings),
447
- getSearchTerm,
448
- getTotalCount: (state, listing = '') => getTotalCount(state, listing, Context$1.listings),
449
- getSelectedFilters: (state, listing = '') => getSelectedFilters(state, listing, Context$1.listings)
450
- };
451
- const selectCurrentPath = state => getImmutableOrJS(state, ['routing', 'currentPath']);
452
- const selectVersionStatus = state => getImmutableOrJS(state, ['version', 'contensisVersionStatus']);
453
-
454
- var selectors = /*#__PURE__*/Object.freeze({
455
- __proto__: null,
456
- getSearchContext: getSearchContext,
457
- getCurrent: getCurrent,
458
- getCurrentFacet: getCurrentFacet,
459
- getCurrentListing: getCurrentListing,
460
- getCurrentTab: getCurrentTab,
461
- getFacets: getFacets,
462
- getTabFacets: getTabFacets,
463
- getFacetTitles: getFacetTitles,
464
- getFacet: getFacet,
465
- getListing: getListing,
466
- getFilters: getFilters,
467
- getRenderableFilters: getRenderableFilters,
468
- getFiltersToLoad: getFiltersToLoad,
469
- getSelectedFilters: getSelectedFilters,
470
- getResults: getResults,
471
- getIsInternalPaging: getIsInternalPaging,
472
- getIsLoaded: getIsLoaded,
473
- getIsLoading: getIsLoading,
474
- getIsSsr: getIsSsr,
475
- getFeaturedResults: getFeaturedResults,
476
- getPaging: getPaging,
477
- getPageIndex: getPageIndex,
478
- getPrevPageIndex: getPrevPageIndex,
479
- getPageIsLoading: getPageIsLoading,
480
- getPagesLoaded: getPagesLoaded,
481
- getTotalCount: getTotalCount,
482
- getSearchTerm: getSearchTerm,
483
- getSearchTabs: getSearchTabs,
484
- getQueryParams: getQueryParams,
485
- getQueryParameter: getQueryParameter,
486
- getCustomApi: getCustomApi,
487
- getCustomEnv: getCustomEnv,
488
- getTabsAndFacets: getTabsAndFacets,
489
- getSearchTotalCount: getSearchTotalCount,
490
- getFacetsTotalCount: getFacetsTotalCount,
491
- selectFacets: selectFacets,
492
- selectListing: selectListing,
493
- selectCurrentPath: selectCurrentPath,
494
- selectVersionStatus: selectVersionStatus
495
- });
496
-
497
38
  // eslint-disable-next-line import/default
498
39
 
499
- /* eslint-disable @typescript-eslint/naming-convention */
500
40
  const withSearch = mappers => SearchComponent => {
501
41
  const Wrapper = props => {
502
42
  return /*#__PURE__*/React__default["default"].createElement(SearchComponent, props);
@@ -506,41 +46,42 @@ const withSearch = mappers => SearchComponent => {
506
46
 
507
47
  const mapStateToProps = state => {
508
48
  return {
509
- currentFacet: getCurrentFacet(state),
510
- currentPageIndex: getPageIndex(state),
511
- currentTabIndex: getCurrentTab(state),
512
- facet: getFacet(state),
513
- facets: getTabFacets(state),
514
- facetsTotalCount: getFacetsTotalCount(state),
515
- facetTitles: getFacetTitles(state),
516
- featuredResults: getFeaturedResults(state),
517
- filters: getRenderableFilters(state),
518
- isLoading: getIsLoading(state),
519
- paging: getPaging(state),
520
- pageIsLoading: getPageIsLoading(state),
521
- results: getResults(state),
49
+ currentFacet: sagas.getCurrentFacet(state),
50
+ currentPageIndex: sagas.getPageIndex(state),
51
+ currentTabIndex: sagas.getCurrentTab(state),
52
+ facet: sagas.getFacet(state),
53
+ facets: sagas.getTabFacets(state),
54
+ facetsTotalCount: sagas.getFacetsTotalCount(state),
55
+ facetTitles: sagas.getFacetTitles(state),
56
+ featuredResults: sagas.getFeaturedResults(state),
57
+ filters: sagas.getRenderableFilters(state),
58
+ isLoading: sagas.getIsLoading(state),
59
+ paging: sagas.getPaging(state),
60
+ pageIsLoading: sagas.getPageIsLoading(state),
61
+ results: sagas.getResults(state),
522
62
  resultsInfo: (mappers === null || mappers === void 0 ? void 0 : mappers.resultsInfo) && mappers.resultsInfo(state),
523
- searchTerm: getSearchTerm(state),
524
- searchTotalCount: getSearchTotalCount(state),
525
- sortOrder: getQueryParameter({
63
+ searchTerm: sagas.getSearchTerm(state),
64
+ searchTotalCount: sagas.getSearchTotalCount(state),
65
+ selectedFilters: sagas.getSelectedFilters(state),
66
+ sortOrder: sagas.getQueryParameter({
526
67
  state
527
68
  }, 'dynamicOrderBy', []),
528
- tabsAndFacets: getTabsAndFacets(state),
529
- totalCount: getTotalCount(state)
69
+ tabsAndFacets: sagas.getTabsAndFacets(state),
70
+ totalCount: sagas.getTotalCount(state)
530
71
  };
531
72
  };
532
73
 
533
74
  const mapDispatchToProps = {
534
- clearFilters: () => withMappers(clearFilters$1(), mappers),
535
- updateCurrentFacet: facet => withMappers(updateCurrentFacet$1(facet), mappers),
536
- updateCurrentTab: id => withMappers(updateCurrentTab$1(id), mappers),
537
- updatePageIndex: pageIndex => withMappers(updatePageIndex$1(pageIndex), mappers),
538
- updateSearchTerm: term => withMappers(updateSearchTerm$1(term), mappers),
539
- updateSelectedFilters: (filter, key) => withMappers(updateSelectedFilters(filter, key), mappers),
540
- updateSortOrder: orderBy => withMappers(updateSortOrder$1(orderBy), mappers)
75
+ clearFilters: filterKey => sagas.withMappers(sagas.clearFilters(filterKey), mappers),
76
+ updateCurrentFacet: facet => sagas.withMappers(sagas.updateCurrentFacet(facet), mappers),
77
+ updateCurrentTab: id => sagas.withMappers(sagas.updateCurrentTab(id), mappers),
78
+ updatePageIndex: (pageIndex, scrollYPos) => sagas.withMappers(sagas.updatePageIndex(pageIndex, scrollYPos), mappers),
79
+ updateSearchTerm: term => sagas.withMappers(sagas.updateSearchTerm(term), mappers),
80
+ updateSelectedFilters: (filter, key, isUnknownItem = false, scrollYPos) => sagas.withMappers(sagas.updateSelectedFilters(filter, key, isUnknownItem, scrollYPos), mappers),
81
+ updateSortOrder: orderBy => sagas.withMappers(sagas.updateSortOrder(orderBy), mappers)
541
82
  };
542
83
  const connector = reactRedux.connect(mapStateToProps, mapDispatchToProps);
543
- return connector(toJS$1(Wrapper));
84
+ return connector(toJS(Wrapper));
544
85
  };
545
86
 
546
87
  /* eslint-disable @typescript-eslint/naming-convention */
@@ -561,8 +102,9 @@ const withListing = mappers => ListingComponent => {
561
102
  getQueryParameter,
562
103
  getRenderableFilters,
563
104
  getResults,
564
- getSearchTerm
565
- } = selectListing;
105
+ getSearchTerm,
106
+ getSelectedFilters
107
+ } = sagas.selectListing;
566
108
 
567
109
  const mapStateToProps = state => {
568
110
  return {
@@ -576,6 +118,7 @@ const withListing = mappers => ListingComponent => {
576
118
  results: getResults(state),
577
119
  resultsInfo: mappers && typeof mappers.resultsInfo === 'function' && mappers.resultsInfo(state),
578
120
  searchTerm: getSearchTerm(state),
121
+ selectedFilters: getSelectedFilters(state),
579
122
  sortOrder: getQueryParameter({
580
123
  state
581
124
  }, 'dynamicOrderBy', [])
@@ -583,1399 +126,216 @@ const withListing = mappers => ListingComponent => {
583
126
  };
584
127
 
585
128
  const mapDispatchToProps = {
586
- clearFilters: () => withMappers(clearFilters$1(), mappers),
587
- updateCurrentFacet: facet => withMappers(updateCurrentFacet$1(facet), mappers),
588
- updatePageIndex: pageIndex => withMappers(updatePageIndex$1(pageIndex), mappers),
589
- updateSearchTerm: term => withMappers(updateSearchTerm$1(term), mappers),
590
- updateSelectedFilters: (filter, key) => withMappers(updateSelectedFilters(filter, key), mappers),
591
- updateSortOrder: orderBy => withMappers(updateSortOrder$1(orderBy), mappers)
129
+ clearFilters: filterKey => sagas.withMappers(sagas.clearFilters(filterKey), mappers),
130
+ updateCurrentFacet: facet => sagas.withMappers(sagas.updateCurrentFacet(facet), mappers),
131
+ updatePageIndex: (pageIndex, scrollYPos) => sagas.withMappers(sagas.updatePageIndex(pageIndex, scrollYPos), mappers),
132
+ updateSearchTerm: term => sagas.withMappers(sagas.updateSearchTerm(term), mappers),
133
+ updateSelectedFilters: (filter, key, isUnknownItem = false, scrollYPos) => sagas.withMappers(sagas.updateSelectedFilters(filter, key, isUnknownItem, scrollYPos), mappers),
134
+ updateSortOrder: orderBy => sagas.withMappers(sagas.updateSortOrder(orderBy), mappers)
592
135
  };
593
- return reactRedux.connect(mapStateToProps, mapDispatchToProps)(toJS$1(Wrapper));
136
+ return reactRedux.connect(mapStateToProps, mapDispatchToProps)(toJS(Wrapper));
594
137
  };
595
138
 
596
- const getClientConfig = (project, env) => {
597
- let config = DELIVERY_API_CONFIG;
598
- /* global DELIVERY_API_CONFIG */
599
-
600
- if (project) {
601
- config.projectId = project;
602
- }
603
-
604
- if (typeof window != 'undefined' && PROXY_DELIVERY_API
605
- /* global PROXY_DELIVERY_API */
606
- ) {
607
- // ensure a relative url is used to bypass the need for CORS (separate OPTIONS calls)
608
- config.rootUrl = env || '';
609
- config.responseHandler = {
610
- 404: () => null
611
- };
612
- }
613
-
614
- return config;
139
+ var defaultMappers = {
140
+ results: entries => entries,
141
+ navigate: sagas.mapStateToSearchUri
615
142
  };
616
143
 
617
- class CacheNode {
618
- constructor(key, value) {
619
- this.key = key;
620
- this.value = value;
621
- this.next = null;
622
- this.prev = null;
623
- }
624
-
625
- }
626
-
627
- class LruCache {
628
- constructor(limit = 100) {
629
- this.map = {};
630
- this.head = null;
631
- this.tail = null;
632
- this.limit = limit || 100;
633
- this.size = 0;
634
- }
635
-
636
- get(key) {
637
- if (this.map[key]) {
638
- let value = this.map[key].value;
639
- let node = new CacheNode(key, value);
640
- this.remove(key);
641
- this.setHead(node);
642
- return value;
643
- }
644
- }
645
-
646
- set(key, value) {
647
- let node = new CacheNode(key, value);
648
-
649
- if (this.map[key]) {
650
- this.remove(key);
651
- } else {
652
- if (this.size >= this.limit) {
653
- delete this.map[this.tail.key];
654
- this.size--;
655
- this.tail = this.tail.prev;
656
- this.tail.next = null;
657
- }
658
- }
659
-
660
- this.setHead(node);
661
- }
662
-
663
- setHead(node) {
664
- node.next = this.head;
665
- node.prev = null;
666
-
667
- if (this.head) {
668
- this.head.prev = node;
669
- }
670
-
671
- this.head = node;
672
-
673
- if (!this.tail) {
674
- this.tail = node;
675
- }
676
-
677
- this.size++;
678
- this.map[node.key] = node;
679
- }
680
-
681
- remove(key) {
682
- let node = this.map[key];
683
-
684
- if (node.prev) {
685
- node.prev.next = node.next;
686
- } else {
687
- this.head = node.next;
688
- }
689
-
690
- if (node.next) {
691
- node.next.prev = node.prev;
692
- } else {
693
- this.tail = node.prev;
694
- }
695
-
696
- delete this.map[key];
697
- this.size--;
698
- }
699
-
700
- }
701
-
702
- class CachedSearch {
703
- constructor() {
704
- this.cache = new LruCache();
705
- this.taxonomyLookup = {};
706
- }
707
-
708
- search(query, linkDepth, project, env) {
709
- const client = contensisDeliveryApi.Client.create(getClientConfig(project, env));
710
- return this.request(project + JSON.stringify(query) + linkDepth.toString(), () => client.entries.search(query, linkDepth));
711
- }
712
-
713
- getTaxonomyNodeByPath(path, project, env) {
714
- const client = contensisDeliveryApi.Client.create(getClientConfig(project, env));
715
- return this.request(`[TAXONOMY NODE] ${path}`, () => client.taxonomy.getNodeByPath({
716
- path: path,
717
- order: 'defined',
718
- childDepth: 2
719
- }).then(node => this.extendTaxonomyNode(node)));
720
- }
721
-
722
- request(key, execute) {
723
- if (!this.cache.get(key) || typeof window == 'undefined') {
724
- let promise = execute();
725
- this.cache.set(key, promise);
726
- promise.catch(() => {
727
- this.cache.remove(key);
728
- });
729
- }
730
-
731
- return this.cache.get(key);
732
- }
733
-
734
- extendTaxonomyNode(node) {
735
- let id = this.getTaxonomyId(node);
736
- this.taxonomyLookup[id] = node.key;
737
- return { ...node,
738
- id,
739
- children: node.children ? node.children.map(n => this.extendTaxonomyNode(n)) : null
740
- };
741
- }
742
-
743
- getTaxonomyId(node) {
744
- if (node.key) {
745
- let parts = node.key.split('/');
746
- return parts[parts.length - 1];
747
- }
748
-
749
- return '';
750
- }
751
-
752
- }
753
-
754
- const cachedSearch = new CachedSearch();
755
-
756
- const now = () => {
757
- if (typeof window == 'undefined') {
758
- return Date.now();
759
- }
760
-
761
- return window.performance.now();
762
- };
763
-
764
- // eslint-disable-next-line import/default
765
- function fixFreeTextForElastic(s) {
766
- const illegalChars = ['>', '<', '=', '|', '!', '{', '}', '[', ']', '^', '~', '*', '?', ':', '\\', '/'];
767
- const illegalRegEx = new RegExp(illegalChars.map(c => '\\' + c).join('|'), 'g');
768
- s = s.replace(illegalRegEx, ''); // s = s.replace(encodedRegEx, ''); // (m) => '\\\\' + m);
769
-
770
- return s;
771
- }
772
- const timedSearch = async (query, linkDepth = 0, projectId, env) => {
773
- if (!query) return null;
774
- let duration = 0;
775
- const start = now();
776
- const payload = await cachedSearch.search(query, linkDepth, projectId, env);
777
- const end = now();
778
- duration = end - start;
779
- return {
780
- duration,
781
- payload
782
- };
783
- };
784
- const getItemsFromResult = result => {
785
- const {
786
- payload
787
- } = result || {};
788
-
789
- if (payload) {
790
- if (Array.isArray(payload)) return payload;
791
- if (Array.isArray(payload.items)) return payload.items;
792
- return payload;
793
- }
794
-
795
- return [];
796
- };
797
- const extractQuotedPhrases = searchTerm => {
798
- const pattern = new RegExp(/(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')/gm);
799
- return (searchTerm.match(pattern) || []).map(match => match.replace(/"/g, ''));
800
- };
801
- const buildUrl = (route, params) => {
802
- const qs = queryString__default["default"].stringify(params);
803
- const path = qs ? `${route}?${qs}` : route;
804
- return path;
805
- };
806
- const callCustomApi = async (customApi, filters) => {
807
- const apiUri = customApi.uri || '';
808
- let uri = buildUrl(apiUri, filters);
809
- if (!uri) throw new Error('uri is required to use customApi');
810
- if (typeof window == 'undefined' && uri.startsWith('/')) uri = `http://localhost:3001${uri}`;
811
- const response = await fetch(uri);
812
- return await response.json();
813
- };
814
- const removeEmptyAttributes = obj => {
815
- Object.entries(obj).forEach(([key, val]) => val && typeof val === 'object' && removeEmptyAttributes(val) || (typeof val === 'undefined' || val === null || val === '') && delete obj[key]);
816
- return obj;
817
- };
818
- const toArray = (obj, seperator = ',') => typeof obj === 'undefined' || obj === null ? obj : Array.isArray(obj) ? obj : obj.split(seperator); // assumes array elements are primitive types
819
-
820
- const areArraysEqualSets = (a1, a2) => {
821
- const superSet = {};
822
-
823
- for (const ai of a1) {
824
- const e = ai + typeof ai;
825
- superSet[e] = 1;
826
- }
827
-
828
- for (const ai of a2) {
829
- const e = ai + typeof ai;
830
-
831
- if (!superSet[e]) {
832
- return false;
833
- }
834
-
835
- superSet[e] = 2;
836
- }
837
-
838
- for (const e in superSet) {
839
- if (superSet[e] === 1) {
840
- return false;
841
- }
842
- }
843
-
844
- return true;
845
- };
846
-
847
- const DataFormats = {
848
- asset: 'asset',
849
- entry: 'entry',
850
- webpage: 'webpage'
851
- };
852
- const FilterExpressionTypes = {
853
- contentType: 'contentType',
854
- field: 'field'
855
- };
856
- const sys = {
857
- allUris: 'sys.allUris',
858
- contentTypeId: 'sys.contentTypeId',
859
- dataFormat: 'sys.dataFormat',
860
- filename: 'sys.properties.filename',
861
- id: 'sys.id',
862
- includeInSearch: 'sys.metadata.includeInSearch',
863
- language: 'sys.language',
864
- uri: 'sys.uri',
865
- versionStatus: 'sys.versionStatus'
866
- };
867
- const Fields = {
868
- entryDescription: 'entryDescription',
869
- entryTitle: 'entryTitle',
870
- keywords: 'keywords',
871
- searchContent: 'searchContent',
872
- sys,
873
- contentTypeId: 'sys.contentTypeId',
874
- wildcard: '*'
875
- };
876
-
877
- const fieldExpression = (field, value, operator = 'equalTo', weight) => {
878
- if (!field || !value) return [];
879
- if (Array.isArray(field)) // If an array of fieldIds have been provided, call self for each fieldId
880
- // to generate expressions that are combined with an 'or' operator
881
- return [contensisCoreApi.Op.or(...field.map(fieldId => fieldExpression(fieldId, value, operator, weight)).flat())];
882
- if (operator === 'between') return between(field, value);
883
- if (Array.isArray(value)) return equalToOrIn(field, value, operator);else return !weight ? [contensisCoreApi.Op[operator](field, value, undefined, undefined)] : [contensisCoreApi.Op[operator](field, value, undefined, undefined).weight(weight)];
884
- };
885
- const contentTypeIdExpression = (contentTypeIds, webpageTemplates, assetTypes) => {
886
- const expressions = [];
887
- if (!contentTypeIds && !webpageTemplates && !assetTypes) return expressions;
888
-
889
- if (contentTypeIds && contentTypeIds.length > 0) {
890
- expressions.push(...dataFormatExpression(contentTypeIds, DataFormats.entry));
891
- }
892
-
893
- if (webpageTemplates && webpageTemplates.length > 0) {
894
- expressions.push(...dataFormatExpression(webpageTemplates, DataFormats.webpage));
895
- }
896
-
897
- if (assetTypes && assetTypes.length > 0) {
898
- expressions.push(...dataFormatExpression(assetTypes, DataFormats.asset));
899
- }
900
-
901
- if (expressions.length > 1) return [contensisCoreApi.Op.or(...expressions)];
902
- return expressions;
903
- };
904
- const filterExpressions = filters => {
905
- if (!filters) return [];
906
- const expressions = [];
907
- filters.map(param => {
908
- expressions.push(...fieldExpression(param.key, param.value, param.operator || 'in'));
909
- });
910
- return expressions;
911
- };
912
- const dataFormatExpression = (contentTypeIds, dataFormat = DataFormats.entry) => {
913
- if (contentTypeIds && contentTypeIds.length > 0) {
914
- /**
915
- * We have an array of contentTypeIds some may be prefixed with a "!"
916
- * to indicate this is a "not" expression
917
- */
918
- const withContentTypeIds = contentTypeIds.filter(c => !c.startsWith('!'));
919
- const notContentTypeIds = contentTypeIds.filter(c => c.startsWith('!')).map(id => id.substring(1));
920
- const andExpr = contensisCoreApi.Op.and();
921
- const dataFormatExpr = fieldExpression(Fields.sys.dataFormat, dataFormat)[0];
922
- const withExpr = fieldExpression(Fields.sys.contentTypeId, withContentTypeIds)[0];
923
- const notExpr = contensisCoreApi.Op.not(fieldExpression(Fields.sys.contentTypeId, notContentTypeIds)[0]);
924
- andExpr.add(dataFormatExpr);
925
- if (withContentTypeIds.length > 0) andExpr.add(withExpr);
926
- if (notContentTypeIds.length > 0) andExpr.add(notExpr);
927
- return [andExpr];
928
- }
929
-
930
- return [];
931
- };
932
- const featuredResultsExpression = ({
933
- contentTypeId,
934
- fieldId,
935
- fieldValue = true
936
- } = {}) => {
937
- const expressions = [];
938
-
939
- if (contentTypeId) {
940
- expressions.push(...contentTypeIdExpression(Array.isArray(contentTypeId) ? contentTypeId : [contentTypeId]));
941
- }
942
-
943
- if (fieldId && fieldValue) {
944
- expressions.push(...fieldExpression(fieldId, fieldValue));
945
- }
946
-
947
- return expressions;
948
- };
949
- const languagesExpression = languages => fieldExpression(Fields.sys.language, languages);
950
- const includeInSearchExpressions = (webpageTemplates, includeInSearchFields) => {
951
- const expressions = []; // Or include this expression if we have explicity specified non-default includeInSearch fields
952
-
953
- if (Array.isArray(includeInSearchFields)) expressions.push(...includeInSearchFields.map(includeInSearchField => contensisCoreApi.Op.or(contensisCoreApi.Op.and(contensisCoreApi.Op.exists(includeInSearchField, true), contensisCoreApi.Op.equalTo(includeInSearchField, true)), contensisCoreApi.Op.exists(includeInSearchField, false)))); // If webpageTemplates have been specified, include this expression
954
- // with the default includeInSearch field from classic Contensis.
955
-
956
- if (Array.isArray(webpageTemplates) && webpageTemplates.length > 0) expressions.push(contensisCoreApi.Op.or(contensisCoreApi.Op.and(contensisCoreApi.Op.exists(Fields.sys.includeInSearch, true), contensisCoreApi.Op.equalTo(Fields.sys.includeInSearch, true)), contensisCoreApi.Op.exists(Fields.sys.includeInSearch, false)));
957
- return expressions;
958
- };
959
- const defaultExpressions = versionStatus => {
960
- return [contensisCoreApi.Op.equalTo(Fields.sys.versionStatus, versionStatus)];
961
- };
962
- const excludeIdsExpression = excludeIds => {
963
- if (Array.isArray(excludeIds) && excludeIds.length > 0) {
964
- const [expr] = fieldExpression(Fields.sys.id, excludeIds);
965
- return [contensisCoreApi.Op.not(expr)];
966
- } else return [];
967
- };
968
- const orderByExpression = orderBy => {
969
- let expression = contensisCoreApi.OrderBy;
970
-
971
- if (orderBy && orderBy.length > 0) {
972
- orderBy.map(ob => expression = ob.startsWith('-') ? expression.desc(ob.substring(1)) : expression.asc(ob));
973
- }
974
-
975
- return expression;
976
- };
977
-
978
- const equalToOrIn = (field, value, operator = 'equalTo') => {
979
- if (value.length === 0) return [];
980
-
981
- if (Array.isArray(value)) {
982
- if (value.length === 1) return [contensisCoreApi.Op[operator](field, value[0], undefined, undefined)];
983
- return [contensisCoreApi.Op.in(field, ...value)];
984
- }
985
-
986
- return [];
987
- };
988
-
989
- const between = (field, value) => {
990
- const handle = betweenValue => {
991
- const valArr = betweenValue.split('-');
992
-
993
- if (valArr.length > 1) {
994
- const [minimum, maximum = null] = betweenValue.split('-');
995
- return contensisCoreApi.Op.between(field, minimum, maximum);
996
- } else {
997
- // eslint-disable-next-line no-console
998
- console.log(`[search] You have supplied only one value to a "between" operator which must have two values. Your supplied value "${valArr.length && valArr[0]}" has been discarded.`);
999
- return false;
1000
- }
1001
- };
1002
-
1003
- if (value.length === 0) return [];
1004
- if (Array.isArray(value)) return [contensisCoreApi.Op.or(...value.map(handle).filter(bc => bc !== false))]; // const valArr = value.split('-');
1005
-
1006
- const op = handle(value);
1007
- return op ? [op] : []; // valArr.length > 1 ? [Op.between(field, ...value.split('-'))] : [];
1008
- };
1009
- /**
1010
- * Accept HTTP style objects and map them to
1011
- * their equivalent JS client "Op" expressions
1012
- * @param {array} where the where array as you'd provide it to the HTTP API
1013
- * @returns {array} array of constructed Delivery API Operators
1014
- */
1015
-
1016
-
1017
- const customWhereExpressions = where => {
1018
- if (!where || !Array.isArray(where)) return []; // Map each clause inside the where array
1019
-
1020
- return where.map(clause => {
1021
- let expression; // Map through each property in the clause so we can
1022
- // capture the values required and reconstruct them as
1023
- // a Delivery API expression
1024
-
1025
- let operator;
1026
- Object.keys(clause).map((key, idx) => {
1027
- // The clause may contain only one key
1028
- if (idx === 0) operator = key;
1029
- const field = clause.field;
1030
- const value = clause[Object.keys(clause).find(k => !['field', 'weight'].includes(k)) || ''];
1031
- const weight = clause.weight;
1032
-
1033
- if (idx === 0) {
1034
- if (operator === 'and' || operator === 'or') {
1035
- // These are array expressions so we can call ourself recursively
1036
- // to map these inner values to expressions
1037
- const recurseExpr = customWhereExpressions(clause[operator]);
1038
- expression = contensisCoreApi.Op[operator](...recurseExpr);
1039
- }
1040
-
1041
- if (['not'].includes(operator)) {
1042
- // A 'not' expression is an object with only one inner field and inner operator
1043
- Object.keys(value).map((notKey, notIdx) => {
1044
- const innerOperator = notKey;
1045
- const innerValue = value[notKey];
1046
- const innerField = value.field; // Map the expression when we've looped and scoped to
1047
- // the second property inside the clause
1048
-
1049
- if (notIdx === 1) {
1050
- expression = contensisCoreApi.Op.not(contensisCoreApi.Op[innerOperator](innerField, innerValue));
1051
- }
1052
- });
1053
- }
1054
- } // Map the expression when we've looped and scoped to
1055
- // the second property inside the clause
1056
-
1057
-
1058
- operator = Object.keys(clause).find(clauseKey => !['field', 'weight'].includes(clauseKey));
1059
-
1060
- if (idx === 1 && // operator !== 'and' &&
1061
- // operator !== 'or' &&
1062
- operator !== 'between' && operator !== 'distanceWithin') {
1063
- expression = operator === 'freeText' || operator === 'contains' ? contensisCoreApi.Op[operator](field, value) : operator === 'in' ? contensisCoreApi.Op[operator](field, ...value) : contensisCoreApi.Op[operator](field, value);
1064
- if (typeof weight === 'number') expression = expression.weight(weight);
1065
- }
1066
- });
1067
- return expression;
1068
- });
1069
- };
1070
- const termExpressions = (searchTerm, weightedSearchFields) => {
1071
- if (searchTerm && weightedSearchFields && weightedSearchFields.length > 0) {
1072
- // Extract any phrases in quotes to array
1073
- const quotedPhrases = extractQuotedPhrases(searchTerm); // Modify the search term to remove any quoted phrases to leave any remaining terms
1074
-
1075
- let modifiedSearchTerm = searchTerm;
1076
- quotedPhrases.forEach(qp => modifiedSearchTerm = modifiedSearchTerm.replace(qp, '').replace('""', '').trim()); // Push to the operators array to include in the query
1077
-
1078
- const operators = []; // Helper functions to generate Op expressions
1079
-
1080
- const containsOp = (f, term) => fieldExpression(f.fieldId, fixFreeTextForElastic(term), 'contains', f.weight);
1081
-
1082
- const freeTextOp = (f, term) => fieldExpression(f.fieldId, fixFreeTextForElastic(term), 'freeText', f.weight); // For each weighted search field
1083
-
1084
-
1085
- weightedSearchFields.forEach(wsf => {
1086
- // Push to field operators
1087
- const fieldOperators = []; // Add operator expressions for modified search term
1088
-
1089
- if (modifiedSearchTerm) {
1090
- if ([Fields.keywords, Fields.sys.filename, Fields.sys.uri].includes(wsf.fieldId)) {
1091
- fieldOperators.push(...containsOp(wsf, modifiedSearchTerm));
1092
- } else {
1093
- if ([Fields.entryTitle].includes(wsf.fieldId)) {
1094
- fieldOperators.push(contensisCoreApi.Op.or(...containsOp(wsf, modifiedSearchTerm), ...freeTextOp(wsf, modifiedSearchTerm)));
1095
- } else {
1096
- fieldOperators.push(...freeTextOp(wsf, modifiedSearchTerm));
1097
- }
1098
- }
1099
- } // Add operator expressions for any quoted phrases
1100
-
1101
-
1102
- quotedPhrases.forEach(qp => fieldOperators.push(...containsOp(wsf, qp))); // If we are using multiple operators for a field we will
1103
- // wrap each field inside an And operator so we will match
1104
- // all terms/phrases rather than any terms/phrases
1105
-
1106
- if (fieldOperators.length > 1) {
1107
- operators.push(contensisCoreApi.Op.and(...fieldOperators));
1108
- } else {
1109
- operators.push(...fieldOperators);
1110
- }
1111
- }); // Wrap operators in an Or operator
1112
-
1113
- return [contensisCoreApi.Op.or().addRange(operators).add(contensisCoreApi.Op.freeText(Fields.searchContent, searchTerm))];
1114
- } else if (searchTerm) {
1115
- // Searching without weightedSearchFields defined will fall back
1116
- // to a default set of search fields with arbritary weights set.
1117
- return [contensisCoreApi.Op.or(contensisCoreApi.Op.equalTo(Fields.entryTitle, searchTerm).weight(10), contensisCoreApi.Op.freeText(Fields.entryTitle, searchTerm).weight(2), contensisCoreApi.Op.freeText(Fields.entryDescription, searchTerm).weight(2), contensisCoreApi.Op.contains(Fields.keywords, searchTerm).weight(2), contensisCoreApi.Op.contains(Fields.sys.uri, searchTerm).weight(2), contensisCoreApi.Op.contains(Fields.sys.allUris, searchTerm), contensisCoreApi.Op.freeText(Fields.searchContent, searchTerm))];
1118
- } else {
1119
- return [];
1120
- }
1121
- };
1122
-
1123
- const filterQuery = (contentTypeIds, versionStatus, customWhere) => {
1124
- const query = new contensisCoreApi.Query(...[...contentTypeIdExpression(contentTypeIds), ...defaultExpressions(versionStatus), ...customWhereExpressions(customWhere)]);
1125
- query.orderBy = contensisCoreApi.OrderBy.asc(Fields.entryTitle);
1126
- query.pageSize = 100;
1127
- return query;
1128
- };
1129
- const searchQuery = ({
1130
- assetTypes,
1131
- contentTypeIds,
1132
- customWhere,
1133
- dynamicOrderBy,
1134
- excludeIds,
1135
- featuredResults,
1136
- fields,
1137
- filters,
1138
- includeInSearchFields,
1139
- languages,
1140
- pageSize,
1141
- pageIndex,
1142
- orderBy,
1143
- searchTerm,
1144
- versionStatus,
1145
- webpageTemplates,
1146
- weightedSearchFields
1147
- }, isFeatured = false) => {
1148
- let expressions = [...termExpressions(searchTerm, weightedSearchFields), ...defaultExpressions(versionStatus), ...includeInSearchExpressions(webpageTemplates, includeInSearchFields), ...languagesExpression(languages), ...customWhereExpressions(customWhere), ...excludeIdsExpression(excludeIds)];
1149
- if (isFeatured) expressions = [...expressions, ...featuredResultsExpression(featuredResults)];
1150
- if (!isFeatured || featuredResults && !featuredResults.contentTypeId) expressions = [...expressions, ...filterExpressions(filters), ...contentTypeIdExpression(contentTypeIds, webpageTemplates, assetTypes)];
1151
- const query = new contensisCoreApi.Query(...expressions);
1152
- if (!searchTerm) query.orderBy = orderByExpression(orderBy);
1153
- if (dynamicOrderBy && dynamicOrderBy.length) query.orderBy = orderByExpression(dynamicOrderBy);
1154
-
1155
- if (fields && fields.length > 0 && !isFeatured) {
1156
- query.fields = fields;
1157
- }
1158
-
1159
- query.pageIndex = isFeatured ? 0 : pageIndex;
1160
- query.pageSize = isFeatured && typeof featuredResults.count === 'number' ? featuredResults.count : pageSize;
1161
- return query;
1162
- };
1163
-
1164
- var queries = /*#__PURE__*/Object.freeze({
1165
- __proto__: null,
1166
- filterQuery: filterQuery,
1167
- searchQuery: searchQuery
1168
- });
1169
-
1170
- const searchUriTemplate = {
1171
- path: ({
1172
- state,
1173
- facet,
1174
- pageIndex
1175
- }) => {
1176
- const currentFacet = getSearchContext(state) !== Context$1.listings && (facet || getCurrentFacet(state));
1177
- const currentPath = selectCurrentPath(state) || '/search';
1178
- const newPath = currentFacet ? `${currentPath}/${currentFacet}` : currentPath;
1179
- if (pageIndex) return `${newPath}/${pageIndex + 1}`;
1180
- return newPath;
1181
- },
1182
- search: ({
1183
- state,
1184
- facet,
1185
- orderBy,
1186
- term
1187
- }) => {
1188
- const searchContext = getSearchContext(state); // Lose stateFilters and currentSearch if a new
1189
- // term is passed via an argument
1190
-
1191
- const stateFilters = term ? {} : Object.fromEntries(Object.entries(getSelectedFilters(state, facet, searchContext, 'js')).map(([key, f]) => [key, f === null || f === void 0 ? void 0 : f.join(',')]));
1192
- const currentSearch = !term && getImmutableOrJS(state, ['routing', 'location', 'search']);
1193
- const currentQs = removeEmptyAttributes(queryString__default["default"].parse(currentSearch));
1194
- if (orderBy) currentQs.orderBy = orderBy;
1195
- const searchTerm = getSearchTerm(state); // Use Immutable's merge to merge the stateFilters with any current Qs
1196
- // to build the new Qs.
1197
-
1198
- const mergedSearch = removeEmptyAttributes({ ...merge__default["default"](currentQs, stateFilters),
1199
- term: searchTerm
1200
- });
1201
- return queryString__default["default"].stringify(mergedSearch);
1202
- },
1203
- hash: {
1204
- $path: 'state',
1205
- $formatting: state => getImmutableOrJS(state, ['routing', 'location', 'hash'], '').replace('#', '')
1206
- }
1207
- };
1208
-
1209
- const mapStateToSearchUri = params => mapJson__default["default"](params, searchUriTemplate);
1210
-
1211
- const mapEntriesToSearchResults = ({
1212
- mappers,
1213
- mapper,
1214
- context,
1215
- facet
1216
- }, items, state) => {
1217
- const mapperFunc = mapper || mappers && mappers.results;
1218
- return items && typeof mapperFunc === 'function' ? mapperFunc(items, facet, context, state) : [];
1219
- };
1220
-
1221
- const facetTemplate = {
1222
- type: () => SET_SEARCH_ENTRIES,
1223
- context: 'action.context',
1224
- facet: 'action.facet',
1225
- mappers: 'action.mappers',
1226
- nextFacet: {
1227
- entries: {
1228
- isLoading: () => false,
1229
- isError: () => false
1230
- },
1231
- featuredEntries: {
1232
- isLoading: () => false,
1233
- isError: () => false
1234
- },
1235
- featuredResults: ({
1236
- action,
1237
- featuredResult,
1238
- state
1239
- }) => mapEntriesToSearchResults(action, getItemsFromResult(featuredResult), state),
1240
- queryDuration: 'result.duration',
1241
- pagingInfo: {
1242
- isLoading: () => false,
1243
- pageCount: {
1244
- $path: 'result.payload.pageCount',
1245
- $default: 0
1246
- },
1247
- totalCount: {
1248
- $path: 'result.payload.totalCount',
1249
- $default: 0
1250
- },
1251
- pageSize: {
1252
- $path: 'result.payload.pageSize',
1253
- $default: 0
1254
- },
1255
- pageIndex: 'pageIndex',
1256
- pagesLoaded: {
1257
- $path: 'action.queryParams',
1258
- $formatting: ({
1259
- pageIndex,
1260
- pagesLoaded
1261
- }) => {
1262
- const loaded = [...(pagesLoaded || [])];
1263
-
1264
- if (isNaN(loaded.find(l => l === pageIndex))) {
1265
- loaded.push(pageIndex);
1266
- }
1267
-
1268
- return loaded.sort((a, b) => a - b);
1269
- }
1270
- },
1271
- prevPageIndex: 'action.queryParams.prevPageIndex'
1272
- },
1273
- preloaded: {
1274
- $path: 'preload',
1275
- $default: false
1276
- },
1277
- results: ({
1278
- action,
1279
- pageIndex,
1280
- result,
1281
- prevResults,
1282
- state
1283
- }) => {
1284
- const {
1285
- loadMorePaging,
1286
- pagesLoaded,
1287
- prevPageIndex
1288
- } = action.queryParams;
1289
- const results = mapEntriesToSearchResults(action, getItemsFromResult(result), state);
1290
- if (!loadMorePaging) return results; // add a _pageIndex property to the returned results to help us later
1291
-
1292
- const nextResults = results.map((r, idx) => ({
1293
- _pageIndex: pageIndex,
1294
- _pagePosition: idx,
1295
- ...r
1296
- }));
1297
- const loadedPages = pagesLoaded || []; // if pageIndex is found in loadedPages, we have already loaded this page
1298
-
1299
- if (!isNaN(loadedPages.find(l => l === pageIndex))) return prevResults; // Determine where we put the results depending on if we
1300
- // are paging forwards, backwards, or doing a new search
1301
-
1302
- const firstResultSet = pageIndex > prevPageIndex ? prevResults || [] : nextResults;
1303
- const secondResultSet = pageIndex > prevPageIndex ? nextResults : prevResults || [];
1304
- const onlyResultSet = loadedPages.length === 0 ? nextResults : false;
1305
- return onlyResultSet || [...firstResultSet, ...secondResultSet];
1306
- }
1307
- },
1308
- preload: 'action.preload',
1309
- ogState: 'action.ogState',
1310
- debug: 'action.debug'
1311
- };
1312
- const filterTemplate = {
1313
- type: ({
1314
- type
1315
- }) => type || LOAD_FILTERS_COMPLETE,
1316
- context: 'context',
1317
- facetKey: 'facetKey',
1318
- filterKey: 'filterKey',
1319
- nextFilter: {
1320
- isLoading: () => false,
1321
- isError: ({
1322
- type
1323
- }) => type === LOAD_FILTERS_ERROR,
1324
- items: ({
1325
- payload,
1326
- selectedKeys,
1327
- mapper
1328
- }) => {
1329
- if (payload && (payload.items || payload.children)) {
1330
- const items = (payload.items || payload.children).map(item => {
1331
- var _item$sys;
1332
-
1333
- item.isSelected = selectedKeys === null || selectedKeys === void 0 ? void 0 : selectedKeys.includes((item === null || item === void 0 ? void 0 : (_item$sys = item.sys) === null || _item$sys === void 0 ? void 0 : _item$sys.id) || item.key);
1334
- return item;
1335
- });
1336
- return mapper(items);
1337
- }
1338
-
1339
- return [];
1340
- }
1341
- },
1342
- error: {
1343
- $path: 'error',
1344
- $disable: e => !e
1345
- }
1346
- };
1347
-
1348
- const filterExpressionMapper = {
1349
- // Expression type: so we can identify how to build the query
1350
- expressionType: ({
1351
- filter
1352
- }) => filter.contentTypeId ? FilterExpressionTypes.contentType : FilterExpressionTypes.field,
1353
- // Key: so we can target the query to a specific field
1354
- key: 'filter.fieldId',
1355
- // Value: so we can filter a specific field by an array of values
1356
- // e.g. taxonomy key or contentTypeId array
1357
- value: 'selectedValue',
1358
- operator: 'filter.fieldOperator'
1359
- };
1360
-
1361
- const mapFilterToFilterExpression = filter => mapJson__default["default"](filter, filterExpressionMapper);
1362
-
1363
- const mapFiltersToFilterExpression = (filters, selectedFilters) => {
1364
- if (!selectedFilters || Object.keys(selectedFilters).length === 0) return [];
1365
- const filterExpressions = []; // Iterate through the keys in selectedFilters and locate
1366
- // the items that are selected and queryable
1367
-
1368
- Object.entries(selectedFilters).map(([fkey, selectedValue]) => {
1369
- const filter = filters[fkey];
1370
-
1371
- if (selectedValue && filter) {
1372
- const selectedItems = filter.items && filter.items.filter(itm => itm.isSelected) || []; // Where we have a value for a selectedFilter
1373
- // and a filter is found for the current key
1374
- // map the filter to a filterExpression object
1375
-
1376
- const expr = mapFilterToFilterExpression({
1377
- filter,
1378
- selectedItems,
1379
- selectedValue
1380
- });
1381
- filterExpressions.push(expr);
1382
- }
1383
- });
1384
- return filterExpressions;
1385
- };
1386
-
1387
- const queryParamsTemplate = {
1388
- assetTypes: root => getQueryParameter(root, 'assetTypes', []),
1389
- contentTypeIds: root => getQueryParameter(root, 'contentTypeIds', []),
1390
- customWhere: root => getQueryParameter(root, 'customWhere', []),
1391
- dynamicOrderBy: root => getQueryParameter(root, 'dynamicOrderBy', []),
1392
- env: ({
1393
- state,
1394
- facet,
1395
- context
1396
- }) => getCustomEnv(state, facet, context),
1397
- excludeIds: ({
1398
- action: {
1399
- excludeIds
1400
- }
1401
- }) => {
1402
- // Exclude current route entry id from minilist searches or any supplied ids
1403
- if (excludeIds) return Array.isArray(excludeIds) ? excludeIds : excludeIds.split(',').map(id => id.trim());
1404
- return null;
1405
- },
1406
- featuredResults: root => getQueryParameter(root, 'featuredResults', null),
1407
- fields: root => getQueryParameter(root, 'fields', []),
1408
- filters: ({
1409
- state,
1410
- facet,
1411
- context
1412
- }) => {
1413
- const stateFilters = getFilters(state, facet, context, 'js');
1414
- const selectedFilters = getSelectedFilters(state, facet, context, 'js'); // Use another mapping function to map the filter parameters for the query
1415
-
1416
- const filterParams = mapFiltersToFilterExpression(stateFilters, selectedFilters);
1417
- return filterParams;
1418
- },
1419
- includeInSearchFields: root => getQueryParameter(root, 'includeInSearch', []),
1420
- internalPageIndex: ({
1421
- action,
1422
- state
1423
- }) => getPageIndex(state, '', action.context),
1424
- internalPaging: root => getQueryParameter(root, 'internalPaging', false),
1425
- languages: ({
1426
- action
1427
- }) => action.defaultLang ? [action.defaultLang] : [],
1428
- linkDepth: root => getQueryParameter(root, 'linkDepth', 0),
1429
- loadMorePaging: root => getQueryParameter(root, 'loadMorePaging', false),
1430
- orderBy: root => getQueryParameter(root, 'orderBy', []),
1431
- pageIndex: root => {
1432
- const {
1433
- action,
1434
- state
1435
- } = root;
1436
- if (getQueryParameter(root, 'internalPaging', false)) return 0;
1437
- if (action.type === UPDATE_PAGE_INDEX) return action.params.pageIndex;
1438
- return !action.preload ? getPageIndex(state, '', action.context) : 0;
1439
- },
1440
- pageSize: root => getQueryParameter(root, 'pageSize'),
1441
- pagesLoaded: ({
1442
- state,
1443
- facet,
1444
- context
1445
- }) => getPagesLoaded(state, facet, context),
1446
- prevPageIndex: ({
1447
- state,
1448
- facet,
1449
- context
1450
- }) => getPrevPageIndex(state, facet, context),
1451
- projectId: ({
1452
- state,
1453
- facet,
1454
- context
1455
- }) => {
1456
- var _getFacet;
1457
-
1458
- return (_getFacet = getFacet(state, facet, context)) === null || _getFacet === void 0 ? void 0 : _getFacet.projectId;
1459
- },
1460
- searchTerm: root => root.context !== Context$1.minilist || getQueryParameter(root, 'useSearchTerm', false) ? getSearchTerm(root.state) : '',
1461
- selectedFilters: ({
1462
- state,
1463
- facet,
1464
- context
1465
- }) => Object.fromEntries(Object.entries(getSelectedFilters(state, facet, context, 'js')).map(([key, f]) => [key, f === null || f === void 0 ? void 0 : f.join(',')])),
1466
- versionStatus: ({
144
+ const {
145
+ getCurrent: getCurrent$1,
146
+ getCurrentTab,
147
+ getFacet,
148
+ getFacetsTotalCount,
149
+ getFacetTitles,
150
+ getFeaturedResults: getFeaturedResults$1,
151
+ getIsLoading: getIsLoading$1,
152
+ getPageIndex: getPageIndex$1,
153
+ getPageIsLoading: getPageIsLoading$1,
154
+ getQueryParameter: getQueryParameter$1,
155
+ getRenderableFilters: getRenderableFilters$1,
156
+ getSearchTerm: getSearchTerm$1,
157
+ getSearchTotalCount,
158
+ getTabFacets,
159
+ getTabsAndFacets,
160
+ getTotalCount
161
+ } = sagas.selectFacets;
162
+
163
+ const makeSelectFacetsProps = () => reselect.createSelector(state => state, (_, mappers) => mappers, (state, mappers) => ({
164
+ currentFacet: getCurrent$1(state),
165
+ currentPageIndex: getPageIndex$1(state),
166
+ currentTabIndex: getCurrentTab(state),
167
+ facet: getFacet(state),
168
+ facetTitles: getFacetTitles(state),
169
+ facets: getTabFacets(state),
170
+ facetsTotalCount: getFacetsTotalCount(state),
171
+ featured: getFeaturedResults$1(state),
172
+ filters: getRenderableFilters$1(state),
173
+ isLoading: getIsLoading$1(state),
174
+ pageIsLoading: getPageIsLoading$1(state),
175
+ paging: sagas.getPaging(state, '', sagas.Context.facets, 'js'),
176
+ results: sagas.getResults(state, '', sagas.Context.facets, 'js'),
177
+ resultsInfo: mappers && typeof mappers.resultsInfo === 'function' && mappers.resultsInfo(state),
178
+ searchTerm: getSearchTerm$1(state),
179
+ searchTotalCount: getSearchTotalCount(state),
180
+ selectedFilters: sagas.getSelectedFilters(state, '', sagas.Context.facets, 'js'),
181
+ sortOrder: getQueryParameter$1({
1467
182
  state
1468
- }) => selectVersionStatus(state),
1469
- weightedSearchFields: root => {
1470
- const wsf = getQueryParameter(root, 'weightedSearchFields', []);
1471
- const deduped = wsf.filter((v, i, a) => a.findIndex(t => t.fieldId === v.fieldId) === i);
1472
- return deduped; // return wsf;
1473
- },
1474
- webpageTemplates: root => getQueryParameter(root, 'webpageTemplates', [])
1475
- };
1476
-
1477
- const mapStateToQueryParams = sourceJson => mapJson__default["default"](sourceJson, queryParamsTemplate);
183
+ }, 'dynamicOrderBy', []),
184
+ tabsAndFacets: getTabsAndFacets(state),
185
+ totalCount: getTotalCount(state)
186
+ }));
1478
187
 
1479
- /**
1480
- * 1, Generates all the parameters required to run the search query.
1481
- * 2, Tells us if we should run the search.
1482
- * @param {object} action
1483
- * @param {AppState} state
1484
- * @returns [queryParams, runSearch]
1485
- */
1486
- const generateQueryParams = (action, state) => {
188
+ const useFacets = ({
189
+ mappers
190
+ } = {
191
+ id: ''
192
+ }) => {
193
+ const dispatch = reactRedux.useDispatch();
194
+ const m = mappers || defaultMappers;
195
+ const selectListingProps = React.useMemo(makeSelectFacetsProps, [m]);
196
+ const dispatchProps = {
197
+ clearFilters: filterKey => dispatch(sagas.withMappers(sagas.clearFilters(filterKey), m)),
198
+ updateCurrentFacet: facet => dispatch(sagas.withMappers(sagas.updateCurrentFacet(facet), m)),
199
+ updateCurrentTab: id => sagas.withMappers(sagas.updateCurrentTab(id), m),
200
+ updatePageIndex: (pageIndex, scrollYPos) => dispatch(sagas.withMappers(sagas.updatePageIndex(pageIndex, scrollYPos), m)),
201
+ updateSearchTerm: term => dispatch(sagas.withMappers(sagas.updateSearchTerm(term), m)),
202
+ updateSelectedFilters: (filter, key, isUnknownItem = false, scrollYPos) => dispatch(sagas.withMappers(sagas.updateSelectedFilters(filter, key, isUnknownItem, scrollYPos), m)),
203
+ updateSortOrder: orderBy => dispatch(sagas.withMappers(sagas.updateSortOrder(orderBy), m))
204
+ };
1487
205
  const {
1488
- context,
1489
- facet
1490
- } = action; // Map parameters using state and some additional
1491
- // inputs from the action
1492
-
1493
- const queryParams = mapStateToQueryParams({
1494
- context,
206
+ currentFacet,
207
+ currentPageIndex,
208
+ currentTabIndex,
1495
209
  facet,
1496
- action,
1497
- state
1498
- });
1499
- return [queryParams, runSearch(action, state, queryParams)];
1500
- };
1501
- /**
1502
- * Checks if we have already loaded everything we're asking for and tells us to run the search or not
1503
- * @param action
1504
- * @param state
1505
- */
1506
-
1507
- const runSearch = (action, state, queryParams) => {
1508
- const {
1509
- context,
1510
- defaultLang,
210
+ facets,
211
+ facetsTotalCount,
212
+ facetTitles,
213
+ featured,
214
+ filters,
215
+ isLoading,
216
+ paging,
217
+ pageIsLoading,
218
+ results,
219
+ resultsInfo,
220
+ searchTerm,
221
+ searchTotalCount,
222
+ selectedFilters,
223
+ sortOrder,
224
+ tabsAndFacets,
225
+ totalCount
226
+ } = reactRedux.useSelector(state => selectListingProps(state, m));
227
+ return {
228
+ currentFacet,
229
+ currentPageIndex,
230
+ currentTabIndex,
1511
231
  facet,
1512
- ogState = state,
1513
- preload,
1514
- ssr
1515
- } = action;
1516
- let willRun = false;
1517
- const facetIsLoaded = defaultLang ? false : getIsLoaded(state, context, facet);
1518
- const stateParams = { ...getQueryParams(ogState, facet, context)
232
+ facets,
233
+ facetsTotalCount,
234
+ facetTitles,
235
+ featured,
236
+ filters,
237
+ isLoading,
238
+ paging,
239
+ pageIsLoading,
240
+ results,
241
+ resultsInfo,
242
+ searchTerm,
243
+ searchTotalCount,
244
+ selectedFilters,
245
+ sortOrder,
246
+ tabsAndFacets,
247
+ totalCount,
248
+ ...dispatchProps
1519
249
  };
1520
- stateParams.pageIndex = getPageIndex(ogState, facet, context);
1521
- stateParams.searchTerm = getSearchTerm(ogState);
1522
-
1523
- if (context === Context$1.facets && ssr || // context === Context.minilist ||
1524
- preload || !facetIsLoaded || filterParamsChanged(action) || defaultLang) {
1525
- willRun = true;
1526
- } else {
1527
- // Don't execute the search if the inbound query params
1528
- // are the same as what we already have in state
1529
- Object.entries(stateParams).forEach(([param, value]) => {
1530
- const queryParam = queryParams[param];
1531
-
1532
- if (JSON.stringify(value) !== JSON.stringify(queryParam)) {
1533
- willRun = true;
1534
- }
1535
- });
1536
- }
1537
-
1538
- const internalPaging = getIsInternalPaging(ogState, facet, context);
1539
-
1540
- if (internalPaging && facetIsLoaded) {
1541
- willRun = false;
1542
- }
1543
-
1544
- return willRun;
1545
- };
1546
- /**
1547
- * This will tell us if filter parameters have been
1548
- * changed by some external event such as a route change
1549
- * @param action
1550
- * @returns true or false
1551
- */
1552
-
1553
- const filterParamsChanged = (action, state) => {
1554
- const {
1555
- context,
1556
- facet,
1557
- params,
1558
- ogState = state
1559
- } = action;
1560
- const selectedFilters = getSelectedFilters(ogState, facet, context, 'js');
1561
- const paramsChanged = Object.entries(selectedFilters).map(([filterKey, selectedValues]) => {
1562
- const inboundValues = params && params[filterKey] && params[filterKey].split(',') || [];
1563
- if (!areArraysEqualSets(selectedValues, inboundValues)) return true;
1564
- });
1565
- return paramsChanged.filter(f => f === true).length > 0;
1566
- };
1567
- /* eslint-disable no-console */
1568
-
1569
- const debugExecuteSearch = (action, state) => {
1570
- const [queryParams, runSearch] = generateQueryParams(action, state);
1571
- console.log('runSearch', runSearch, 'action', action, 'filterParamsChanged', filterParamsChanged(action, state), 'getIsLoaded(state, context, facet)', getIsLoaded(state, action.context, action.facet));
1572
- const stateParams = getQueryParams(action.ogState || state, action.facet, action.context);
1573
- stateParams.pageIndex = getPageIndex(action.ogState || state, action.facet, action.context);
1574
- stateParams.searchTerm = getSearchTerm(action.ogState || state);
1575
- console.log(stateParams, queryParams);
1576
- console.log('getSelectedFilters', getSelectedFilters(action.ogState || state, action.facet, action.context, 'js'), 'params', action.params);
1577
- };
1578
-
1579
- // Base mapping, fields that are the same across all mappings
1580
- // to save repeating these elements in every mapper, spread this
1581
- // into your discrete mappings
1582
-
1583
- const base = {
1584
- contentTypeId: Fields.sys.contentTypeId,
1585
- title: 'entryTitle',
1586
- key: 'sys.id',
1587
- path: 'sys.slug',
1588
- isSelected: 'isSelected'
1589
- };
1590
-
1591
- const mapEntriesToFilterItems = entries => {
1592
- if (!entries) return [];
1593
- return entries.map(entry => {
1594
- const template = base;
1595
-
1596
- if (template) {
1597
- return mapJson__default["default"](entry, template);
1598
- }
1599
-
1600
- return entry;
1601
- });
1602
250
  };
1603
251
 
1604
- const searchSagas = [effects.takeEvery(CLEAR_FILTERS, clearFilters), effects.takeEvery(DO_SEARCH, doSearch), effects.takeEvery(SET_ROUTE_FILTERS, loadFilters), effects.takeEvery(SET_SEARCH_ENTRIES, preloadOtherFacets), effects.takeEvery(UPDATE_CURRENT_FACET, updateCurrentFacet), effects.takeEvery(UPDATE_CURRENT_TAB, updateCurrentTab), effects.takeEvery(UPDATE_PAGE_INDEX, updatePageIndex), effects.takeEvery(UPDATE_SEARCH_TERM, updateSearchTerm), effects.takeEvery(UPDATE_SORT_ORDER, updateSortOrder), effects.takeEvery(UPDATE_SELECTED_FILTERS, applySearchFilter)];
1605
-
1606
- const toJS = obj => obj && 'toJS' in obj && typeof obj.toJS === 'function' ? obj.toJS() : obj;
1607
-
1608
- function* setRouteFilters(action) {
1609
- const {
1610
- mappers,
1611
- params,
1612
- listingType,
1613
- defaultLang,
1614
- debug
1615
- } = action;
1616
- const context = listingType ? Context$1.listings : Context$1.facets;
1617
- const state = toJS(yield effects.select());
1618
- const ssr = getIsSsr(state); // Get current facet from params or state
1619
-
1620
- let currentFacet = params && params.facet || listingType; // Pick the default facet from initialState
1621
-
1622
- if (!currentFacet) {
1623
- var _Object$keys;
1624
-
1625
- const tabs = getSearchTabs(state, 'js');
1626
- currentFacet = (tabs === null || tabs === void 0 ? void 0 : tabs[0].defaultFacet) || ((_Object$keys = Object.keys(getFacets(state, 'js'))) === null || _Object$keys === void 0 ? void 0 : _Object$keys[0]) || '';
1627
- }
1628
-
1629
- const nextAction = {
1630
- type: SET_ROUTE_FILTERS,
1631
- context,
1632
- facet: currentFacet,
1633
- mappers,
1634
- params,
1635
- defaultLang,
1636
- ssr,
1637
- debug
1638
- };
1639
- yield effects.put(nextAction); // Using call instead of triggering from the put
1640
- // to allow this exported saga to continue during SSR
1641
-
1642
- yield effects.call(ensureSearch, { ...nextAction,
1643
- ogState: state
1644
- });
1645
- }
1646
- function* doSearch(action) {
1647
- const state = toJS(yield effects.select());
1648
-
1649
- if (action.config) {
1650
- // If the action contains a config object, we can add this to the
1651
- // state at runtime
1652
- yield effects.put({ ...action,
1653
- type: APPLY_CONFIG
1654
- });
1655
- }
252
+ const {
253
+ getCurrent,
254
+ getFeaturedResults,
255
+ getIsLoading,
256
+ getListing,
257
+ getPageIndex,
258
+ getPageIsLoading,
259
+ getQueryParameter,
260
+ getRenderableFilters,
261
+ getSearchTerm
262
+ } = sagas.selectListing;
263
+
264
+ const makeSelectListingProps = () => reselect.createSelector(state => state, (_, mappers) => mappers, (state, mappers) => ({
265
+ currentListing: getCurrent(state),
266
+ currentPageIndex: getPageIndex(state),
267
+ listing: getListing(state),
268
+ featured: getFeaturedResults(state),
269
+ filters: getRenderableFilters(state),
270
+ isLoading: getIsLoading(state),
271
+ pageIsLoading: getPageIsLoading(state),
272
+ paging: sagas.getPaging(state, '', sagas.Context.listings, 'js'),
273
+ results: sagas.getResults(state, '', sagas.Context.listings, 'js'),
274
+ resultsInfo: mappers && typeof mappers.resultsInfo === 'function' && mappers.resultsInfo(state),
275
+ searchTerm: getSearchTerm(state),
276
+ selectedFilters: sagas.getSelectedFilters(state, '', sagas.Context.listings, 'js'),
277
+ sortOrder: getQueryParameter({
278
+ state
279
+ }, 'dynamicOrderBy', [])
280
+ }));
1656
281
 
1657
- const nextAction = { ...action,
1658
- type: SET_SEARCH_FILTERS,
1659
- ssr: getIsSsr(state)
282
+ const useListing = ({
283
+ mappers
284
+ } = {
285
+ id: ''
286
+ }) => {
287
+ const dispatch = reactRedux.useDispatch();
288
+ const m = mappers || defaultMappers;
289
+ const selectListingProps = React.useMemo(makeSelectListingProps, [m]);
290
+ const dispatchProps = {
291
+ clearFilters: filterKey => dispatch(sagas.withMappers(sagas.clearFilters(filterKey), m)),
292
+ updateCurrentFacet: facet => dispatch(sagas.withMappers(sagas.updateCurrentFacet(facet), m)),
293
+ updatePageIndex: (pageIndex, scrollYPos) => dispatch(sagas.withMappers(sagas.updatePageIndex(pageIndex, scrollYPos), m)),
294
+ updateSearchTerm: term => dispatch(sagas.withMappers(sagas.updateSearchTerm(term), m)),
295
+ updateSelectedFilters: (filter, key, isUnknownItem = false, scrollYPos) => dispatch(sagas.withMappers(sagas.updateSelectedFilters(filter, key, isUnknownItem, scrollYPos), m)),
296
+ updateSortOrder: orderBy => dispatch(sagas.withMappers(sagas.updateSortOrder(orderBy), m))
1660
297
  };
1661
- yield effects.put(nextAction);
1662
- yield effects.call(ensureSearch, { ...nextAction,
1663
- ogState: state
1664
- });
1665
- }
1666
-
1667
- function* loadFilters(action) {
1668
- const {
1669
- facet: facetKey,
1670
- context,
1671
- mappers = {}
1672
- } = action;
1673
- const filtersToLoad = yield effects.select(getFiltersToLoad, facetKey, context, 'js');
1674
-
1675
- if (filtersToLoad.length > 0) {
1676
- yield effects.put({
1677
- type: LOAD_FILTERS,
1678
- filtersToLoad,
1679
- facetKey,
1680
- context
1681
- });
1682
- const selectedKeys = yield effects.select(getSelectedFilters, facetKey, context, 'js');
1683
- const facet = yield effects.select(getFacet, facetKey, context, 'js');
1684
- const filters = facet.filters || {};
1685
- const projectId = facet.projectId;
1686
- const filtersToLoadSagas = filters && filtersToLoad.map((filterKey = '') => {
1687
- return effects.call(loadFilter, {
1688
- facetKey,
1689
- filterKey,
1690
- filter: filters[filterKey],
1691
- projectId,
1692
- selectedKeys: selectedKeys[filterKey],
1693
- context,
1694
- mapper: 'filterItems' in mappers && mappers.filterItems || mapEntriesToFilterItems
1695
- });
1696
- });
1697
- if (filtersToLoadSagas) yield effects.all(filtersToLoadSagas);
1698
- }
1699
- }
1700
-
1701
- function* loadFilter(action) {
1702
- const {
1703
- facetKey,
1704
- filterKey,
1705
- filter,
1706
- projectId,
1707
- selectedKeys,
1708
- context,
1709
- mapper
1710
- } = action;
1711
298
  const {
1712
- contentTypeId,
1713
- customWhere,
1714
- path
1715
- } = filter;
1716
- const createStateFrom = {
1717
- type: LOAD_FILTERS_COMPLETE,
1718
- context,
1719
- error: undefined,
1720
- facetKey,
1721
- filterKey,
1722
- payload: {},
1723
- selectedKeys,
1724
- mapper
299
+ currentListing,
300
+ currentPageIndex,
301
+ featured,
302
+ filters,
303
+ isLoading,
304
+ listing,
305
+ paging,
306
+ pageIsLoading,
307
+ results,
308
+ resultsInfo,
309
+ searchTerm,
310
+ selectedFilters,
311
+ sortOrder
312
+ } = reactRedux.useSelector(state => selectListingProps(state, m));
313
+ return {
314
+ currentListing,
315
+ currentPageIndex,
316
+ featured,
317
+ filters,
318
+ isLoading,
319
+ listing,
320
+ pageIsLoading,
321
+ paging,
322
+ results,
323
+ resultsInfo,
324
+ searchTerm,
325
+ selectedFilters,
326
+ sortOrder,
327
+ title: listing.title,
328
+ ...dispatchProps
1725
329
  };
1726
-
1727
- try {
1728
- if (contentTypeId) {
1729
- const versionStatus = yield effects.select(selectVersionStatus);
1730
- const query = filterQuery(Array.isArray(contentTypeId) ? contentTypeId : [contentTypeId], versionStatus, customWhere);
1731
- const payload = yield cachedSearch.search(query, 0, projectId);
1732
- if (!payload) throw new Error('No payload returned by search');
1733
- if (payload.type === 'error') throw payload;
1734
- createStateFrom.payload = payload;
1735
- }
1736
-
1737
- if (path) {
1738
- const payload = yield cachedSearch.getTaxonomyNodeByPath(path, projectId);
1739
- if (!payload) throw new Error(`No payload returned for taxonomy path: '${path}'`);
1740
- if (payload.type === 'error') throw payload;
1741
- createStateFrom.payload = payload;
1742
- }
1743
- } catch (error) {
1744
- createStateFrom.type = LOAD_FILTERS_ERROR;
1745
- createStateFrom.error = error;
1746
- }
1747
-
1748
- const nextAction = mapJson__default["default"](createStateFrom, filterTemplate);
1749
- yield effects.put(nextAction);
1750
- }
1751
-
1752
- function* ensureSearch(action) {
1753
- const {
1754
- context,
1755
- facet,
1756
- debug
1757
- } = action;
1758
-
1759
- try {
1760
- const state = yield effects.select();
1761
- const nextAction = { ...action,
1762
- ogState: action.ogState || state
1763
- };
1764
- const [queryParams, runSearch] = generateQueryParams(nextAction, state);
1765
- if (debug && (debug === true || debug.executeSearch)) debugExecuteSearch(nextAction, state);
1766
-
1767
- if (runSearch) {
1768
- yield effects.put({
1769
- type: EXECUTE_SEARCH,
1770
- facet,
1771
- context
1772
- });
1773
- yield effects.call(executeSearch, { ...nextAction,
1774
- context,
1775
- facet,
1776
- queryParams,
1777
- debug
1778
- });
1779
- }
1780
- } catch (error) {
1781
- // eslint-disable-next-line import/namespace
1782
- log__namespace.error(...['Error running search saga:', error, error.stack]);
1783
- }
1784
- }
1785
-
1786
- function* executeSearch(action) {
1787
- const {
1788
- context,
1789
- facet,
1790
- queryParams,
1791
- mappers
1792
- } = action;
1793
-
1794
- try {
1795
- const state = yield effects.select();
1796
- let result = {};
1797
- let featuredResult;
1798
- let featuredQuery;
1799
- const customApi = getCustomApi(state, facet, context, 'js');
1800
-
1801
- if (customApi) {
1802
- const apiParams = typeof mappers === 'object' && typeof mappers.customApi === 'function' && mappers.customApi(queryParams) || {};
1803
- result.payload = yield callCustomApi(customApi, apiParams);
1804
- result.duration = 1;
1805
- } else {
1806
- if (queryParams.featuredResults) {
1807
- featuredQuery = searchQuery(queryParams, true);
1808
- featuredResult = yield timedSearch(featuredQuery, queryParams.linkDepth, queryParams.projectId, queryParams.env); // eslint-disable-next-line require-atomic-updates
1809
-
1810
- queryParams.excludeIds = getItemsFromResult(featuredResult).map(fi => {
1811
- var _fi$sys;
1812
-
1813
- return fi === null || fi === void 0 ? void 0 : (_fi$sys = fi.sys) === null || _fi$sys === void 0 ? void 0 : _fi$sys.id;
1814
- }).filter(fi => typeof fi === 'string');
1815
- }
1816
-
1817
- const query = searchQuery(queryParams);
1818
- result = yield timedSearch(query, queryParams.linkDepth, queryParams.projectId, queryParams.env);
1819
- }
1820
-
1821
- const createStateFrom = {
1822
- action,
1823
- featuredResult,
1824
- pageIndex: queryParams.internalPaging && queryParams.internalPageIndex || queryParams.pageIndex,
1825
- prevResults: getResults(state, facet, action.context, 'js'),
1826
- result,
1827
- state
1828
- };
1829
- const nextAction = mapJson__default["default"](createStateFrom, facetTemplate);
1830
- yield effects.put(nextAction);
1831
- } catch (error) {
1832
- // eslint-disable-next-line import/namespace
1833
- log__namespace.error(...['Error running search saga:', error, error.stack]);
1834
- }
1835
- }
1836
-
1837
- function* preloadOtherFacets(action) {
1838
- const {
1839
- preload,
1840
- context,
1841
- facet,
1842
- debug
1843
- } = action;
1844
- const state = yield effects.select();
1845
- const currentFacet = getCurrentFacet(state);
1846
-
1847
- if (!preload && facet === currentFacet && context !== Context$1.listings) {
1848
- const allFacets = getFacets(state, 'js');
1849
- const otherFacets = Object.keys(allFacets).filter(f => f !== currentFacet);
1850
- yield effects.all(otherFacets.map((preloadFacet = '') => {
1851
- const preloadAction = { ...action,
1852
- facet: preloadFacet,
1853
- preload: true
1854
- };
1855
- const [queryParams, runSearch] = generateQueryParams(preloadAction, state);
1856
- if (debug && (debug === true || debug.preloadOtherFacets)) debugExecuteSearch(preloadAction, state);
1857
- return runSearch && effects.call(executeSearch, { ...action,
1858
- type: EXECUTE_SEARCH_PRELOAD,
1859
- preload: true,
1860
- facet: preloadFacet,
1861
- queryParams
1862
- });
1863
- }));
1864
- }
1865
- }
1866
-
1867
- function* updateCurrentTab(action) {
1868
- const {
1869
- id,
1870
- mappers
1871
- } = action;
1872
- const state = yield effects.select();
1873
- const facets = getFacets(state, 'js');
1874
- const tabs = getSearchTabs(state, 'js');
1875
- let nextFacet = tabs === null || tabs === void 0 ? void 0 : tabs[id].currentFacet;
1876
-
1877
- if (!nextFacet) {
1878
- Object.entries(facets).map(([facetName, facet]) => {
1879
- if (facet.tabId === id && (tabs === null || tabs === void 0 ? void 0 : tabs[id].defaultFacet) === facetName) nextFacet = facetName;
1880
- });
1881
- } // If the next Tab does not have a defaultFacet,
1882
- // take the first facet for that tab
1883
-
1884
-
1885
- if (!nextFacet) nextFacet = Object.entries(facets).filter(([, f]) => f.tabId === id)[0][0];
1886
- yield effects.put(withMappers(updateCurrentFacet$1(nextFacet), mappers));
1887
- }
1888
-
1889
- function* clearFilters(action) {
1890
- const {
1891
- mappers
1892
- } = action;
1893
- const uri = yield buildUri({}, mappers);
1894
- yield effects.put(navigate(uri));
1895
- }
1896
-
1897
- function* updateCurrentFacet(action) {
1898
- const {
1899
- facet,
1900
- mappers
1901
- } = action;
1902
- const pageIndex = yield effects.select(getPageIndex, facet);
1903
- const uri = yield buildUri({
1904
- facet,
1905
- pageIndex
1906
- }, mappers);
1907
- yield effects.put(navigate(uri));
1908
- }
1909
-
1910
- function* updateSearchTerm(action) {
1911
- const {
1912
- term,
1913
- mappers
1914
- } = action;
1915
- const uri = yield buildUri({
1916
- term
1917
- }, mappers);
1918
- yield effects.put(navigate(uri));
1919
- }
1920
-
1921
- function* updateSortOrder(action) {
1922
- const {
1923
- orderBy,
1924
- facet,
1925
- mappers
1926
- } = action;
1927
- const uri = yield buildUri({
1928
- orderBy,
1929
- facet
1930
- }, mappers);
1931
- yield effects.put(navigate(uri));
1932
- }
1933
-
1934
- function* updatePageIndex(action) {
1935
- const {
1936
- pageIndex,
1937
- mappers
1938
- } = action;
1939
- const uri = yield buildUri({
1940
- pageIndex
1941
- }, mappers);
1942
- yield effects.put(navigate(uri));
1943
- }
1944
-
1945
- function* applySearchFilter(action) {
1946
- const {
1947
- mappers
1948
- } = action;
1949
- const uri = yield buildUri({}, mappers);
1950
- yield effects.put(navigate(uri));
1951
- }
1952
-
1953
- function* buildUri({
1954
- facet,
1955
- orderBy,
1956
- pageIndex = 0,
1957
- term
1958
- }, mappers) {
1959
- const state = yield effects.select();
1960
- const mapUri = mappers && mappers.navigate || mapStateToSearchUri;
1961
- const uri = mapUri({
1962
- state,
1963
- facet,
1964
- orderBy,
1965
- pageIndex,
1966
- term
1967
- }); // return uri;
1968
-
1969
- return `${uri.path}${uri.search && `?${uri.search}` || ''}${uri.hash && `#${uri.hash}` || ''}`;
1970
- }
330
+ };
1971
331
 
1972
332
  const makeSelectMinilistProps = () => reselect.createSelector(state => state, (_, id) => id, (state, id) => ({
1973
- facet: getFacet(state, id, Context$1.minilist, 'js'),
1974
- filters: getFilters(state, id, Context$1.minilist, 'js'),
1975
- isLoading: getIsLoading(state, Context$1.minilist, id),
1976
- pagingInfo: getPaging(state, id, Context$1.minilist, 'js'),
1977
- results: getResults(state, id, Context$1.minilist, 'js'),
1978
- searchTerm: getSearchTerm(state)
333
+ facet: sagas.getFacet(state, id, sagas.Context.minilist, 'js'),
334
+ filters: sagas.getFilters(state, id, sagas.Context.minilist, 'js'),
335
+ isLoading: sagas.getIsLoading(state, sagas.Context.minilist, id),
336
+ pagingInfo: sagas.getPaging(state, id, sagas.Context.minilist, 'js'),
337
+ results: sagas.getResults(state, id, sagas.Context.minilist, 'js'),
338
+ searchTerm: sagas.getSearchTerm(state)
1979
339
  }));
1980
340
 
1981
341
  const useMinilist = ({
@@ -2009,10 +369,10 @@ const useMinilist = ({
2009
369
  // }));
2010
370
 
2011
371
  React.useEffect(() => {
2012
- if (id && (mapper || mappers && mappers.results)) {
2013
- dispatch(triggerSearch({
372
+ if (id && (mapper || mappers !== null && mappers !== void 0 && mappers.results)) {
373
+ dispatch(sagas.triggerSearch({
2014
374
  config,
2015
- context: Context$1.minilist,
375
+ context: sagas.Context.minilist,
2016
376
  defaultLang,
2017
377
  facet: id,
2018
378
  mapper,
@@ -2026,7 +386,7 @@ const useMinilist = ({
2026
386
  return {
2027
387
  filters,
2028
388
  isLoading,
2029
- pagingInfo,
389
+ paging: pagingInfo,
2030
390
  results,
2031
391
  searchTerm,
2032
392
  title: facet.title
@@ -2210,7 +570,10 @@ const generateFiltersState = ({
2210
570
  // the search results during SSR without needing to fetch the filters first
2211
571
 
2212
572
 
2213
- Object.entries(filterParams).map(([paramName = '', paramValue]) => typeof paramValue === 'string' && paramValue.split(',').map(pVal => filters = addFilterItem(filters, paramName, pVal)));
573
+ Object.entries(filterParams).map(([paramName = '', paramValue]) => {
574
+ if (typeof paramValue === 'string') return paramValue.split(',').map(pVal => filters = addFilterItem(filters, paramName, pVal));
575
+ if (typeof paramValue === 'boolean') filters = addFilterItem(filters, paramName, paramValue);
576
+ });
2214
577
  return Object.fromEntries(filters);
2215
578
  };
2216
579
 
@@ -2227,43 +590,46 @@ var reducers = (config => {
2227
590
  // Add facets from SearchConfig to initialState
2228
591
  const initState = { ...initialState,
2229
592
  tabs: config.tabs,
2230
- facets: generateSearchFacets(Context$1.facets, config),
2231
- listings: generateSearchFacets(Context$1.listings, config),
2232
- minilist: generateSearchFacets(Context$1.minilist, config)
593
+ facets: generateSearchFacets(sagas.Context.facets, config),
594
+ listings: generateSearchFacets(sagas.Context.listings, config),
595
+ minilist: generateSearchFacets(sagas.Context.minilist, config)
2233
596
  };
2234
597
  return immer.produce((state = initState, action) => {
2235
598
  const context = state.context;
2236
599
  const current = context !== 'listings' ? state.currentFacet : state.currentListing;
2237
600
 
2238
601
  switch (action.type) {
2239
- case APPLY_CONFIG:
602
+ case sagas.APPLY_CONFIG:
2240
603
  {
2241
604
  state = addConfigToState(state, action);
2242
- return;
605
+ return state;
2243
606
  }
2244
607
 
2245
- case CLEAR_FILTERS:
608
+ case sagas.CLEAR_FILTERS:
2246
609
  {
2247
610
  const currentFilters = state[context][current].filters;
2248
- state[context][current].filters = Object.fromEntries(Object.entries(currentFilters).map(([key, filter]) => {
2249
- const filterItems = filter.items || [];
2250
- filter.items = filterItems.map(item => ({ ...item,
2251
- isSelected: false
2252
- }));
2253
- return [key, filter];
611
+ state[context][current].filters = Object.fromEntries(Object.entries(currentFilters).map(([filterKey, filter]) => {
612
+ if (typeof action.filterKey === 'undefined' || action.filterKey === filterKey) {
613
+ const filterItems = filter.items || [];
614
+ filter.items = filterItems.map(item => ({ ...item,
615
+ isSelected: false
616
+ }));
617
+ }
618
+
619
+ return [filterKey, filter];
2254
620
  }));
2255
621
  state[context][current].queryDuration = 0;
2256
622
  state[context][current].pagingInfo.pagesLoaded = [];
2257
623
  return;
2258
624
  }
2259
625
 
2260
- case EXECUTE_SEARCH:
626
+ case sagas.EXECUTE_SEARCH:
2261
627
  {
2262
628
  state[action.context][action.facet].entries.isLoading = true;
2263
629
  return;
2264
630
  }
2265
631
 
2266
- case EXECUTE_SEARCH_ERROR:
632
+ case sagas.EXECUTE_SEARCH_ERROR:
2267
633
  {
2268
634
  state[action.context][action.facet].entries = { ...entries,
2269
635
  isError: true,
@@ -2272,7 +638,7 @@ var reducers = (config => {
2272
638
  return;
2273
639
  }
2274
640
 
2275
- case LOAD_FILTERS:
641
+ case sagas.LOAD_FILTERS:
2276
642
  {
2277
643
  const {
2278
644
  facetKey,
@@ -2294,8 +660,8 @@ var reducers = (config => {
2294
660
  return;
2295
661
  }
2296
662
 
2297
- case LOAD_FILTERS_ERROR:
2298
- case LOAD_FILTERS_COMPLETE:
663
+ case sagas.LOAD_FILTERS_ERROR:
664
+ case sagas.LOAD_FILTERS_COMPLETE:
2299
665
  {
2300
666
  const {
2301
667
  facetKey,
@@ -2319,7 +685,7 @@ var reducers = (config => {
2319
685
  return;
2320
686
  }
2321
687
 
2322
- case SET_ROUTE_FILTERS:
688
+ case sagas.SET_ROUTE_FILTERS:
2323
689
  {
2324
690
  const {
2325
691
  facet,
@@ -2351,12 +717,12 @@ var reducers = (config => {
2351
717
  resetCurrentFacet = state.config.isLoaded === true && !equals__default["default"](nextFilters, stateFacet.filters);
2352
718
  stateFacet = resetCurrentFacet ? resetFacet(stateFacet) : stateFacet;
2353
719
  stateFacet.filters = nextFilters;
2354
- stateFacet.queryParams.dynamicOrderBy = toArray(orderBy) || [];
720
+ stateFacet.queryParams.dynamicOrderBy = sagas.toArray(orderBy) || [];
2355
721
  return [facetName, stateFacet];
2356
722
  }));
2357
723
  state.context = context;
2358
724
  state[context] = nextFacets;
2359
- state[action.context === Context$1.facets ? 'currentFacet' : 'currentListing'] = facet;
725
+ state[action.context === sagas.Context.facets ? 'currentFacet' : 'currentListing'] = facet;
2360
726
  state.term = term;
2361
727
  state.tabs[tabId].currentFacet = facet;
2362
728
  state[context][facet].pagingInfo.pageIndex = Number(pageIndex) - 1 || (state[context][facet].queryParams.loadMorePaging ? state[context][facet].pagingInfo.pageIndex || 0 : 0);
@@ -2366,7 +732,7 @@ var reducers = (config => {
2366
732
  return;
2367
733
  }
2368
734
 
2369
- case SET_SEARCH_ENTRIES:
735
+ case sagas.SET_SEARCH_ENTRIES:
2370
736
  {
2371
737
  const thisContext = action.context || context;
2372
738
  const currentFacet = state[thisContext][action.facet];
@@ -2376,7 +742,7 @@ var reducers = (config => {
2376
742
  return;
2377
743
  }
2378
744
 
2379
- case SET_SEARCH_FILTERS:
745
+ case sagas.SET_SEARCH_FILTERS:
2380
746
  {
2381
747
  var _action$params;
2382
748
 
@@ -2389,15 +755,15 @@ var reducers = (config => {
2389
755
  isCurrentFacet: true
2390
756
  }, state);
2391
757
  const term = action === null || action === void 0 ? void 0 : (_action$params = action.params) === null || _action$params === void 0 ? void 0 : _action$params.term;
2392
- const useSearchTerm = state[action.context || Context$1.minilist][action.facet].queryParams.useSearchTerm || false;
2393
- state[action.context || Context$1.minilist][action.facet].filters = filters;
2394
- state[action.context || Context$1.minilist][action.facet].queryParams.excludeIds = action.excludeIds;
758
+ const useSearchTerm = state[action.context || sagas.Context.minilist][action.facet].queryParams.useSearchTerm || false;
759
+ state[action.context || sagas.Context.minilist][action.facet].filters = filters;
760
+ state[action.context || sagas.Context.minilist][action.facet].queryParams.excludeIds = action.excludeIds;
2395
761
  state.term = useSearchTerm ? term : state.term;
2396
762
  state.config.ssr = typeof window === 'undefined';
2397
763
  return;
2398
764
  }
2399
765
 
2400
- case UPDATE_PAGE_INDEX:
766
+ case sagas.UPDATE_PAGE_INDEX:
2401
767
  {
2402
768
  const {
2403
769
  pageIndex
@@ -2412,24 +778,33 @@ var reducers = (config => {
2412
778
  return;
2413
779
  }
2414
780
 
2415
- case UPDATE_SEARCH_TERM:
781
+ case sagas.UPDATE_SEARCH_TERM:
2416
782
  {
2417
783
  state.term = action.term;
2418
784
  state[context] = resetFacets(state, context);
2419
785
  return;
2420
786
  }
2421
787
 
2422
- case UPDATE_SELECTED_FILTERS:
788
+ case sagas.UPDATE_SELECTED_FILTERS:
2423
789
  {
2424
790
  const {
2425
791
  filter,
2426
- key
792
+ key,
793
+ isUnknownItem
2427
794
  } = action;
2428
795
  const isSingleSelect = state[context][current].filters[filter].isSingleSelect || false;
2429
796
  const isGrouped = state[context][current].filters[filter].isGrouped || false;
2430
797
  const currentItems = state[context][current].filters[filter].items;
2431
798
  if (isGrouped) state[context] = resetFacets(state, context);
2432
799
  state[context][current] = resetFacet(state[context][current]);
800
+
801
+ if (isUnknownItem && (currentItems === null || currentItems === void 0 ? void 0 : currentItems.findIndex(item => (item === null || item === void 0 ? void 0 : item.key) === key)) === -1) {
802
+ currentItems === null || currentItems === void 0 ? void 0 : currentItems.push({
803
+ key,
804
+ isSelected: false
805
+ });
806
+ }
807
+
2433
808
  state[context][current].filters[filter].items = currentItems === null || currentItems === void 0 ? void 0 : currentItems.map(item => {
2434
809
  if (item.key === key) {
2435
810
  return { ...item,
@@ -2445,7 +820,7 @@ var reducers = (config => {
2445
820
  return;
2446
821
  }
2447
822
 
2448
- case UPDATE_SORT_ORDER:
823
+ case sagas.UPDATE_SORT_ORDER:
2449
824
  {
2450
825
  const {
2451
826
  orderBy,
@@ -2453,7 +828,7 @@ var reducers = (config => {
2453
828
  } = action;
2454
829
  state[context] = resetFacets(state, context);
2455
830
  const currentFacet = facet || current;
2456
- state[context][currentFacet].queryParams.dynamicOrderBy = orderBy ? toArray(orderBy) || [] : [];
831
+ state[context][currentFacet].queryParams.dynamicOrderBy = orderBy ? sagas.toArray(orderBy) || [] : [];
2457
832
  return;
2458
833
  }
2459
834
 
@@ -2463,23 +838,29 @@ var reducers = (config => {
2463
838
  }, initState);
2464
839
  });
2465
840
 
2466
- // eslint-disable-next-line @typescript-eslint/naming-convention
2467
841
  const Context = {
2468
842
  facets: 'facets',
2469
843
  listings: 'listings',
2470
844
  minilist: 'minilist'
2471
845
  };
2472
846
 
847
+ exports.actions = sagas.actions;
848
+ exports.doSearch = sagas.doSearch;
849
+ exports.expressions = sagas.expressions;
850
+ exports.queries = sagas.queries;
851
+ exports.routeParams = sagas.routeParams;
852
+ exports.sagas = sagas.searchSagas;
853
+ exports.selectors = sagas.selectors;
854
+ exports.setRouteFilters = sagas.setRouteFilters;
855
+ exports.triggerListingSsr = sagas.triggerListingSsr;
856
+ exports.triggerMinilistSsr = sagas.triggerMinilistSsr;
857
+ exports.triggerSearchSsr = sagas.triggerSearchSsr;
858
+ exports.types = sagas.types;
2473
859
  exports.Context = Context;
2474
- exports.actions = actions;
2475
- exports.doSearch = doSearch;
2476
- exports.queries = queries;
2477
860
  exports.reducer = reducers;
2478
- exports.sagas = searchSagas;
2479
861
  exports.schema = schema;
2480
- exports.selectors = selectors;
2481
- exports.setRouteFilters = setRouteFilters;
2482
- exports.types = types;
862
+ exports.useFacets = useFacets;
863
+ exports.useListing = useListing;
2483
864
  exports.useMinilist = useMinilist;
2484
865
  exports.withListing = withListing;
2485
866
  exports.withSearch = withSearch;