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