Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new Events and localization for AttachResult and ResultsFilter components #28

Merged
merged 4 commits into from
Aug 20, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 {
mikegron marked this conversation as resolved.
Show resolved Hide resolved
/** 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 = {
mikegron marked this conversation as resolved.
Show resolved Hide resolved
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';
mikegron marked this conversation as resolved.
Show resolved Hide resolved

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 {
mikegron marked this conversation as resolved.
Show resolved Hide resolved
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';
mikegron marked this conversation as resolved.
Show resolved Hide resolved

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';
mikegron marked this conversation as resolved.
Show resolved Hide resolved

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