Skip to content

Commit 719a540

Browse files
authored
Merge pull request #157 from searchspring/price-facet-inputs
Facet range inputs & formalValue for filters
2 parents f4318c9 + 9823f76 commit 719a540

24 files changed

Lines changed: 855 additions & 80 deletions

File tree

packages/snap-controller/src/Search/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ The `SearchController` is used when making queries to the API `search` endpoint.
1515
| settings.facets.trim | facets that do not change results will be removed | true | |
1616
| settings.facets.autoOpenActive | setting for "auto open" functionality for facets that are filtered (active), collapsed, and have no stored data | true | |
1717
| settings.facets.fields | object keyed by individual facet fields for configuration of any settings.facets options || |
18+
| settings.filters.fields | object keyed by individual filter fields for configuration of any settings.filters options || |
1819
| settings.filters.hierarchy.enabled | boolean to enable/disable selected hierarchy facets from showing in the filters | false | |
1920
| settings.filters.hierarchy.showFullPath | boolean to show the full hierarchy path in the filter | false | |
2021
| settings.filters.hierarchy.displayDelimiter | string to adjust the delimiter between each level of the full hierarchy path | ' / ' | |
22+
| settings.filters.rangeFormatValue | setting to re-format the value of a range filter using sprintf | false | |
2123
| settings.history.max | how many search terms should be kept in the history store | 25 | |
2224
| settings.history.url | allows for adjust the root URL for history store terms (default is relative URLs) || |
2325
| settings.pagination.pageSizeOptions | setting to change the page size options available || |

packages/snap-controller/src/Search/SearchController.test.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,12 @@ describe('Search Controller', () => {
476476
settings: {
477477
...searchConfig.settings,
478478
filters: {
479-
hierarchy: {
480-
enabled: true,
479+
fields: {
480+
ss_category_hierarchy: {
481+
hiearchy: {
482+
enabled: true,
483+
},
484+
},
481485
},
482486
},
483487
},
@@ -507,8 +511,12 @@ describe('Search Controller', () => {
507511
settings: {
508512
...searchConfig.settings,
509513
filters: {
510-
hierarchy: {
511-
enabled: false,
514+
fields: {
515+
ss_category_hierarchy: {
516+
hiearchy: {
517+
enabled: false,
518+
},
519+
},
512520
},
513521
},
514522
},
@@ -537,9 +545,13 @@ describe('Search Controller', () => {
537545
settings: {
538546
...searchConfig.settings,
539547
filters: {
540-
hierarchy: {
541-
enabled: true,
542-
showFullPath: true,
548+
fields: {
549+
ss_category_hierarchy: {
550+
hiearchy: {
551+
enabled: true,
552+
showFullPath: true,
553+
},
554+
},
543555
},
544556
},
545557
},
@@ -569,10 +581,14 @@ describe('Search Controller', () => {
569581
settings: {
570582
...searchConfig.settings,
571583
filters: {
572-
hierarchy: {
573-
enabled: true,
574-
displayDelimiter: ' ? ',
575-
showFullPath: true,
584+
fields: {
585+
ss_category_hierarchy: {
586+
hiearchy: {
587+
enabled: true,
588+
displayDelimiter: ' ? ',
589+
showFullPath: true,
590+
},
591+
},
576592
},
577593
},
578594
},

packages/snap-controller/src/Search/SearchController.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { StorageStore, ErrorType } from '@searchspring/snap-store-mobx';
66
import { getSearchParams } from '../utils/getParams';
77
import { ControllerTypes, PageContextVariable } from '../types';
88

9-
import type { Product, Banner, SearchStore, ValueFacet } from '@searchspring/snap-store-mobx';
9+
import type { Product, Banner, SearchStore, ValueFacet, SearchStoreConfig } from '@searchspring/snap-store-mobx';
1010
import type {
1111
SearchControllerConfig,
1212
SearchAfterSearchObj,
@@ -208,49 +208,58 @@ export class SearchController extends AbstractController {
208208
this.eventManager.fire('restorePosition', { controller: this, element: elementPosition });
209209
});
210210

211-
const hierarchySettings = this.config.settings?.filters?.hierarchy;
212-
if (hierarchySettings && hierarchySettings.enabled) {
213-
this.eventManager.on('afterSearch', async (search: SearchAfterSearchObj, next: Next): Promise<void | boolean> => {
214-
await next();
211+
this.eventManager.on('afterSearch', async (search: SearchAfterSearchObj, next: Next): Promise<void | boolean> => {
212+
await next();
215213

216-
const displayDelimiter = hierarchySettings.displayDelimiter ?? ' / '; // choose delimiter for label
217-
const showFullPath = hierarchySettings.showFullPath ?? false; // display full hierarchy path or just the current level
218-
// add hierarchy filter to filter summary
219-
const facets = search.response.search.facets;
220-
if (facets) {
221-
facets.forEach((facet: any) => {
222-
if (search.response.meta?.facets && facet.field) {
223-
const metaFacet = search.response.meta.facets[facet.field];
224-
const dataDelimiter = (metaFacet as MetaResponseModelFacetHierarchy)?.hierarchyDelimiter || ' / ';
225-
226-
if (metaFacet && metaFacet.display === 'hierarchy' && facet.filtered && (facet as ValueFacet).values?.length > 0) {
227-
const filteredValues = (facet as SearchResponseModelFacetValue).values?.filter((val) => val?.filtered === true);
228-
229-
if (filteredValues && filteredValues.length) {
230-
const filterToAdd: SearchResponseModelFilter = {
231-
field: facet.field,
232-
//escape special charactors used in regex
233-
label: showFullPath
234-
? (filteredValues[0].value ?? filteredValues[0].label ?? '').replace(
235-
new RegExp(dataDelimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
236-
displayDelimiter
237-
)
238-
: filteredValues[0].label,
239-
type: 'value' as SearchResponseModelFilterTypeEnum.Value,
240-
};
241-
242-
if (search.response.search.filters) {
243-
search.response.search.filters.push(filterToAdd);
244-
} else {
245-
search.response.search.filters = [filterToAdd];
246-
}
214+
// add hierarchy filter to filter summary
215+
const facets = search.response.search.facets;
216+
if (facets) {
217+
facets.forEach((facet: any) => {
218+
if (search.response.meta?.facets && facet.field) {
219+
const field = (facet.field as string) || '';
220+
const metaFacet = search.response.meta.facets[field];
221+
222+
const dataDelimiter = (metaFacet as MetaResponseModelFacetHierarchy)?.hierarchyDelimiter || ' / ';
223+
const filterSettings = (this.config as SearchStoreConfig)?.settings?.filters?.fields
224+
? this.config?.settings?.filters?.fields![field]
225+
: this.config?.settings?.filters;
226+
227+
const displayDelimiter = filterSettings?.hiearchy?.displayDelimiter ?? ' / '; // choose delimiter for label
228+
const showFullPath = filterSettings?.hiearchy?.showFullPath ?? false; // display full hierarchy path or just the current level
229+
230+
if (
231+
filterSettings?.hiearchy?.enabled &&
232+
metaFacet &&
233+
metaFacet.display === 'hierarchy' &&
234+
facet.filtered &&
235+
(facet as ValueFacet).values?.length > 0
236+
) {
237+
const filteredValues = (facet as SearchResponseModelFacetValue).values?.filter((val) => val?.filtered === true);
238+
239+
if (filteredValues && filteredValues.length) {
240+
const filterToAdd: SearchResponseModelFilter = {
241+
field: facet.field,
242+
//escape special charactors used in regex
243+
label: showFullPath
244+
? (filteredValues[0].value ?? filteredValues[0].label ?? '').replace(
245+
new RegExp(dataDelimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
246+
displayDelimiter
247+
)
248+
: filteredValues[0].label,
249+
type: 'value' as SearchResponseModelFilterTypeEnum.Value,
250+
};
251+
252+
if (search.response.search.filters) {
253+
search.response.search.filters.push(filterToAdd);
254+
} else {
255+
search.response.search.filters = [filterToAdd];
247256
}
248257
}
249258
}
250-
});
251-
}
252-
});
253-
}
259+
}
260+
});
261+
}
262+
});
254263

255264
this.eventManager.on('afterStore', async (search: AfterStoreObj, next: Next): Promise<void | boolean> => {
256265
await next();

packages/snap-preact-demo/templates/src/index.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,42 @@ import { combineMerge } from '../../snap/src/middleware/functions';
55
import type { SnapTemplatesConfig } from '@searchspring/snap-preact';
66
const siteId = 'atkzs2';
77

8+
// const siteId = '8uyt2m';
9+
10+
// const clientConfig = {
11+
// meta: {
12+
// origin: `https://${siteId}.a.searchspring.io`,
13+
// },
14+
// search: {
15+
// origin: `https://${siteId}.a.searchspring.io`,
16+
// },
17+
// autocomplete: {
18+
// requesters: {
19+
// suggest: {
20+
// origin: `https://${siteId}.a.searchspring.io`,
21+
// },
22+
// legacy: {
23+
// origin: `https://${siteId}.a.searchspring.io`,
24+
// },
25+
// },
26+
// },
27+
// finder: {
28+
// origin: `https://${siteId}.a.searchspring.io`,
29+
// },
30+
// recommend: {
31+
// origin: `https://${siteId}.a.searchspring.io`,
32+
// },
33+
// suggest: {
34+
// origin: `https://${siteId}.a.searchspring.io`,
35+
// },
36+
// };
837
let config: SnapTemplatesConfig = {
938
config: {
1039
siteId,
1140
language: 'en',
1241
currency: 'usd',
1342
platform: 'other',
43+
// client: clientConfig
1444
},
1545
plugins: {
1646
common: {
@@ -39,7 +69,14 @@ let config: SnapTemplatesConfig = {
3969
// },
4070
},
4171
style: globalStyles,
42-
overrides: {},
72+
overrides: {
73+
// default: {
74+
// 'facet': {
75+
// rangeInputs: true,
76+
// rangeInputsPrefix: "$",
77+
// }
78+
// }
79+
},
4380
},
4481
recommendation: {
4582
email: {
@@ -65,6 +102,18 @@ let config: SnapTemplatesConfig = {
65102
component: 'Search',
66103
},
67104
],
105+
// settings: {
106+
// filters: {
107+
// fields: {
108+
// 'price': {
109+
// filterFormatValue: '$%01.2f - $%01.2f'
110+
// },
111+
// 'ss_category_hierarchy': {
112+
// enabled: true,
113+
// }
114+
// }
115+
// },
116+
// },
68117
},
69118
autocomplete: {
70119
targets: [

0 commit comments

Comments
 (0)