Skip to content

Commit

Permalink
new Events and localization for AttachResult and ResultsFilter compon…
Browse files Browse the repository at this point in the history
…ents (#28)

Added strings for defaults strings of AttachResult and ResultsFilter
Added events when attaching / detaching result and filtering
  • Loading branch information
mikegron committed Aug 20, 2019
1 parent 03a756a commit 9abe803
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 6 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"module": "./bin/es6/Index.js",
"types": "./bin/typings",
"sideEffects": [
"./bin/es6/components/AttachResult/Strings.js",
"./bin/es6/components/ResultsFilter/Strings.js",
"./bin/es6/components/UserActions/Strings.js",
"./bin/es6/components/ViewedByCustomer/Strings.js"
],
Expand Down
16 changes: 12 additions & 4 deletions src/components/AttachResult/AttachResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import {
IAnalyticsCaseAttachMeta,
IAnalyticsCaseDetachMeta,
analyticsActionCauseList,
IAnalyticsActionCause
IAnalyticsActionCause,
l
} from 'coveo-search-ui';
import { paperclipIcon } from '../../utils/icons';
import { AttachResultEvents, IAttachResultEventArgs } from './Events';
import './Strings';

/**
* Possible options to configure the **AttachResult** component.
*/
export interface IAttachResultOptions {
/** Specifies the tooltip displayed when the result is not attached. */
attachCaption?: string;
Expand All @@ -37,12 +43,12 @@ export class AttachResult extends Component {
private buttonElement: HTMLElement;
private tooltipElement: HTMLElement;

static options: IAttachResultOptions = {
public static readonly options: IAttachResultOptions = {
attachCaption: ComponentOptions.buildStringOption({
defaultValue: 'Attach Result'
defaultValue: l(`${AttachResult.ID}_Attach`)
}),
detachCaption: ComponentOptions.buildStringOption({
defaultValue: 'Detach Result'
defaultValue: l(`${AttachResult.ID}_Detach`)
}),
attach: ComponentOptions.buildCustomOption(
name => (result: IQueryResult) =>
Expand Down Expand Up @@ -111,6 +117,7 @@ export class AttachResult extends Component {
.then(() => {
this.attached = true;
this.logAnalyticsCaseEvent(analyticsActionCauseList.caseAttach);
Coveo.$$(this.root).trigger(AttachResultEvents.Attach, { queryResult: this.queryResult } as IAttachResultEventArgs);
})
.finally(() => {
this.setLoading(false);
Expand All @@ -131,6 +138,7 @@ export class AttachResult extends Component {
.then(() => {
this.attached = false;
this.logAnalyticsCaseEvent(analyticsActionCauseList.caseDetach);
Coveo.$$(this.root).trigger(AttachResultEvents.Detach, { queryResult: this.queryResult } as IAttachResultEventArgs);
})
.finally(() => {
this.setLoading(false);
Expand Down
20 changes: 20 additions & 0 deletions src/components/AttachResult/Events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { IQueryResult } from 'coveo-search-ui';

/**
* List of possible event types triggered by the **AttachResult** component
* when a user interacts with it.
*/
export enum AttachResultEvents {
Attach = 'attach',
Detach = 'detach'
}

/**
* Arguments sent with the events coming from the **AttachResult** component.
*/
export interface IAttachResultEventArgs {
/**
* The **IQueryResult** that is attached to the **AttachResult** component.
*/
queryResult: IQueryResult;
}
6 changes: 6 additions & 0 deletions src/components/AttachResult/Strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Translation, Language } from '../../utils/translation';

Translation.register(Language.English, {
AttachResult_Attach: 'Attach Result',
AttachResult_Detach: 'Detach Result'
});
16 changes: 16 additions & 0 deletions src/components/ResultsFilter/Events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Events triggered by the **ResultsFilter** component.
*/
export enum ResultsFilterEvents {
Click = 'click'
}

/**
* Arguments sent with the events coming from the **ResultsFilter** component.
*/
export interface IResultsFilterEventArgs {
/**
* Whether the filter is currently checked or not.
*/
checked: boolean;
}
14 changes: 12 additions & 2 deletions src/components/ResultsFilter/ResultsFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@ import {
IBuildingQueryEventArgs,
QueryStateModel,
load,
IAttributesChangedEventArg
IAttributesChangedEventArg,
l
} from 'coveo-search-ui';
import { ResultsFilterEvents, IResultsFilterEventArgs } from './Events';
import './Strings';

/**
* Metadata sent when an analytics event is sent.
*/
export interface IAnalyticsFilteredResultsMeta {
filteredResults: boolean;
}

/**
* Possible options to configure the **ResultsFilter** component.
*/
export interface IResultsFilterOptions {
/** Specifies the text displayed next to the checkbox. */
text?: string;
Expand All @@ -36,7 +45,7 @@ export class ResultsFilter extends Component {

static options: IResultsFilterOptions = {
text: ComponentOptions.buildStringOption({
defaultValue: 'Filter Results'
defaultValue: l(`${ResultsFilter.ID}_Label`)
}),
field: ComponentOptions.buildStringOption({
defaultValue: 'urihash'
Expand Down Expand Up @@ -97,6 +106,7 @@ export class ResultsFilter extends Component {
private handleCheckboxChange(checkbox: Checkbox) {
this.queryStateModel.set(QueryStateModel.getFacetId(ResultsFilter.ID), this.checkbox.isSelected());
this.triggerQuery();
Coveo.$$(this.root).trigger(ResultsFilterEvents.Click, { checked: this.checkbox.isSelected() } as IResultsFilterEventArgs);
}

private triggerQuery() {
Expand Down
5 changes: 5 additions & 0 deletions src/components/ResultsFilter/Strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Translation, Language } from '../../utils/translation';

Translation.register(Language.English, {
ResultsFilter_Label: 'Filter Results'
});
24 changes: 24 additions & 0 deletions tests/components/AttachResult/AttachResult.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AttachResult, IAttachResultOptions } from '../../../src/components/AttachResult/AttachResult';
import { Mock, Fake } from 'coveo-search-ui-tests';
import { IQueryResult, Logger } from 'coveo-search-ui';
import { AttachResultEvents, IAttachResultEventArgs } from '../../../src/components/AttachResult/Events';

describe('AttachResult', () => {
let attachResult: Mock.IBasicComponentSetup<AttachResult>;
Expand Down Expand Up @@ -55,6 +56,13 @@ describe('AttachResult', () => {
}, 50);
});

it('tooltip should contain the default localized string', async () => {
await attachResult.cmp.attach();
expect(attachResult.cmp.element.querySelector('.coveo-caption-for-icon').textContent).toBe('Detach Result');
await attachResult.cmp.detach();
expect(attachResult.cmp.element.querySelector('.coveo-caption-for-icon').textContent).toBe('Attach Result');
});

it('should be detached when isAttached returns false', done => {
isAttachedSpy.and.returnValue(Promise.resolve(false));
attachResult = Mock.optionsResultComponentSetup(AttachResult, { isAttached: faker.isAttached }, fakeResult);
Expand Down Expand Up @@ -129,6 +137,14 @@ describe('AttachResult', () => {
await attachResult.cmp.attach();
expect(attachResult.cmp.element.querySelector('.coveo-caption-for-icon').innerHTML).toBe('detach me');
});

it('should trigger the attach event', done => {
Coveo.$$(attachResult.env.root).on(AttachResultEvents.Attach, (evt: Event, args: IAttachResultEventArgs) => {
expect(args.queryResult).not.toBeNull();
done();
});
attachResult.cmp.attach();
});
});

describe('detach', () => {
Expand Down Expand Up @@ -186,6 +202,14 @@ describe('AttachResult', () => {
await attachResult.cmp.detach();
expect(attachResult.cmp.element.querySelector('.coveo-caption-for-icon').innerHTML).toBe('attach me');
});

it('should trigger the detach event', done => {
Coveo.$$(attachResult.env.root).on(AttachResultEvents.Detach, (evt: Event, args: IAttachResultEventArgs) => {
expect(args.queryResult).not.toBeNull();
done();
});
attachResult.cmp.detach();
});
});

describe('click', () => {
Expand Down
27 changes: 27 additions & 0 deletions tests/components/ResultsFilter/ResultsFilter.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ResultsFilter, IResultsFilterOptions } from '../../../src/components/ResultsFilter/ResultsFilter';
import { Mock, Simulate } from 'coveo-search-ui-tests';
import { QueryStateModel } from 'coveo-search-ui';
import { ResultsFilterEvents, IResultsFilterEventArgs } from '../../../src/components/ResultsFilter/Events';
import { Translation, Language } from '../../../src/utils/translation';

describe('ResultsFilter', () => {
let filter: Mock.IBasicComponentSetup<ResultsFilter>;
Expand Down Expand Up @@ -42,6 +44,31 @@ describe('ResultsFilter', () => {
expect(filter.cmp.isSelected()).toBeFalsy();
});

it('should trigger event with checked true when first toggling', () => {
return new Promise(resolve => {
Coveo.$$(filter.env.root).on(ResultsFilterEvents.Click, (evt: Event, args: IResultsFilterEventArgs) => {
expect(args.checked).toBeTruthy();
resolve();
});
filter.cmp.toggle();
});
});

it('should trigger event with checked false when toggling twice', () => {
return new Promise(resolve => {
filter.cmp.toggle();
Coveo.$$(filter.env.root).on(ResultsFilterEvents.Click, (evt: Event, args: IResultsFilterEventArgs) => {
expect(args.checked).toBeFalsy();
resolve();
});
filter.cmp.toggle();
});
});

it('should contain the default label string', () => {
expect(filter.cmp.element.querySelector('span').innerText).toBe('Filter Results');
});

describe('when setting options', () => {
beforeEach(() => {
filter = Mock.optionsComponentSetup<ResultsFilter, IResultsFilterOptions>(ResultsFilter, {
Expand Down

0 comments on commit 9abe803

Please sign in to comment.