Skip to content

Commit

Permalink
add location facets
Browse files Browse the repository at this point in the history
  • Loading branch information
Spuffynism committed Oct 21, 2024
1 parent 9e15c6c commit 503ec58
Show file tree
Hide file tree
Showing 27 changed files with 1,008 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface FacetSearchType<
T extends 'specific' | 'location' | 'hierarchical',
> {
type: T;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {BaseFacetSearchRequest} from '../../../search/facet-search/base/base-facet-search-request.js';
import {FacetSearchType} from '../base/base-facet-search-request.js';

export interface LocationFacetSearchRequest
extends BaseFacetSearchRequest,
FacetSearchType<'location'> {
ignoreValues: string[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {
BaseFacetSearchResponse,
BaseFacetSearchResult,
} from '../../../search/facet-search/base/base-facet-search-response.js';

export type LocationFacetSearchResult = BaseFacetSearchResult;
export type LocationFacetSearchResponse =
BaseFacetSearchResponse<LocationFacetSearchResult>;
12 changes: 12 additions & 0 deletions packages/headless/src/commerce.index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export * from './features/commerce/sort/sort-actions-loader.js';
export * from './features/commerce/facets/core-facet/core-facet-actions-loader.js';
export * from './features/commerce/facets/category-facet/category-facet-actions-loader.js';
export * from './features/commerce/facets/regular-facet/regular-facet-actions-loader.js';
// TODO COMHUB-247 export location facets actions loader
export * from './features/commerce/facets/date-facet/date-facet-actions-loader.js';
export * from './features/commerce/facets/numeric-facet/numeric-facet-actions-loader.js';
export * from './features/commerce/query-set/query-set-actions-loader.js';
Expand Down Expand Up @@ -164,6 +165,10 @@ export type {
RegularFacet,
RegularFacetState,
} from './controllers/commerce/core/facets/regular/headless-commerce-regular-facet.js';
export type {
LocationFacet,
LocationFacetState,
} from './controllers/commerce/core/facets/location/headless-commerce-location-facet.js';
export type {
NumericFacet,
NumericFacetState,
Expand All @@ -178,6 +183,8 @@ export type {
FacetType,
FacetValueRequest,
RegularFacetValue,
LocationFacetValueRequest,
LocationFacetValue,
NumericRangeRequest,
NumericFacetValue,
DateRangeRequest,
Expand All @@ -194,6 +201,11 @@ export type {
RegularFacetSearchState,
} from './controllers/commerce/core/facets/regular/headless-commerce-regular-facet-search.js';
export type {SpecificFacetSearchResult as RegularFacetSearchResult} from './api/search/facet-search/specific-facet-search/specific-facet-search-response.js';
export type {
LocationFacetSearch,
LocationFacetSearchState,
} from './controllers/commerce/core/facets/location/headless-commerce-location-facet-search.js';
export type {LocationFacetSearchResult} from './api/commerce/facet-search/location-facet-search/location-facet-search-response.js';
export type {
CategoryFacetSearch,
CategoryFacetSearchState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
BaseFacetValue,
CategoryFacetResponse,
DateFacetResponse,
LocationFacetResponse,
NumericFacetResponse,
RegularFacetResponse,
} from '../../../../features/commerce/facets/facet-set/interfaces/response.js';
Expand Down Expand Up @@ -116,7 +117,8 @@ interface ActionCreators {

const facetTypeWithoutExcludeAction: FacetType = 'hierarchical';

const actions: Record<FacetType, ActionCreators> = {
// TODO: COMHUB-247 add support for location facet
const actions: Record<Exclude<FacetType, 'location'>, ActionCreators> = {
regular: {
toggleSelectActionCreator: toggleSelectFacetValue,
toggleExcludeActionCreator: toggleExcludeFacetValue,
Expand Down Expand Up @@ -153,7 +155,10 @@ export function buildCoreBreadcrumbManager(
const controller = buildController(engine);
const {dispatch} = engine;

const createBreadcrumb = (facet: AnyFacetResponse) => ({
// TODO: COMHUB-247 add support for location facet
const createBreadcrumb = (
facet: Exclude<AnyFacetResponse, LocationFacetResponse>
) => ({
facetId: facet.facetId,
facetDisplayName: facet.displayName,
field: facet.field,
Expand Down Expand Up @@ -253,7 +258,9 @@ export function buildCoreBreadcrumbManager(
(facetOrder): BreadcrumbManagerState => {
const breadcrumbs = facetOrder.flatMap((facetId) => {
const facet = options.facetResponseSelector(engine[stateKey], facetId);
if (hasActiveValue(facet)) {

// TODO: COMHUB-247 add support for location facet
if (hasActiveValue(facet) && facet.type !== 'location') {
return [createBreadcrumb(facet)];
}
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
buildMockCommerceDateFacetResponse,
buildMockCommerceNumericFacetResponse,
buildMockCommerceRegularFacetResponse,
buildMockCommerceLocationFacetResponse,
} from '../../../../../test/mock-commerce-facet-response.js';
import {buildMockCommerceState} from '../../../../../test/mock-commerce-state.js';
import {
Expand Down Expand Up @@ -55,6 +56,9 @@ describe('SSR FacetGenerator', () => {
case 'numericalRange':
response = buildMockCommerceNumericFacetResponse({facetId, type});
break;
case 'location':
response = buildMockCommerceLocationFacetResponse({facetId, type});
break;
case 'regular':
default:
response = buildMockCommerceRegularFacetResponse({facetId, type});
Expand All @@ -71,7 +75,7 @@ describe('SSR FacetGenerator', () => {
type: facet.type,
}),
};
if (type === 'regular') {
if (type === 'regular' || type === 'location') {
state.facetSearchSet[facet.facetId] = buildMockFacetSearch();
} else if (type === 'hierarchical') {
state.categoryFacetSearchSet[facet.facetId] =
Expand Down Expand Up @@ -117,6 +121,10 @@ describe('SSR FacetGenerator', () => {
facetId: 'regular-facet',
type: 'regular',
},
{
facetId: 'location-facet',
type: 'location',
},
];
state = buildMockCommerceState();
setFacetState(facetsInEngineState);
Expand All @@ -131,7 +139,7 @@ describe('SSR FacetGenerator', () => {
expect(facetGenerator).toBeTruthy();
});
it('#state is an array containing the state of each facet', () => {
expect(facetGenerator.state.length).toBe(4);
expect(facetGenerator.state.length).toBe(5);
expect(
facetGenerator.state.map((facet) => ({
facetId: facet.facetId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import {stateKey} from '../../../../../app/state-key.js';
import {facetRequestSelector} from '../../../../../features/commerce/facets/facet-set/facet-set-selector.js';
import {
AnyFacetResponse,
LocationFacetValue,
RegularFacetValue,
} from '../../../../../features/commerce/facets/facet-set/interfaces/response.js';
import {manualNumericFacetSelector} from '../../../../../features/commerce/facets/numeric-facet/manual-numeric-facet-selectors.js';
import {manualNumericFacetReducer as manualNumericFacetSet} from '../../../../../features/commerce/facets/numeric-facet/manual-numeric-facet-slice.js';
import {categoryFacetSearchStateSelector} from '../../../../../features/facets/facet-search-set/category/category-facet-search-state-selector.js';
import {locationFacetSearchStateSelector} from '../../../../../features/facets/facet-search-set/location/location-facet-search-state-selector.js';
import {specificFacetSearchStateSelector} from '../../../../../features/facets/facet-search-set/specific/specific-facet-search-state-selector.js';
import {ManualRangeSection} from '../../../../../state/state-sections.js';
import {loadReducerError} from '../../../../../utils/errors.js';
Expand Down Expand Up @@ -44,6 +46,11 @@ import {
FacetType,
getCoreFacetState,
} from '../headless-core-commerce-facet.js';
import {
getLocationFacetState,
LocationFacet,
LocationFacetState,
} from '../location/headless-commerce-location-facet.js';
import {
getNumericFacetState,
NumericFacet,
Expand Down Expand Up @@ -72,6 +79,9 @@ export type {
RegularFacet,
RegularFacetState,
RegularFacetValue,
LocationFacet,
LocationFacetState,
LocationFacetValue,
};

export type FacetGeneratorState = MappedFacetStates;
Expand All @@ -87,7 +97,9 @@ type MappedFacetState = {
? DateFacetState
: T extends 'hierarchical'
? CategoryFacetState
: never;
: T extends 'location'
? LocationFacetState
: never;
};

export function defineFacetGenerator<
Expand Down Expand Up @@ -235,6 +247,11 @@ export function buildFacetGenerator(
createFacetState(facetResponseSelector) as RegularFacetState,
specificFacetSearchStateSelector(getEngineState(), facetId)
);
case 'location':
return getLocationFacetState(
createFacetState(facetResponseSelector) as LocationFacetState,
locationFacetSearchStateSelector(getEngineState(), facetId)
);
}
});
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('CSR FacetGenerator', () => {
let facetGenerator: FacetGenerator;
const mockBuildNumericFacet = vi.fn();
const mockBuildRegularFacet = vi.fn();
const mockBuildLocationFacet = vi.fn();
const mockBuildDateFacet = vi.fn();
const mockBuildCategoryFacet = vi.fn();
const mockFetchProductsActionCreator = vi.fn();
Expand Down Expand Up @@ -61,6 +62,7 @@ describe('CSR FacetGenerator', () => {
options = {
buildNumericFacet: mockBuildNumericFacet,
buildRegularFacet: mockBuildRegularFacet,
buildLocationFacet: mockBuildLocationFacet,
buildDateFacet: mockBuildDateFacet,
buildCategoryFacet: mockBuildCategoryFacet,
fetchProductsActionCreator: mockFetchProductsActionCreator,
Expand Down Expand Up @@ -97,6 +99,14 @@ describe('CSR FacetGenerator', () => {
expect(mockBuildRegularFacet).toHaveBeenCalledWith(engine, {facetId});
});

it('when engine facet state contains a location facet, generates a location facet controller', () => {
const facetId = 'location_facet_id';
setFacetState([{facetId, type: 'location'}]);

expect(facetGenerator.facets.length).toEqual(1);
expect(mockBuildLocationFacet).toHaveBeenCalledWith(engine, {facetId});
});

it('when engine facet state contains a numeric facet, generates a numeric facet controller', () => {
const facetId = 'numeric_facet_id';
setFacetState([{facetId, type: 'numericalRange'}]);
Expand Down Expand Up @@ -127,6 +137,10 @@ describe('CSR FacetGenerator', () => {
facetId: 'regular_facet_id',
type: 'regular',
},
{
facetId: 'location_facet_id',
type: 'location',
},
{
facetId: 'numeric_facet_id',
type: 'numericalRange',
Expand All @@ -142,24 +156,29 @@ describe('CSR FacetGenerator', () => {
];
setFacetState(facets);

let index = 0;
mockBuildRegularFacet.mockReturnValue({
state: {facetId: facets[0].facetId},
state: {facetId: facets[index++].facetId},
});
mockBuildLocationFacet.mockReturnValue({
state: {facetId: facets[index++].facetId},
});
mockBuildNumericFacet.mockReturnValue({
state: {facetId: facets[1].facetId},
state: {facetId: facets[index++].facetId},
});
mockBuildDateFacet.mockReturnValue({
state: {facetId: facets[index++].facetId},
});
mockBuildDateFacet.mockReturnValue({state: {facetId: facets[2].facetId}});
mockBuildCategoryFacet.mockReturnValue({
state: {facetId: facets[3].facetId},
state: {facetId: facets[index++].facetId},
});

const facetState = facetGenerator.facets;

expect(facetState.length).toEqual(4);
expect(facetState[0].state.facetId).toEqual(facets[0].facetId);
expect(facetState[1].state.facetId).toEqual(facets[1].facetId);
expect(facetState[2].state.facetId).toEqual(facets[2].facetId);
expect(facetState[3].state.facetId).toEqual(facets[3].facetId);
expect(facetState.length).toEqual(5);
expect(facetState.map((f) => f.state.facetId)).toEqual(
facets.map((f) => f.facetId)
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
CommerceFacetOptions,
CoreCommerceFacet,
} from '../headless-core-commerce-facet.js';
import {LocationFacet} from '../location/headless-commerce-location-facet.js';
import {NumericFacet} from '../numeric/headless-commerce-numeric-facet.js';
import {RegularFacet} from '../regular/headless-commerce-regular-facet.js';
import {SearchableFacetOptions} from '../searchable/headless-commerce-searchable-facet.js';
Expand All @@ -47,7 +48,7 @@ export interface FacetGenerator extends Controller {

/**
* The facet sub-controllers created by the facet generator.
* Array of [RegularFacet](./regular-facet), [DateRangeFacet](./date-range-facet), [NumericFacet](./numeric-facet), and [CategoryFacet](./category-facet).
* Array of [RegularFacet](./regular-facet), [DateRangeFacet](./date-range-facet), [NumericFacet](./numeric-facet), [CategoryFacet](./category-facet), and [LocationFacet](./location-facet).
*/
facets: GeneratedFacetControllers;

Expand Down Expand Up @@ -79,7 +80,9 @@ export type MappedGeneratedFacetController = {
? DateFacet
: T extends 'hierarchical'
? CategoryFacet
: never;
: T extends 'location'
? LocationFacet
: never;
};

type CommerceFacetBuilder<
Expand Down Expand Up @@ -108,6 +111,7 @@ export interface FacetGeneratorOptions {
buildNumericFacet: CommerceFacetBuilder<NumericFacet>;
buildDateFacet: CommerceFacetBuilder<DateFacet>;
buildCategoryFacet: CommerceFacetBuilder<CategoryFacet>;
buildLocationFacet: CommerceFacetBuilder<LocationFacet>;
fetchProductsActionCreator: FetchProductsActionCreator;
}

Expand Down Expand Up @@ -159,6 +163,8 @@ export function buildFacetGenerator(
return options.buildNumericFacet(engine, {facetId});
case 'regular':
return options.buildRegularFacet(engine, {facetId});
case 'location':
return options.buildLocationFacet(engine, {facetId});
}
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import {FacetType} from '../../../../features/commerce/facets/facet-set/interfac
import {
AnyFacetRequest,
CategoryFacetValueRequest,
LocationFacetValueRequest,
} from '../../../../features/commerce/facets/facet-set/interfaces/request.js';
import {
AnyFacetResponse,
AnyFacetValueResponse,
CategoryFacetValue,
DateFacetValue,
LocationFacetValue,
NumericFacetValue,
RegularFacetValue,
} from '../../../../features/commerce/facets/facet-set/interfaces/response.js';
Expand All @@ -37,6 +39,8 @@ export type {
FacetType,
FacetValueRequest,
RegularFacetValue,
LocationFacetValueRequest,
LocationFacetValue,
NumericRangeRequest,
NumericFacetValue,
DateRangeRequest,
Expand Down
Loading

0 comments on commit 503ec58

Please sign in to comment.