Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/snap-controller/src/Search/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ The `SearchController` is used when making queries to the API `search` endpoint.
| settings.facets.trim | facets that do not change results will be removed | true | |
| settings.facets.autoOpenActive | setting for "auto open" functionality for facets that are filtered (active), collapsed, and have no stored data | true | |
| settings.facets.fields | object keyed by individual facet fields for configuration of any settings.facets options | ➖ | |
| settings.filters.fields | object keyed by individual filter fields for configuration of any settings.filters options | ➖ | |
| settings.filters.hierarchy.enabled | boolean to enable/disable selected hierarchy facets from showing in the filters | false | |
| settings.filters.hierarchy.showFullPath | boolean to show the full hierarchy path in the filter | false | |
| settings.filters.hierarchy.displayDelimiter | string to adjust the delimiter between each level of the full hierarchy path | ' / ' | |
| settings.filters.rangeFormatValue | setting to re-format the value of a range filter using sprintf | false | |
| settings.history.max | how many search terms should be kept in the history store | 25 | |
| settings.history.url | allows for adjust the root URL for history store terms (default is relative URLs) | ➖ | |
| settings.pagination.pageSizeOptions | setting to change the page size options available | ➖ | |
Expand Down
38 changes: 27 additions & 11 deletions packages/snap-controller/src/Search/SearchController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,12 @@ describe('Search Controller', () => {
settings: {
...searchConfig.settings,
filters: {
hierarchy: {
enabled: true,
fields: {
ss_category_hierarchy: {
hiearchy: {
enabled: true,
},
},
},
},
},
Expand Down Expand Up @@ -507,8 +511,12 @@ describe('Search Controller', () => {
settings: {
...searchConfig.settings,
filters: {
hierarchy: {
enabled: false,
fields: {
ss_category_hierarchy: {
hiearchy: {
enabled: false,
},
},
},
},
},
Expand Down Expand Up @@ -537,9 +545,13 @@ describe('Search Controller', () => {
settings: {
...searchConfig.settings,
filters: {
hierarchy: {
enabled: true,
showFullPath: true,
fields: {
ss_category_hierarchy: {
hiearchy: {
enabled: true,
showFullPath: true,
},
},
},
},
},
Expand Down Expand Up @@ -569,10 +581,14 @@ describe('Search Controller', () => {
settings: {
...searchConfig.settings,
filters: {
hierarchy: {
enabled: true,
displayDelimiter: ' ? ',
showFullPath: true,
fields: {
ss_category_hierarchy: {
hiearchy: {
enabled: true,
displayDelimiter: ' ? ',
showFullPath: true,
},
},
},
},
},
Expand Down
89 changes: 49 additions & 40 deletions packages/snap-controller/src/Search/SearchController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { StorageStore, ErrorType } from '@searchspring/snap-store-mobx';
import { getSearchParams } from '../utils/getParams';
import { ControllerTypes, PageContextVariable } from '../types';

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

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

const displayDelimiter = hierarchySettings.displayDelimiter ?? ' / '; // choose delimiter for label
const showFullPath = hierarchySettings.showFullPath ?? false; // display full hierarchy path or just the current level
// add hierarchy filter to filter summary
const facets = search.response.search.facets;
if (facets) {
facets.forEach((facet: any) => {
if (search.response.meta?.facets && facet.field) {
const metaFacet = search.response.meta.facets[facet.field];
const dataDelimiter = (metaFacet as MetaResponseModelFacetHierarchy)?.hierarchyDelimiter || ' / ';

if (metaFacet && metaFacet.display === 'hierarchy' && facet.filtered && (facet as ValueFacet).values?.length > 0) {
const filteredValues = (facet as SearchResponseModelFacetValue).values?.filter((val) => val?.filtered === true);

if (filteredValues && filteredValues.length) {
const filterToAdd: SearchResponseModelFilter = {
field: facet.field,
//escape special charactors used in regex
label: showFullPath
? (filteredValues[0].value ?? filteredValues[0].label ?? '').replace(
new RegExp(dataDelimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
displayDelimiter
)
: filteredValues[0].label,
type: 'value' as SearchResponseModelFilterTypeEnum.Value,
};

if (search.response.search.filters) {
search.response.search.filters.push(filterToAdd);
} else {
search.response.search.filters = [filterToAdd];
}
// add hierarchy filter to filter summary
const facets = search.response.search.facets;
if (facets) {
facets.forEach((facet: any) => {
if (search.response.meta?.facets && facet.field) {
const field = (facet.field as string) || '';
const metaFacet = search.response.meta.facets[field];

const dataDelimiter = (metaFacet as MetaResponseModelFacetHierarchy)?.hierarchyDelimiter || ' / ';
const filterSettings = (this.config as SearchStoreConfig)?.settings?.filters?.fields
? this.config?.settings?.filters?.fields![field]
: this.config?.settings?.filters;

const displayDelimiter = filterSettings?.hiearchy?.displayDelimiter ?? ' / '; // choose delimiter for label
const showFullPath = filterSettings?.hiearchy?.showFullPath ?? false; // display full hierarchy path or just the current level

if (
filterSettings?.hiearchy?.enabled &&
metaFacet &&
metaFacet.display === 'hierarchy' &&
facet.filtered &&
(facet as ValueFacet).values?.length > 0
) {
const filteredValues = (facet as SearchResponseModelFacetValue).values?.filter((val) => val?.filtered === true);

if (filteredValues && filteredValues.length) {
const filterToAdd: SearchResponseModelFilter = {
field: facet.field,
//escape special charactors used in regex
label: showFullPath
? (filteredValues[0].value ?? filteredValues[0].label ?? '').replace(
new RegExp(dataDelimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
displayDelimiter
)
: filteredValues[0].label,
type: 'value' as SearchResponseModelFilterTypeEnum.Value,
};

if (search.response.search.filters) {
search.response.search.filters.push(filterToAdd);
} else {
search.response.search.filters = [filterToAdd];
}
}
}
});
}
});
}
}
});
}
});

this.eventManager.on('afterStore', async (search: AfterStoreObj, next: Next): Promise<void | boolean> => {
await next();
Expand Down
51 changes: 50 additions & 1 deletion packages/snap-preact-demo/templates/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,42 @@ import { combineMerge } from '../../snap/src/middleware/functions';
import type { SnapTemplatesConfig } from '@searchspring/snap-preact';
const siteId = 'atkzs2';

// const siteId = '8uyt2m';

// const clientConfig = {
// meta: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// search: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// autocomplete: {
// requesters: {
// suggest: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// legacy: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// },
// },
// finder: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// recommend: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// suggest: {
// origin: `https://${siteId}.a.searchspring.io`,
// },
// };
let config: SnapTemplatesConfig = {
config: {
siteId,
language: 'en',
currency: 'usd',
platform: 'other',
// client: clientConfig
},
plugins: {
common: {
Expand Down Expand Up @@ -39,7 +69,14 @@ let config: SnapTemplatesConfig = {
// },
},
style: globalStyles,
overrides: {},
overrides: {
// default: {
// 'facet': {
// rangeInputs: true,
// rangeInputsPrefix: "$",
// }
// }
},
},
recommendation: {
email: {
Expand All @@ -65,6 +102,18 @@ let config: SnapTemplatesConfig = {
component: 'Search',
},
],
// settings: {
// filters: {
// fields: {
// 'price': {
// filterFormatValue: '$%01.2f - $%01.2f'
// },
// 'ss_category_hierarchy': {
// enabled: true,
// }
// }
// },
// },
},
autocomplete: {
targets: [
Expand Down
Loading
Loading