@abcagency/hc-ui-components 1.6.5 → 1.6.7
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.
- package/dist/components/HireControlMap.js +43 -2
- package/dist/components/HireControlMap.js.map +1 -1
- package/dist/components/containers/accordions/filter-item-container.js +3 -1
- package/dist/components/containers/accordions/filter-item-container.js.map +1 -1
- package/dist/components/containers/filter/filter-item-container.js +29 -15
- package/dist/components/containers/filter/filter-item-container.js.map +1 -1
- package/dist/components/containers/list/item-list-container.js +1 -1
- package/dist/components/containers/list/item-list-container.js.map +1 -1
- package/dist/components/modules/accordions/filterItem.js +8 -3
- package/dist/components/modules/accordions/filterItem.js.map +1 -1
- package/dist/components/modules/filter/index.js +123 -19
- package/dist/components/modules/filter/index.js.map +1 -1
- package/dist/components/modules/filter/item.js +8 -3
- package/dist/components/modules/filter/item.js.map +1 -1
- package/dist/components/modules/filter/search.js +6 -1
- package/dist/components/modules/filter/search.js.map +1 -1
- package/dist/components/modules/list/list-item/list-item.js.map +1 -1
- package/dist/components/modules/maps/tabs.js +1 -1
- package/dist/components/modules/maps/tabs.js.map +1 -1
- package/dist/contexts/mapListContext.js +48 -3
- package/dist/contexts/mapListContext.js.map +1 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +51 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/util/filterUtil.d.ts +9 -3
- package/dist/util/algoliaSearchUtil.js.map +1 -1
- package/dist/util/filterUtil.js +77 -14
- package/dist/util/filterUtil.js.map +1 -1
- package/dist/util/twMerge.js +9 -0
- package/dist/util/twMerge.js.map +1 -0
- package/package.json +1 -1
- package/src/components/HireControlMap.js +48 -2
- package/src/components/containers/accordions/filter-item-container.js +1 -1
- package/src/components/containers/filter/filter-item-container.js +27 -14
- package/src/components/containers/list/item-list-container.tsx +1 -1
- package/src/components/modules/accordions/filterItem.js +16 -3
- package/src/components/modules/filter/index.js +161 -43
- package/src/components/modules/filter/item.js +15 -3
- package/src/components/modules/filter/search.js +7 -1
- package/src/components/modules/list/list-item/list-item.jsx +1 -1
- package/src/components/modules/maps/tabs.js +10 -10
- package/src/contexts/mapListContext.tsx +103 -10
- package/src/util/algoliaSearchUtil.js +7 -7
- package/src/util/filterUtil.js +63 -17
- package/src/util/twMerge.js +6 -0
|
@@ -55,6 +55,28 @@ interface MapListContextProps {
|
|
|
55
55
|
containerStyle?: any;
|
|
56
56
|
ExpandListComponent?: React.ComponentType<{ listing: any }> | ((listing: any) => JSX.Element) | null;
|
|
57
57
|
noEntities?: boolean;
|
|
58
|
+
filterConfig?: {
|
|
59
|
+
hideZeroResults?: boolean;
|
|
60
|
+
dynamicCounts?: boolean;
|
|
61
|
+
showFavorites?: boolean;
|
|
62
|
+
collapsedByDefault?: boolean;
|
|
63
|
+
sortAlphabetically?: boolean;
|
|
64
|
+
classNames?: {
|
|
65
|
+
filterContainer?: string;
|
|
66
|
+
filterContent?: string;
|
|
67
|
+
filterAccordion?: string;
|
|
68
|
+
filterAccordionHeader?: string;
|
|
69
|
+
filterAccordionContent?: string;
|
|
70
|
+
filterItem?: string;
|
|
71
|
+
filterItemLabel?: string;
|
|
72
|
+
filterItemCheckbox?: string;
|
|
73
|
+
filterItemCount?: string;
|
|
74
|
+
searchInput?: string;
|
|
75
|
+
resetButton?: string;
|
|
76
|
+
showJobsButton?: string;
|
|
77
|
+
filterFooter?: string;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
const MapListContext = createContext<MapListContextProps | undefined>(undefined);
|
|
@@ -101,6 +123,28 @@ interface MapListProviderProps {
|
|
|
101
123
|
hideMap?: boolean;
|
|
102
124
|
hideFilters?: boolean;
|
|
103
125
|
noEntities?: boolean;
|
|
126
|
+
filterConfig?: {
|
|
127
|
+
hideZeroResults?: boolean;
|
|
128
|
+
dynamicCounts?: boolean;
|
|
129
|
+
showFavorites?: boolean;
|
|
130
|
+
collapsedByDefault?: boolean;
|
|
131
|
+
sortAlphabetically?: boolean;
|
|
132
|
+
classNames?: {
|
|
133
|
+
filterContainer?: string;
|
|
134
|
+
filterContent?: string;
|
|
135
|
+
filterAccordion?: string;
|
|
136
|
+
filterAccordionHeader?: string;
|
|
137
|
+
filterAccordionContent?: string;
|
|
138
|
+
filterItem?: string;
|
|
139
|
+
filterItemLabel?: string;
|
|
140
|
+
filterItemCheckbox?: string;
|
|
141
|
+
filterItemCount?: string;
|
|
142
|
+
searchInput?: string;
|
|
143
|
+
resetButton?: string;
|
|
144
|
+
showJobsButton?: string;
|
|
145
|
+
filterFooter?: string;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
104
148
|
}
|
|
105
149
|
|
|
106
150
|
export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
@@ -128,17 +172,39 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
128
172
|
localStorageKey,
|
|
129
173
|
hideMap = false,
|
|
130
174
|
hideFilters = false,
|
|
131
|
-
noEntities = false
|
|
175
|
+
noEntities = false,
|
|
176
|
+
filterConfig = {
|
|
177
|
+
hideZeroResults: false,
|
|
178
|
+
dynamicCounts: true,
|
|
179
|
+
showFavorites: true,
|
|
180
|
+
collapsedByDefault: false,
|
|
181
|
+
sortAlphabetically: false,
|
|
182
|
+
classNames: {
|
|
183
|
+
filterContainer: '',
|
|
184
|
+
filterContent: '',
|
|
185
|
+
filterAccordion: '',
|
|
186
|
+
filterAccordionHeader: '',
|
|
187
|
+
filterAccordionContent: '',
|
|
188
|
+
filterItem: '',
|
|
189
|
+
filterItemLabel: '',
|
|
190
|
+
filterItemCheckbox: '',
|
|
191
|
+
filterItemCount: '',
|
|
192
|
+
searchInput: '',
|
|
193
|
+
resetButton: '',
|
|
194
|
+
showJobsButton: '',
|
|
195
|
+
filterFooter: ''
|
|
196
|
+
}
|
|
197
|
+
}
|
|
132
198
|
}) => {
|
|
133
199
|
const firstLoadFilters = () =>{
|
|
134
200
|
let urlData = filtersFromURL(window.location);
|
|
135
201
|
let urlFilters = urlData?.filters;
|
|
136
|
-
|
|
202
|
+
|
|
137
203
|
// If ls-ignore=true is in URL, don't load from localStorage
|
|
138
204
|
if (urlData?.lsIgnore) {
|
|
139
205
|
return urlFilters || {};
|
|
140
206
|
}
|
|
141
|
-
|
|
207
|
+
|
|
142
208
|
return (setFiltersUrl === true && urlFilters && Object.keys(urlFilters).length > 0) ? urlFilters : getStorageObject(localStorageKey + 'selectedFilters', {}) || {}
|
|
143
209
|
}
|
|
144
210
|
|
|
@@ -146,12 +212,12 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
146
212
|
if (resetFilters) return null;
|
|
147
213
|
// Check URL first
|
|
148
214
|
const urlData = filtersFromURL(window.location);
|
|
149
|
-
|
|
215
|
+
|
|
150
216
|
// If ls-ignore=true is in URL, don't load from localStorage
|
|
151
217
|
if (urlData?.lsIgnore) {
|
|
152
218
|
return urlData?.query || null;
|
|
153
219
|
}
|
|
154
|
-
|
|
220
|
+
|
|
155
221
|
if (setFiltersUrl === true && urlData?.query) {
|
|
156
222
|
return urlData.query;
|
|
157
223
|
}
|
|
@@ -277,7 +343,7 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
277
343
|
console.log('processListings: Skipping - allListings is empty');
|
|
278
344
|
return;
|
|
279
345
|
}
|
|
280
|
-
|
|
346
|
+
|
|
281
347
|
let filteredListings: Listing[];
|
|
282
348
|
let tempSelectedFilters = selectedFilters;
|
|
283
349
|
let tempQuery = query;
|
|
@@ -297,11 +363,11 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
297
363
|
if (filterByFavorites) {
|
|
298
364
|
filteredListings = filteredListings.filter((x: Listing) => favorites.includes(x.id));
|
|
299
365
|
}
|
|
300
|
-
|
|
366
|
+
|
|
301
367
|
// Batch state updates together
|
|
302
368
|
setNewFilteredListings(filteredListings);
|
|
303
369
|
setMapItems(mapItems);
|
|
304
|
-
|
|
370
|
+
|
|
305
371
|
if (firstLoad && tempSelectedFilters) {
|
|
306
372
|
// Update URL with filters if needed
|
|
307
373
|
} else if (Object.keys(tempSelectedFilters).length === 0 && !firstLoad) {
|
|
@@ -318,6 +384,31 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
318
384
|
if (tempSelectedFilters) {
|
|
319
385
|
const keys = Object.keys(tempSelectedFilters);
|
|
320
386
|
const lastKey = keys[keys.length - 1];
|
|
387
|
+
|
|
388
|
+
// Ensure all filterConfig properties have values
|
|
389
|
+
const normalizedFilterConfig = {
|
|
390
|
+
hideZeroResults: filterConfig?.hideZeroResults ?? false,
|
|
391
|
+
dynamicCounts: filterConfig?.dynamicCounts ?? true,
|
|
392
|
+
showFavorites: filterConfig?.showFavorites ?? true,
|
|
393
|
+
collapsedByDefault: filterConfig?.collapsedByDefault ?? false,
|
|
394
|
+
sortAlphabetically: filterConfig?.sortAlphabetically ?? false,
|
|
395
|
+
classNames: {
|
|
396
|
+
filterContainer: filterConfig?.classNames?.filterContainer ?? '',
|
|
397
|
+
filterContent: filterConfig?.classNames?.filterContent ?? '',
|
|
398
|
+
filterAccordion: filterConfig?.classNames?.filterAccordion ?? '',
|
|
399
|
+
filterAccordionHeader: filterConfig?.classNames?.filterAccordionHeader ?? '',
|
|
400
|
+
filterAccordionContent: filterConfig?.classNames?.filterAccordionContent ?? '',
|
|
401
|
+
filterItem: filterConfig?.classNames?.filterItem ?? '',
|
|
402
|
+
filterItemLabel: filterConfig?.classNames?.filterItemLabel ?? '',
|
|
403
|
+
filterItemCheckbox: filterConfig?.classNames?.filterItemCheckbox ?? '',
|
|
404
|
+
filterItemCount: filterConfig?.classNames?.filterItemCount ?? '',
|
|
405
|
+
searchInput: filterConfig?.classNames?.searchInput ?? '',
|
|
406
|
+
resetButton: filterConfig?.classNames?.resetButton ?? '',
|
|
407
|
+
showJobsButton: filterConfig?.classNames?.showJobsButton ?? '',
|
|
408
|
+
filterFooter: filterConfig?.classNames?.filterFooter ?? ''
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
321
412
|
const options = generateFilterOptions(
|
|
322
413
|
filteredListings,
|
|
323
414
|
allListings,
|
|
@@ -325,7 +416,8 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
325
416
|
filterOptions,
|
|
326
417
|
lastKey,
|
|
327
418
|
favorites,
|
|
328
|
-
tempSelectedFilters
|
|
419
|
+
tempSelectedFilters,
|
|
420
|
+
normalizedFilterConfig
|
|
329
421
|
);
|
|
330
422
|
if (options) {
|
|
331
423
|
setFilterOptions(options);
|
|
@@ -403,7 +495,8 @@ export const MapListProvider: React.FC<MapListProviderProps> = ({
|
|
|
403
495
|
hiddenFilters,
|
|
404
496
|
containerStyle,
|
|
405
497
|
ExpandListComponent,
|
|
406
|
-
noEntities
|
|
498
|
+
noEntities,
|
|
499
|
+
filterConfig
|
|
407
500
|
}}>
|
|
408
501
|
{children}
|
|
409
502
|
</MapListContext.Provider>
|
|
@@ -56,11 +56,11 @@ export const searchAlgolia = async (query) => {
|
|
|
56
56
|
// Extract IDs from the results and maintain order
|
|
57
57
|
const hits = results[0]?.hits || [];
|
|
58
58
|
console.log('Algolia search returned', hits.length, 'hits');
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
const referenceNumbers = [];
|
|
61
61
|
const ids = [];
|
|
62
62
|
const orderMap = new Map(); // Map to store the Algolia result order
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
hits.forEach((hit, index) => {
|
|
65
65
|
if (hit.referenceNumber) {
|
|
66
66
|
const refNum = parseInt(hit.referenceNumber);
|
|
@@ -92,18 +92,18 @@ export const filterListingsByAlgoliaSearch = async (listings, query) => {
|
|
|
92
92
|
|
|
93
93
|
try {
|
|
94
94
|
const { referenceNumbers, ids, orderMap } = await searchAlgolia(query);
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
console.log('Filtering', listings.length, 'listings against', referenceNumbers.length, 'referenceNumbers and', ids.length, 'ids');
|
|
97
97
|
console.log('Sample listing referenceNumbers:', listings.slice(0, 5).map(l => l.referenceNumber));
|
|
98
98
|
console.log('Sample listing ids:', listings.slice(0, 5).map(l => l.id));
|
|
99
99
|
console.log('Sample Algolia referenceNumbers:', referenceNumbers.slice(0, 5));
|
|
100
100
|
console.log('Sample Algolia ids:', ids.slice(0, 5));
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
// Filter listings by matching referenceNumber OR id
|
|
103
|
-
const filtered = listings.filter(listing =>
|
|
103
|
+
const filtered = listings.filter(listing =>
|
|
104
104
|
referenceNumbers.includes(listing.referenceNumber) || ids.includes(listing.id)
|
|
105
105
|
);
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
// Sort filtered listings by Algolia result order
|
|
108
108
|
filtered.sort((a, b) => {
|
|
109
109
|
// Get the Algolia order index for each listing
|
|
@@ -111,7 +111,7 @@ export const filterListingsByAlgoliaSearch = async (listings, query) => {
|
|
|
111
111
|
const orderB = orderMap.get(`ref-${b.referenceNumber}`) ?? orderMap.get(`id-${b.id}`) ?? Infinity;
|
|
112
112
|
return orderA - orderB;
|
|
113
113
|
});
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
console.log('Filtered result:', filtered.length, 'listings matched and sorted by Algolia order');
|
|
116
116
|
return filtered;
|
|
117
117
|
} catch (error) {
|
package/src/util/filterUtil.js
CHANGED
|
@@ -4,10 +4,10 @@ import { isAlgoliaAvailable, filterListingsByAlgoliaSearch } from '~/util/algoli
|
|
|
4
4
|
|
|
5
5
|
import Fuse from 'fuse.js';
|
|
6
6
|
|
|
7
|
-
export const getFilterOptions = (listings, filteredListings, field, excludeZeroCount =
|
|
7
|
+
export const getFilterOptions = (listings, filteredListings, field, excludeZeroCount = false, sortAlphabetically = false) => {
|
|
8
8
|
const options = new Set();
|
|
9
9
|
listings.forEach(listing => {
|
|
10
|
-
if (listing.fields[field]) {
|
|
10
|
+
if (listing.fields && listing.fields[field]) {
|
|
11
11
|
options.add(listing.fields[field]);
|
|
12
12
|
}
|
|
13
13
|
});
|
|
@@ -18,22 +18,32 @@ export const getFilterOptions = (listings, filteredListings, field, excludeZeroC
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
filteredListings.forEach(listing => {
|
|
21
|
+
if (!listing.fields) return;
|
|
21
22
|
const value = listing.fields[field];
|
|
22
|
-
if (value &&
|
|
23
|
+
if (value && Object.prototype.hasOwnProperty.call(optionCounts, value)) {
|
|
23
24
|
optionCounts[value] += 1;
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
.
|
|
28
|
+
let result = Array.from(options)
|
|
29
|
+
.filter(option => option != null && option !== '') // Filter out null/empty values
|
|
29
30
|
.map(option => ({
|
|
30
31
|
name: option,
|
|
31
32
|
count: optionCounts[option] || 0
|
|
32
33
|
}))
|
|
33
34
|
.filter(option => !(excludeZeroCount === true && option.count === 0));
|
|
35
|
+
|
|
36
|
+
// Sort alphabetically or by count
|
|
37
|
+
if (sortAlphabetically) {
|
|
38
|
+
result.sort((a, b) => a.name.localeCompare(b.name));
|
|
39
|
+
} else {
|
|
40
|
+
result.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return result;
|
|
34
44
|
};
|
|
35
45
|
|
|
36
|
-
export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig, favorites) => {
|
|
46
|
+
export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig, favorites, filterConfig = {}) => {
|
|
37
47
|
const specialFeatures = siteConfig.specialFeatures;
|
|
38
48
|
const featureCounts = Object.keys(specialFeatures).sort().reduce((acc, key) => {
|
|
39
49
|
acc[specialFeatures[key]] = 0;
|
|
@@ -48,17 +58,28 @@ export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig,
|
|
|
48
58
|
});
|
|
49
59
|
});
|
|
50
60
|
|
|
51
|
-
|
|
61
|
+
let specialFeatureOptions = Object.entries(featureCounts).map(([name, count]) => ({
|
|
52
62
|
name,
|
|
53
63
|
count
|
|
54
64
|
}));
|
|
55
65
|
|
|
66
|
+
// Update favorite count
|
|
56
67
|
for (let option of specialFeatureOptions) {
|
|
57
68
|
if (option.name === 'Favorite') {
|
|
58
69
|
option.count = filteredListings.filter(x => favorites.includes(x.id)).length;
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
72
|
|
|
73
|
+
// Hide favorites if filterConfig.showFavorites is false
|
|
74
|
+
if (filterConfig.showFavorites === false) {
|
|
75
|
+
specialFeatureOptions = specialFeatureOptions.filter(option => option.name !== 'Favorite');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Hide zero results if filterConfig.hideZeroResults is true
|
|
79
|
+
if (filterConfig.hideZeroResults === true) {
|
|
80
|
+
specialFeatureOptions = specialFeatureOptions.filter(option => option.count > 0);
|
|
81
|
+
}
|
|
82
|
+
|
|
62
83
|
return specialFeatureOptions;
|
|
63
84
|
};
|
|
64
85
|
|
|
@@ -76,9 +97,19 @@ export const generateFilterOptions = (
|
|
|
76
97
|
filterOptions,
|
|
77
98
|
parentField,
|
|
78
99
|
favorites,
|
|
79
|
-
selectedFilters
|
|
100
|
+
selectedFilters,
|
|
101
|
+
filterConfig = {
|
|
102
|
+
hideZeroResults: false,
|
|
103
|
+
dynamicCounts: true,
|
|
104
|
+
showFavorites: true,
|
|
105
|
+
collapsedByDefault: false,
|
|
106
|
+
sortAlphabetically: false
|
|
107
|
+
}
|
|
80
108
|
) => {
|
|
81
109
|
if (allListings.length > 0) {
|
|
110
|
+
// Determine which listings to use for counts based on dynamicCounts setting
|
|
111
|
+
const countListings = filterConfig.dynamicCounts ? filteredListings : allListings;
|
|
112
|
+
|
|
82
113
|
const dynamicFilters = siteConfig.fieldFiltersShown.map(fieldName => {
|
|
83
114
|
if (fieldName === parentField && filterOptions?.filters) {
|
|
84
115
|
return filterOptions.filters.find(filter => filter.id === fieldName);
|
|
@@ -87,31 +118,31 @@ export const generateFilterOptions = (
|
|
|
87
118
|
return {
|
|
88
119
|
id: fieldName,
|
|
89
120
|
title: siteConfig.fieldNames[fieldName],
|
|
90
|
-
items: getFilterOptions(allListings,
|
|
121
|
+
items: getFilterOptions(allListings, countListings, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
|
|
91
122
|
};
|
|
92
123
|
}
|
|
93
124
|
if(fieldName == 'subCategory' && selectedFilters.category){
|
|
94
125
|
const categoryKeys = Object.keys(selectedFilters.category);
|
|
95
|
-
const
|
|
126
|
+
const filteredByCategory = allListings.filter(
|
|
96
127
|
x => categoryKeys.includes(x.fields?.category)
|
|
97
128
|
);
|
|
98
129
|
return {
|
|
99
130
|
id: fieldName,
|
|
100
131
|
title: siteConfig.fieldNames[fieldName],
|
|
101
|
-
items: getFilterOptions(allListings,
|
|
132
|
+
items: getFilterOptions(allListings, filteredByCategory, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
|
|
102
133
|
};
|
|
103
134
|
}
|
|
104
135
|
if (fieldName == "specialFeatures") {
|
|
105
136
|
return {
|
|
106
137
|
id: fieldName,
|
|
107
138
|
title: siteConfig.fieldNames[fieldName],
|
|
108
|
-
items: getSpecialFeatureOptions(allListings,
|
|
139
|
+
items: getSpecialFeatureOptions(allListings, countListings, siteConfig, favorites, filterConfig).sort()
|
|
109
140
|
};
|
|
110
141
|
}
|
|
111
142
|
return {
|
|
112
143
|
id: fieldName,
|
|
113
144
|
title: siteConfig.fieldNames[fieldName],
|
|
114
|
-
items: getFilterOptions(allListings,
|
|
145
|
+
items: getFilterOptions(allListings, countListings, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
|
|
115
146
|
};
|
|
116
147
|
});
|
|
117
148
|
|
|
@@ -186,9 +217,24 @@ export const generateFilterOptions = (
|
|
|
186
217
|
)
|
|
187
218
|
};
|
|
188
219
|
|
|
220
|
+
// Filter out null filters and ensure items arrays don't contain undefined values
|
|
221
|
+
const cleanFilters = dynamicFilters
|
|
222
|
+
.filter(f => f != null && f.items != null)
|
|
223
|
+
.map(f => ({
|
|
224
|
+
...f,
|
|
225
|
+
items: f.items.filter(item => item != null && item.name != null)
|
|
226
|
+
}));
|
|
227
|
+
|
|
228
|
+
const cleanLocations = locations
|
|
229
|
+
.filter(l => l != null && l.items != null)
|
|
230
|
+
.map(l => ({
|
|
231
|
+
...l,
|
|
232
|
+
items: l.items.filter(item => item != null && item.name != null)
|
|
233
|
+
}));
|
|
234
|
+
|
|
189
235
|
return {
|
|
190
|
-
filters:
|
|
191
|
-
locations:
|
|
236
|
+
filters: cleanFilters,
|
|
237
|
+
locations: cleanLocations,
|
|
192
238
|
pointsOfInterest: pointsOfInterest
|
|
193
239
|
};
|
|
194
240
|
}
|
|
@@ -235,7 +281,7 @@ export const applyFilters = async (
|
|
|
235
281
|
});
|
|
236
282
|
} else if (Object.keys(filterItems).length > 0) {
|
|
237
283
|
results = results.filter(listing =>
|
|
238
|
-
|
|
284
|
+
Object.prototype.hasOwnProperty.call(filterItems, listing.fields[formattedField])
|
|
239
285
|
);
|
|
240
286
|
}
|
|
241
287
|
}
|
|
@@ -314,7 +360,7 @@ export const filterListingsByLocation = (
|
|
|
314
360
|
let results = allListings;
|
|
315
361
|
if (selectedLocation !== null) {
|
|
316
362
|
results = results.filter(item =>
|
|
317
|
-
|
|
363
|
+
Object.prototype.hasOwnProperty.call(selectedLocation.items, item.id)
|
|
318
364
|
);
|
|
319
365
|
}
|
|
320
366
|
const mapItems = getDistinctItemsByProximity(results, listingEntities);
|