coveo-search-ui
Version:
Coveo JavaScript Search Framework
204 lines (163 loc) • 5.97 kB
text/typescript
import 'styling/DynamicFacet/_DynamicFacetValues';
import { $$ } from '../../../utils/Dom';
import { findWhere, find, escape } from 'underscore';
import { DynamicFacetValue } from './DynamicFacetValue';
import { IFacetResponse } from '../../../rest/Facet/FacetResponse';
import { FacetValueState } from '../../../rest/Facet/FacetValueState';
import { l } from '../../../strings/Strings';
import { IDynamicFacet, IValueCreator, IDynamicFacetValue, IDynamicFacetValues } from '../IDynamicFacet';
import { DynamicFacetValueShowMoreLessButton } from './DynamicFacetValueMoreLessButton';
import { Utils } from '../../../utils/Utils';
import { getDynamicFacetHeaderId } from '../DynamicFacetHeader/DynamicFacetHeader';
export interface IDynamicFacetValueCreatorKlass {
new (facet: IDynamicFacet): IValueCreator;
}
export class DynamicFacetValues implements IDynamicFacetValues {
private facetValues: IDynamicFacetValue[];
private list = $$('ul', {
className: 'coveo-dynamic-facet-values',
'aria-labelledby': getDynamicFacetHeaderId(this.facet.options.id),
role: 'group'
}).el;
private valueCreator: IValueCreator;
constructor(private facet: IDynamicFacet, creatorKlass: IDynamicFacetValueCreatorKlass) {
this.valueCreator = new creatorKlass(this.facet);
this.resetValues();
}
public createFromResponse(response: IFacetResponse) {
this.facetValues = response.values.map((facetValue, index) => this.valueCreator.createFromResponse(facetValue, index));
}
public reorderValues(order: string[]) {
this.facetValues = Utils.reorderValuesByKeys(this.facetValues, order, value => value.value);
}
public resetValues() {
this.facetValues = this.valueCreator.getDefaultValues();
}
public get allFacetValues() {
return this.facetValues;
}
public get allValues() {
return this.facetValues.map(facetValue => facetValue.value);
}
public get selectedValues() {
return this.facetValues.filter(value => value.isSelected).map(({ value }) => value);
}
private get selectedDisplayValues() {
return this.facetValues.filter(value => value.isSelected).map(({ displayValue }) => displayValue);
}
public get activeValues() {
return this.facetValues.filter(value => !value.isIdle);
}
private get displayedValues() {
return this.facetValues.filter(value => !value.isIdle || value.numberOfResults > 0);
}
public get hasSelectedValues() {
return !!findWhere(this.facetValues, { state: FacetValueState.selected });
}
public get hasActiveValues() {
return !!this.activeValues.length;
}
public get hasIdleValues() {
return !!findWhere(this.facetValues, { state: FacetValueState.idle });
}
public clearAll() {
this.facetValues.forEach(value => value.deselect());
}
public get hasValues() {
return !!this.allFacetValues.length;
}
public get hasDisplayedValues() {
return !!this.displayedValues.length;
}
public hasSelectedValue(arg: string | DynamicFacetValue) {
const value = typeof arg === 'string' ? arg : arg.value;
const foundValue = find(this.facetValues, facetValue => facetValue.equals(value));
return foundValue && foundValue.isSelected;
}
public get(arg: string | DynamicFacetValue) {
const value = typeof arg === 'string' ? arg : arg.value;
const facetValue = find(this.facetValues, facetValue => facetValue.equals(value));
if (facetValue) {
return facetValue;
}
const newFacetValue = this.valueCreator.createFromValue(value);
if (!newFacetValue) {
return null;
}
this.facetValues.push(newFacetValue);
return newFacetValue;
}
public focus(value: string) {
const facetValue = find(this.facetValues, facetValue => facetValue.equals(value));
if (!facetValue) {
return;
}
facetValue.focus();
}
private buildShowLess() {
const showLess = new DynamicFacetValueShowMoreLessButton({
className: 'coveo-dynamic-facet-show-less',
ariaLabel: l('ShowLessFacetResults', this.facet.options.title),
label: l('ShowLess'),
action: () => {
this.facet.enableFreezeFacetOrderFlag();
this.facet.showLessValues();
}
});
return showLess.element;
}
private buildShowMore() {
const showMore = new DynamicFacetValueShowMoreLessButton({
className: 'coveo-dynamic-facet-show-more',
ariaLabel: l('ShowMoreFacetResults', this.facet.options.title),
label: l('ShowMore'),
action: () => {
this.facet.enableFreezeFacetOrderFlag();
this.facet.showMoreValues();
}
});
return showMore.element;
}
private get shouldEnableShowLess() {
const hasMoreValuesThenDefault = this.facetValues.length > this.facet.options.numberOfValues;
return hasMoreValuesThenDefault && this.hasIdleValues;
}
private appendShowMoreLess(fragment: DocumentFragment) {
if (!this.facet.options.enableMoreLess) {
return;
}
if (this.shouldEnableShowLess) {
fragment.appendChild(this.buildShowLess());
}
if (this.facet.moreValuesAvailable) {
fragment.appendChild(this.buildShowMore());
}
}
private appendSelectedCollapsedValues(fragment: DocumentFragment) {
if (!this.hasSelectedValues) {
return;
}
const selectedValues = this.selectedDisplayValues.join(', ');
fragment.appendChild(
$$(
'li',
{
className: 'coveo-dynamic-facet-collapsed-values',
ariaLabel: `${l('CurrentSelections')}: ${selectedValues}`
},
escape(selectedValues)
).el
);
}
public render() {
const fragment = document.createDocumentFragment();
$$(this.list).empty();
this.displayedValues.forEach(facetValue => {
fragment.appendChild(facetValue.renderedElement);
});
this.appendShowMoreLess(fragment);
this.appendSelectedCollapsedValues(fragment);
this.list.appendChild(fragment);
return this.list;
}
}