UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

130 lines (108 loc) 4.15 kB
import * as Globalize from 'globalize'; import { RangeType, IRangeValue, RangeEndScope } from '../../../rest/RangeValue'; import { NumberUtils } from '../../../utils/NumberUtils'; import { isNull } from 'util'; import { DateUtils } from '../../../utils/DateUtils'; import { IDynamicFacetRange, DynamicFacetRangeValueFormat } from '../IDynamicFacetRange'; import { Logger } from '../../../misc/Logger'; import { CurrencyUtils } from '../../../Core'; import { isUndefined } from 'underscore'; export class DynamicFacetRangeValueParser { constructor(private facet: IDynamicFacetRange) {} private get valueFormat() { return this.facet.options.valueFormat; } private get valueSeparator() { return this.facet.options.valueSeparator; } private parseDateFromRangeType(value: RangeType) { const parsedDate = DateUtils.convertToStandardDate(value); if (!DateUtils.isValid(parsedDate)) { new Logger(this).warn('Date value is not valid', value); return null; } return parsedDate; } private formatDisplayValueFromLimit(value: RangeType) { switch (this.valueFormat) { case DynamicFacetRangeValueFormat.number: const numberOfDecimals = isUndefined(this.facet.options.numberOfDecimals) ? NumberUtils.countDecimals(`${value}`) : this.facet.options.numberOfDecimals; return Globalize.format(value, `n${numberOfDecimals}`); case DynamicFacetRangeValueFormat.currency: return CurrencyUtils.currencyToString(parseFloat(`${value}`), { symbol: this.facet.options.currencySymbol, decimals: NumberUtils.countDecimals(`${value}`) ? 2 : 0 }); case DynamicFacetRangeValueFormat.date: return DateUtils.dateToString(this.parseDateFromRangeType(value), { alwaysIncludeTime: false, includeTimeIfThisWeek: false, includeTimeIfToday: false, omitYearIfCurrentOne: false, useTodayYesterdayAndTomorrow: false, useWeekdayIfThisWeek: false }); default: return `${value}`; } } public formatDisplayValue(range: IRangeValue) { const formattedStart = this.formatDisplayValueFromLimit(range.start); const formattedEnd = this.formatDisplayValueFromLimit(range.end); return `${formattedStart} ${this.valueSeparator} ${formattedEnd}`; } private validateRangeLimit(value: RangeType) { switch (this.valueFormat) { case DynamicFacetRangeValueFormat.number: case DynamicFacetRangeValueFormat.currency: return this.validateNumberValue(value); case DynamicFacetRangeValueFormat.date: return this.validateDateValue(value); default: return `${value}`; } } private validateNumberValue(value: RangeType) { const number = parseFloat(`${value}`); return isNaN(number) ? null : number; } private validateDateValue(value: RangeType) { const parsedValue = DateUtils.dateTimeForQuery(this.parseDateFromRangeType(value)); return parsedValue === 'Invalid date' ? null : parsedValue; } public validate(unvalidatedRange: IRangeValue): IRangeValue { const start = this.validateRangeLimit(unvalidatedRange.start); const end = this.validateRangeLimit(unvalidatedRange.end); if (isNull(start) || isNull(end)) { return null; } return { ...unvalidatedRange, start, end }; } public formatValue(range: IRangeValue) { const scope = range.endInclusive ? RangeEndScope.Inclusive : RangeEndScope.Exclusive; return `${range.start}..${range.end}${scope}`; } public parse(value: string): IRangeValue { const valueRegex = new RegExp(`^(.+)\\.\\.(.+)(${RangeEndScope.Inclusive}|${RangeEndScope.Exclusive})$`); const startAndEnd = valueRegex.exec(value); if (!startAndEnd) { return null; } const start = this.validateRangeLimit(startAndEnd[1]); const end = this.validateRangeLimit(startAndEnd[2]); if (isNull(start) || isNull(end)) { return null; } return { start, end, endInclusive: startAndEnd[3] === RangeEndScope.Inclusive }; } }