Skip to content

Commit

Permalink
Add options to specify categoryField + delimiter for FacetValueSugges…
Browse files Browse the repository at this point in the history
  • Loading branch information
olamothe committed Jul 24, 2019
1 parent aea0110 commit 782fc43
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 19 deletions.
47 changes: 34 additions & 13 deletions src/ui/FacetValueSuggestions/FacetValueSuggestions.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { Omnibox, IOmniboxSuggestion } from '../Omnibox/Omnibox';
import { Component } from '../Base/Component';
import { ComponentOptions, IFieldOption } from '../Base/ComponentOptions';
import { IComponentBindings } from '../Base/ComponentBindings';
import { OmniboxEvents, IPopulateOmniboxSuggestionsEventArgs } from '../../events/OmniboxEvents';
import { Initialization } from '../Base/Initialization';
import { analyticsActionCauseList, IAnalyticsNoMeta } from '../Analytics/AnalyticsActionListMeta';
import { $$ } from '../../utils/Dom';
import { exportGlobally } from '../../GlobalExports';
import 'styling/_FieldSuggestions';
import * as _ from 'underscore';
import { IPopulateOmniboxSuggestionsEventArgs, OmniboxEvents } from '../../events/OmniboxEvents';
import { exportGlobally } from '../../GlobalExports';
import { l } from '../../MiscModules';
import { QueryStateModel } from '../../ModelsModules';
import { $$ } from '../../utils/Dom';
import { DomUtils } from '../../UtilsModules';
import { IFacetValueSuggestionRow, FacetValueSuggestionsProvider, IFacetValueSuggestionsProvider } from './FacetValueSuggestionsProvider';
import { l } from '../../MiscModules';
import { analyticsActionCauseList, IAnalyticsNoMeta } from '../Analytics/AnalyticsActionListMeta';
import { Component } from '../Base/Component';
import { IComponentBindings } from '../Base/ComponentBindings';
import { ComponentOptions, IFieldOption } from '../Base/ComponentOptions';
import { Initialization } from '../Base/Initialization';
import { IOmniboxSuggestion, Omnibox } from '../Omnibox/Omnibox';
import { FacetValueSuggestionsProvider, IFacetValueSuggestionRow, IFacetValueSuggestionsProvider } from './FacetValueSuggestionsProvider';

export interface IFacetValueSuggestionsOptions {
numberOfSuggestions: number;
field?: IFieldOption;
isCategoryField?: boolean;
categoryFieldDelimitingCharacter?: string;
useQuerySuggestions?: boolean;
useValueFromSearchbox?: boolean;
displayEstimateNumberOfResults?: boolean;
Expand Down Expand Up @@ -131,7 +133,23 @@ export class FacetValueSuggestions extends Component {
*/
templateHelper: ComponentOptions.buildCustomOption<(row: IFacetValueSuggestionRow, omnibox: Omnibox) => string>(() => {
return null;
})
}),
/**
* Specifies wether the field to suggest is a "Category field", ie., it has the format used by the [`CategoryFacet`]{@link CategoryFacet} component.
*
* This option is required to ensure that on selection, the corresponding [`CategoryFacet`]{@link CategoryFacet} component in the page, if any, will properly handle the filter format.
*
* See also the [`categoryFieldDelimitingCharacter`]{@link categoryFieldDelimitingCharacter} option.
*
* Default value is `false`.
*/
isCategoryField: ComponentOptions.buildBooleanOption({ defaultValue: false }),
/**
* Specifies the delimiting character used by the category field, if the [`isCategoryField`]{@link isCategoryField} option is set to true.
*
* Default value is `|`.
*/
categoryFieldDelimitingCharacter: ComponentOptions.buildStringOption({ defaultValue: '|', depend: 'isCategoryField' })
};

public facetValueSuggestionsProvider: IFacetValueSuggestionsProvider;
Expand Down Expand Up @@ -262,7 +280,10 @@ export class FacetValueSuggestions extends Component {
// Copy the state here, else it will directly modify queryStateModel.defaultAttributes.fv.
const fvState: { [key: string]: string[] } = { ...this.queryStateModel.get(QueryStateModel.attributesEnum.fv) };
const existingValues: string[] = fvState[this.options.field.toString()] || [];
fvState[this.options.field.toString()] = existingValues.concat([row.value]);

const valuesToSetInState = this.options.isCategoryField ? row.value.split(this.options.categoryFieldDelimitingCharacter) : [row.value];
fvState[this.options.field.toString()] = existingValues.concat(valuesToSetInState);

this.queryStateModel.set(QueryStateModel.attributesEnum.fv, fvState);
omnibox.magicBox.blur();
this.usageAnalytics.logSearchEvent<IAnalyticsNoMeta>(analyticsActionCauseList.omniboxField, {});
Expand Down
61 changes: 55 additions & 6 deletions unitTests/ui/FacetValueSuggestionsTest.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { IFacetValueSuggestionsOptions, FacetValueSuggestions } from '../../src/ui/FacetValueSuggestions/FacetValueSuggestions';
import * as Mock from '../MockEnvironment';
import { IFieldOption } from '../../src/ui/Base/ComponentOptions';
import { $$, OmniboxEvents, QueryStateModel, l } from '../Test';
import { Omnibox, IOmniboxSuggestion } from '../../src/ui/Omnibox/Omnibox';
import { IPopulateOmniboxSuggestionsEventArgs } from '../../src/events/OmniboxEvents';
import { Suggestion } from '../../src/magicbox/SuggestionsManager';
import { IFieldOption } from '../../src/ui/Base/ComponentOptions';
import { FacetValueSuggestions, IFacetValueSuggestionsOptions } from '../../src/ui/FacetValueSuggestions/FacetValueSuggestions';
import { IFacetValueSuggestionRow, IFacetValueSuggestionsProvider } from '../../src/ui/FacetValueSuggestions/FacetValueSuggestionsProvider';
import { IOmniboxSuggestion, Omnibox } from '../../src/ui/Omnibox/Omnibox';
import { QuerySuggestAddon } from '../../src/ui/Omnibox/QuerySuggestAddon';
import { Suggestion } from '../../src/magicbox/SuggestionsManager';
import * as Mock from '../MockEnvironment';
import { $$, l, OmniboxEvents, QueryStateModel } from '../Test';

export function FacetValueSuggestionsTest() {
describe('FacetValueSuggestions', () => {
Expand Down Expand Up @@ -130,6 +130,55 @@ export function FacetValueSuggestionsTest() {
});
});

describe('when the field is a category field', () => {
beforeEach(() => {
setUpKeywordInOmnibox(aKeyword);
setUpOmniboxSuggestionsToReturn([getOmniboxSuggestionValue()]);
test.cmp.options.isCategoryField = true;
});

describe('with standard delimiter', () => {
beforeEach(() => {
setUpSuggestionsFromProviderToReturn([
{ field: someField, keyword: aKeyword, numberOfResults: 10, score: { distanceFromTotalForField: 100 }, value: 'a|b|c|d' }
]);
});

it('should modify the state by correctly splitting the field value', async done => {
const resultingArgs = await triggerPopulateOmniboxEvent();

firstSuggestion(resultingArgs).then(result => {
result[0].onSelect();
expect(test.env.queryStateModel.set).toHaveBeenCalledWith(QueryStateModel.attributesEnum.fv, {
[someField]: ['a', 'b', 'c', 'd']
});
done();
});
});
});

describe('with a custom delimiter', () => {
beforeEach(() => {
setUpSuggestionsFromProviderToReturn([
{ field: someField, keyword: aKeyword, numberOfResults: 10, score: { distanceFromTotalForField: 100 }, value: 'a>b>c>d' }
]);
test.cmp.options.categoryFieldDelimitingCharacter = '>';
});

it('should modify the state by correctly splitting the field value', async done => {
const resultingArgs = await triggerPopulateOmniboxEvent();

firstSuggestion(resultingArgs).then(result => {
result[0].onSelect();
expect(test.env.queryStateModel.set).toHaveBeenCalledWith(QueryStateModel.attributesEnum.fv, {
[someField]: ['a', 'b', 'c', 'd']
});
done();
});
});
});
});

describe('when no keywords are provided', () => {
beforeEach(() => {
setUpOmniboxSuggestionsToReturn([]);
Expand Down

0 comments on commit 782fc43

Please sign in to comment.