@coveo/quantic 3.37.7 → 3.37.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/force-app/main/default/lwc/quanticResult/quanticResult.js +1 -1
- package/force-app/main/default/lwc/quanticSearchBoxInput/quanticSearchBoxInput.js +5 -0
- package/force-app/main/default/lwc/quanticTimeframeFacet/__tests__/quanticTimeframeFacet.test.js +3 -3
- package/force-app/main/default/lwc/quanticTimeframeFacet/quanticTimeframeFacet.js +3 -3
- package/force-app/main/default/lwc/quanticUtils/__tests__/quanticUtils.test.js +0 -20
- package/force-app/main/default/lwc/quanticUtils/__tests__/timeAndDateUtils.test.js +22 -0
- package/force-app/main/default/lwc/quanticUtils/quanticUtils.js +1 -361
- package/force-app/main/default/lwc/quanticUtils/timeAndDateUtils.js +407 -0
- package/force-app/main/default/staticresources/coveoheadless/case-assist/headless.js +15 -15
- package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/core/generated-answer/headless-core-interactive-generated-answer-inline-link.d.ts +44 -0
- package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/generated-answer/headless-interactive-generated-answer-inline-link.d.ts +15 -0
- package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/smart-snippet/headless-smart-snippet-interactive-inline-links.d.ts +2 -11
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/generated-answer/generated-answer-analytics-actions.d.ts +5 -2
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/generated-answer/generated-answer-request.d.ts +2 -2
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/generated-answer/generated-answer-selectors.d.ts +1 -0
- package/force-app/main/default/staticresources/coveoheadless/definitions/index.d.ts +2 -0
- package/force-app/main/default/staticresources/coveoheadless/definitions/utils/inline-link.d.ts +10 -0
- package/force-app/main/default/staticresources/coveoheadless/headless.js +18 -18
- package/force-app/main/default/staticresources/coveoheadless/insight/headless.js +16 -16
- package/force-app/main/default/staticresources/coveoheadless/recommendation/headless.js +14 -14
- package/force-app/main/default/staticresources/dompurify/purify.min.js +2 -2
- package/package.json +7 -6
|
@@ -223,6 +223,11 @@ export default class QuanticSearchBoxInput extends LightningElement {
|
|
|
223
223
|
* @param {KeyboardEvent} event
|
|
224
224
|
*/
|
|
225
225
|
onKeyDown(event) {
|
|
226
|
+
// Let the browser commit IME text before handling shortcuts like Enter during composition.
|
|
227
|
+
if (event.isComposing || event.keyCode === 229) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
226
231
|
// eslint-disable-next-line default-case
|
|
227
232
|
switch (event.key) {
|
|
228
233
|
case keys.ESC:
|
package/force-app/main/default/lwc/quanticTimeframeFacet/__tests__/quanticTimeframeFacet.test.js
CHANGED
|
@@ -13,14 +13,14 @@ jest.mock('c/quanticUtils', () => ({
|
|
|
13
13
|
},
|
|
14
14
|
I18nUtils: {
|
|
15
15
|
format: jest.fn(),
|
|
16
|
+
getLabelNameWithCount: jest.fn(),
|
|
17
|
+
},
|
|
18
|
+
DateUtils: {
|
|
16
19
|
formatDate: jest.fn(
|
|
17
20
|
(date) =>
|
|
18
21
|
`${date.getUTCFullYear()}-${date.getUTCMonth() + 1}-${date.getUTCDate()}`
|
|
19
22
|
),
|
|
20
23
|
getShortDatePattern: jest.fn(),
|
|
21
|
-
getLabelNameWithCount: jest.fn(),
|
|
22
|
-
},
|
|
23
|
-
DateUtils: {
|
|
24
24
|
fromLocalIsoDate: jest.fn((value) => value),
|
|
25
25
|
toLocalSearchApiDate: jest.fn((value) => value),
|
|
26
26
|
},
|
|
@@ -387,7 +387,7 @@ export default class QuanticTimeframeFacet extends LightningElement {
|
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
get datepickerFormat() {
|
|
390
|
-
return
|
|
390
|
+
return DateUtils.getShortDatePattern();
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
/**
|
|
@@ -621,10 +621,10 @@ export default class QuanticTimeframeFacet extends LightningElement {
|
|
|
621
621
|
}
|
|
622
622
|
|
|
623
623
|
const start = fromSearchApiDate(facetValue.start);
|
|
624
|
-
const startDate =
|
|
624
|
+
const startDate = DateUtils.formatDate(new Date(start));
|
|
625
625
|
|
|
626
626
|
const end = fromSearchApiDate(facetValue.end);
|
|
627
|
-
const endDate =
|
|
627
|
+
const endDate = DateUtils.formatDate(new Date(end));
|
|
628
628
|
|
|
629
629
|
return `${startDate} - ${endDate}`;
|
|
630
630
|
};
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
I18nUtils,
|
|
3
3
|
buildTemplateTextFromResult,
|
|
4
4
|
copyToClipboard,
|
|
5
|
-
TimeSpan,
|
|
6
5
|
} from 'c/quanticUtils';
|
|
7
6
|
|
|
8
7
|
describe('c/quanticUtils', () => {
|
|
@@ -201,23 +200,4 @@ describe('c/quanticUtils', () => {
|
|
|
201
200
|
);
|
|
202
201
|
});
|
|
203
202
|
});
|
|
204
|
-
|
|
205
|
-
describe('TimeSpan', () => {
|
|
206
|
-
describe('getYoutubeFormatTimestamp', () => {
|
|
207
|
-
it('should return the correct YouTube timestamp format for timestamps of less than a minute', () => {
|
|
208
|
-
const timeSpan = new TimeSpan(45000); // 45 seconds
|
|
209
|
-
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('0:45');
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should return the correct YouTube timestamp format for timestamps of more than an hour', () => {
|
|
213
|
-
const timeSpan = new TimeSpan(3661000); // 1 hour, 1 minute, and 1 second
|
|
214
|
-
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('1:01:01');
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it('should return the correct YouTube timestamp format for timestamps of less than an hour', () => {
|
|
218
|
-
const timeSpan = new TimeSpan(300000); // 5 minutes
|
|
219
|
-
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('05:00');
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
203
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {TimeSpan} from '../timeAndDateUtils';
|
|
2
|
+
|
|
3
|
+
describe('quanticUtils/timeAndDateUtils', () => {
|
|
4
|
+
describe('TimeSpan', () => {
|
|
5
|
+
describe('getYoutubeFormatTimestamp', () => {
|
|
6
|
+
it('should return the correct YouTube timestamp format for timestamps of less than a minute', () => {
|
|
7
|
+
const timeSpan = new TimeSpan(45000);
|
|
8
|
+
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('0:45');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should return the correct YouTube timestamp format for timestamps of more than an hour', () => {
|
|
12
|
+
const timeSpan = new TimeSpan(3661000);
|
|
13
|
+
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('1:01:01');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return the correct YouTube timestamp format for timestamps of less than an hour', () => {
|
|
17
|
+
const timeSpan = new TimeSpan(300000);
|
|
18
|
+
expect(timeSpan.getYoutubeFormatTimestamp()).toBe('05:00');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -1,33 +1,4 @@
|
|
|
1
1
|
import LOCALE from '@salesforce/i18n/locale';
|
|
2
|
-
import dayPattern from '@salesforce/label/c.quantic_DatePatternDay';
|
|
3
|
-
import monthPattern from '@salesforce/label/c.quantic_DatePatternMonth';
|
|
4
|
-
import yearPattern from '@salesforce/label/c.quantic_DatePatternYear';
|
|
5
|
-
import nextDay from '@salesforce/label/c.quantic_NextDay';
|
|
6
|
-
import nextDay_plural from '@salesforce/label/c.quantic_NextDay_plural';
|
|
7
|
-
import nextHour from '@salesforce/label/c.quantic_NextHour';
|
|
8
|
-
import nextHour_plural from '@salesforce/label/c.quantic_NextHour_plural';
|
|
9
|
-
import nextMonth from '@salesforce/label/c.quantic_NextMonth';
|
|
10
|
-
import nextMonth_plural from '@salesforce/label/c.quantic_NextMonth_plural';
|
|
11
|
-
import nextQuarter from '@salesforce/label/c.quantic_NextQuarter';
|
|
12
|
-
import nextQuarter_plural from '@salesforce/label/c.quantic_NextQuarter_plural';
|
|
13
|
-
import nextWeek from '@salesforce/label/c.quantic_NextWeek';
|
|
14
|
-
import nextWeek_plural from '@salesforce/label/c.quantic_NextWeek_plural';
|
|
15
|
-
import nextYear from '@salesforce/label/c.quantic_NextYear';
|
|
16
|
-
import nextYear_plural from '@salesforce/label/c.quantic_NextYear_plural';
|
|
17
|
-
import pastDay from '@salesforce/label/c.quantic_PastDay';
|
|
18
|
-
import pastDay_plural from '@salesforce/label/c.quantic_PastDay_plural';
|
|
19
|
-
|
|
20
|
-
/** @typedef {import("coveo").RelativeDate} RelativeDate */
|
|
21
|
-
import pastHour from '@salesforce/label/c.quantic_PastHour';
|
|
22
|
-
import pastHour_plural from '@salesforce/label/c.quantic_PastHour_plural';
|
|
23
|
-
import pastMonth from '@salesforce/label/c.quantic_PastMonth';
|
|
24
|
-
import pastMonth_plural from '@salesforce/label/c.quantic_PastMonth_plural';
|
|
25
|
-
import pastQuarter from '@salesforce/label/c.quantic_PastQuarter';
|
|
26
|
-
import pastQuarter_plural from '@salesforce/label/c.quantic_PastQuarter_plural';
|
|
27
|
-
import pastWeek from '@salesforce/label/c.quantic_PastWeek';
|
|
28
|
-
import pastWeek_plural from '@salesforce/label/c.quantic_PastWeek_plural';
|
|
29
|
-
import pastYear from '@salesforce/label/c.quantic_PastYear';
|
|
30
|
-
import pastYear_plural from '@salesforce/label/c.quantic_PastYear_plural';
|
|
31
2
|
|
|
32
3
|
/** @typedef {import("coveo").Result} Result */
|
|
33
4
|
/** @typedef {import("coveo").SortCriterion} SortCriterion */
|
|
@@ -36,6 +7,7 @@ export * from './recentQueriesUtils';
|
|
|
36
7
|
export * from './markdownUtils';
|
|
37
8
|
export * from './facetDependenciesUtils';
|
|
38
9
|
export * from './citationAnchoringUtils';
|
|
10
|
+
export * from './timeAndDateUtils';
|
|
39
11
|
|
|
40
12
|
/**
|
|
41
13
|
* Utility class for debouncing function calls.
|
|
@@ -227,38 +199,6 @@ export class I18nUtils {
|
|
|
227
199
|
);
|
|
228
200
|
}
|
|
229
201
|
|
|
230
|
-
/**
|
|
231
|
-
* Gets the short date pattern for the current locale.
|
|
232
|
-
* @returns {string} The short date pattern.
|
|
233
|
-
* @example `M/d/yyyy` for `en-US`, `d/M/yyyy` for `fr-FR`, etc.
|
|
234
|
-
*/
|
|
235
|
-
static getShortDatePattern() {
|
|
236
|
-
const date = new Date(2000, 2, 4); // month is zero-based
|
|
237
|
-
const dateAsString = I18nUtils.formatDate(date);
|
|
238
|
-
|
|
239
|
-
const day = I18nUtils.format(dayPattern);
|
|
240
|
-
const month = I18nUtils.format(monthPattern);
|
|
241
|
-
const year = I18nUtils.format(yearPattern);
|
|
242
|
-
|
|
243
|
-
return dateAsString
|
|
244
|
-
.replace('2000', year.repeat(4))
|
|
245
|
-
.replace('00', year.repeat(2)) // for 2-digits year
|
|
246
|
-
.replace('03', month.repeat(2))
|
|
247
|
-
.replace('3', month) // for single-digit month
|
|
248
|
-
.replace('04', day.repeat(2))
|
|
249
|
-
.replace('4', day);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Formats the date in the current locale.
|
|
254
|
-
* @param {Date} date
|
|
255
|
-
* @returns {string} The formatted date.
|
|
256
|
-
*/
|
|
257
|
-
static formatDate(date) {
|
|
258
|
-
const formattedDate = new Intl.DateTimeFormat(LOCALE).format(date);
|
|
259
|
-
return formattedDate;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
202
|
/**
|
|
263
203
|
* @param {string} html
|
|
264
204
|
* @returns {string}
|
|
@@ -319,306 +259,6 @@ export function parseXML(string) {
|
|
|
319
259
|
return new window.DOMParser().parseFromString(string, 'text/xml');
|
|
320
260
|
}
|
|
321
261
|
|
|
322
|
-
/**
|
|
323
|
-
* Utility class for time-based calculations and formatting.
|
|
324
|
-
* Provides methods to convert between different time units and format durations.
|
|
325
|
-
*/
|
|
326
|
-
export class TimeSpan {
|
|
327
|
-
constructor(time, isMilliseconds = true) {
|
|
328
|
-
if (isMilliseconds) {
|
|
329
|
-
this.milliseconds = time;
|
|
330
|
-
} else {
|
|
331
|
-
this.milliseconds = time * 1000;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
getMilliseconds() {
|
|
336
|
-
return this.milliseconds;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
getSeconds() {
|
|
340
|
-
return this.getMilliseconds() / 1000;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
getMinutes() {
|
|
344
|
-
return this.getSeconds() / 60;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
getHours() {
|
|
348
|
-
return this.getMinutes() / 60;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
getDays() {
|
|
352
|
-
return this.getHours() / 24;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
getWeeks() {
|
|
356
|
-
return this.getDays() / 7;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
getHHMMSS() {
|
|
360
|
-
const hours = Math.floor(this.getHours());
|
|
361
|
-
const minutes = Math.floor(this.getMinutes()) % 60;
|
|
362
|
-
const seconds = Math.floor(this.getSeconds()) % 60;
|
|
363
|
-
let hoursString, minutesString, secondsString;
|
|
364
|
-
if (hours === 0) {
|
|
365
|
-
hoursString = '';
|
|
366
|
-
} else {
|
|
367
|
-
hoursString = hours < 10 ? '0' + hours.toString() : hours.toString();
|
|
368
|
-
}
|
|
369
|
-
minutesString =
|
|
370
|
-
minutes < 10 ? '0' + minutes.toString() : minutes.toString();
|
|
371
|
-
secondsString =
|
|
372
|
-
seconds < 10 ? '0' + seconds.toString() : seconds.toString();
|
|
373
|
-
const hhmmss =
|
|
374
|
-
(hoursString !== '' ? hoursString + ':' : '') +
|
|
375
|
-
minutesString +
|
|
376
|
-
':' +
|
|
377
|
-
secondsString;
|
|
378
|
-
return hhmmss;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
getYoutubeFormatTimestamp() {
|
|
382
|
-
const hours = Math.floor(this.getHours());
|
|
383
|
-
const minutes = Math.floor(this.getMinutes()) % 60;
|
|
384
|
-
const seconds = Math.floor(this.getSeconds()) % 60;
|
|
385
|
-
|
|
386
|
-
const formattedSeconds = seconds < 10 ? '0' + seconds : seconds;
|
|
387
|
-
|
|
388
|
-
if (hours > 0) {
|
|
389
|
-
const formattedMinutes = minutes < 10 ? '0' + minutes : minutes;
|
|
390
|
-
return hours + ':' + formattedMinutes + ':' + formattedSeconds;
|
|
391
|
-
}
|
|
392
|
-
const formattedMinutes =
|
|
393
|
-
minutes === 0 ? '0' : minutes < 10 ? '0' + minutes : minutes;
|
|
394
|
-
return formattedMinutes + ':' + formattedSeconds;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
getCleanHHMMSS() {
|
|
398
|
-
return this.getHHMMSS().replace(/^0+/, '');
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Utility class for date operations and formatting.
|
|
404
|
-
* Handles conversion between different date formats and provides parsing utilities.
|
|
405
|
-
*/
|
|
406
|
-
export class DateUtils {
|
|
407
|
-
/**
|
|
408
|
-
* Converts a date string from the Coveo Search API format to the ISO-8601 format.
|
|
409
|
-
* Replace `/` characters in date string with `-`.
|
|
410
|
-
* Replace `@` characters in date string with `T`.
|
|
411
|
-
* @param {string} dateString
|
|
412
|
-
* @returns {string}
|
|
413
|
-
*/
|
|
414
|
-
static fromSearchApiDate(dateString) {
|
|
415
|
-
return dateString.replaceAll('/', '-').replaceAll('@', 'T');
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Converts a date object to the Search API format (`yyyy/MM/dd@hh:mm:ss`), using local time.
|
|
420
|
-
* @param {Date} date The date object to convert.
|
|
421
|
-
* @returns {string} The formatted date string.
|
|
422
|
-
*/
|
|
423
|
-
static toLocalSearchApiDate(date) {
|
|
424
|
-
const year = date.getFullYear().toString().padStart(4, '0');
|
|
425
|
-
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
426
|
-
const day = date.getDate().toString().padStart(2, '0');
|
|
427
|
-
const hours = date.getHours().toString().padStart(2, '0');
|
|
428
|
-
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
429
|
-
const seconds = date.getSeconds().toString().padStart(2, '0');
|
|
430
|
-
|
|
431
|
-
return `${year}/${month}/${day}@${hours}:${minutes}:${seconds}`;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Converts a date to the ISO formatted local date.
|
|
436
|
-
* @param {Date} date The date to convert.
|
|
437
|
-
* @returns {string} The formatted date string.
|
|
438
|
-
*/
|
|
439
|
-
static toLocalIsoDate(date) {
|
|
440
|
-
const year = date.getFullYear().toString().padStart(4, '0');
|
|
441
|
-
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
442
|
-
const day = date.getDate().toString().padStart(2, '0');
|
|
443
|
-
|
|
444
|
-
return `${year}-${month}-${day}T00:00:00`;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Parses an ISO-formatted date string to a date object, using the specified local time.
|
|
449
|
-
* @param {string} dateString The ISO formatted date string.
|
|
450
|
-
* @param {number} hours The local hours to set on the date.
|
|
451
|
-
* @param {number} minutes The local minutes to set on the date.
|
|
452
|
-
* @param {number} seconds The local seconds to set on the date.
|
|
453
|
-
* @throws {Error} If specified time is invalid.
|
|
454
|
-
* @returns {Date} The parsed date.
|
|
455
|
-
*/
|
|
456
|
-
static fromLocalIsoDate(dateString, hours, minutes, seconds) {
|
|
457
|
-
const isTimeValid =
|
|
458
|
-
hours >= 0 &&
|
|
459
|
-
hours <= 23 &&
|
|
460
|
-
minutes >= 0 &&
|
|
461
|
-
minutes <= 59 &&
|
|
462
|
-
seconds >= 0 &&
|
|
463
|
-
seconds <= 59;
|
|
464
|
-
if (!isTimeValid) {
|
|
465
|
-
throw new Error(
|
|
466
|
-
'The specified time is invalid. It must be between 00:00:00 and 23:59:59.'
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const withoutTime = DateUtils.trimIsoTime(dateString);
|
|
471
|
-
const time =
|
|
472
|
-
hours.toString().padStart(2, '0') +
|
|
473
|
-
':' +
|
|
474
|
-
minutes.toString().padStart(2, '0') +
|
|
475
|
-
':' +
|
|
476
|
-
seconds.toString().padStart(2, '0');
|
|
477
|
-
|
|
478
|
-
return new Date(`${withoutTime}T${time}`);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* Trims the time portion from an ISO 8601 date string.
|
|
483
|
-
* @param {string} dateString
|
|
484
|
-
* @returns {string}
|
|
485
|
-
*/
|
|
486
|
-
static trimIsoTime(dateString) {
|
|
487
|
-
const timeIdx = dateString.indexOf('T');
|
|
488
|
-
return timeIdx !== -1 ? dateString.substring(0, timeIdx) : dateString;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* @param {number} timestamp
|
|
493
|
-
* @returns {boolean}
|
|
494
|
-
*/
|
|
495
|
-
static isValidTimestamp(timestamp) {
|
|
496
|
-
let isValid = true;
|
|
497
|
-
try {
|
|
498
|
-
// eslint-disable-next-line no-new
|
|
499
|
-
new Date(timestamp);
|
|
500
|
-
} catch (error) {
|
|
501
|
-
isValid = false;
|
|
502
|
-
}
|
|
503
|
-
return isValid;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Parses a given timestamp into detailed date components.
|
|
508
|
-
* @param {number} timestamp - The timestamp in milliseconds since January 1, 1970 (epoch time).
|
|
509
|
-
* @returns {Object} An object containing the following date details:
|
|
510
|
-
* - {number} year - The four-digit year (for example, 2024).
|
|
511
|
-
* - {string} month - The full name of the month (for example, "August").
|
|
512
|
-
* - {string} dayOfWeek - The abbreviated name of the day of the week (for example, "Mon").
|
|
513
|
-
* - {number} day - The day of the month (for example, 26).
|
|
514
|
-
* - {number} hours - The hour of the day in 24-hour format (0-23).
|
|
515
|
-
* - {number} minutes - The minutes of the hour (0-59).
|
|
516
|
-
*/
|
|
517
|
-
static parseTimestampToDateDetails(timestamp) {
|
|
518
|
-
const daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
519
|
-
const months = [
|
|
520
|
-
'January',
|
|
521
|
-
'February',
|
|
522
|
-
'March',
|
|
523
|
-
'April',
|
|
524
|
-
'May',
|
|
525
|
-
'June',
|
|
526
|
-
'July',
|
|
527
|
-
'August',
|
|
528
|
-
'September',
|
|
529
|
-
'October',
|
|
530
|
-
'November',
|
|
531
|
-
'December',
|
|
532
|
-
];
|
|
533
|
-
|
|
534
|
-
const date = new Date(timestamp);
|
|
535
|
-
const dayOfWeek = daysOfWeek[date.getDay()];
|
|
536
|
-
const month = months[date.getMonth()];
|
|
537
|
-
const day = date.getDate();
|
|
538
|
-
const year = date.getFullYear();
|
|
539
|
-
const hours = date.getHours();
|
|
540
|
-
const minutes = date.getMinutes();
|
|
541
|
-
|
|
542
|
-
return {
|
|
543
|
-
year,
|
|
544
|
-
month,
|
|
545
|
-
dayOfWeek,
|
|
546
|
-
day,
|
|
547
|
-
hours,
|
|
548
|
-
minutes,
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* Converts a date string from the Coveo Search API format to the ISO-8601 format.
|
|
555
|
-
* Replace `/` characters in date string with `-`.
|
|
556
|
-
* Replace `@` characters in date string with `T`.
|
|
557
|
-
* @param {string} dateString
|
|
558
|
-
* @returns {string}
|
|
559
|
-
*/
|
|
560
|
-
export function fromSearchApiDate(dateString) {
|
|
561
|
-
return DateUtils.fromSearchApiDate(dateString);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* Formats relative date ranges into human-readable strings.
|
|
566
|
-
* Supports past and future date ranges with proper pluralization.
|
|
567
|
-
*/
|
|
568
|
-
export class RelativeDateFormatter {
|
|
569
|
-
constructor() {
|
|
570
|
-
this.singularIndex = 0;
|
|
571
|
-
this.pluralIndex = 1;
|
|
572
|
-
|
|
573
|
-
this.labels = {
|
|
574
|
-
'past-hour': [pastHour, pastHour_plural],
|
|
575
|
-
'past-day': [pastDay, pastDay_plural],
|
|
576
|
-
'past-week': [pastWeek, pastWeek_plural],
|
|
577
|
-
'past-month': [pastMonth, pastMonth_plural],
|
|
578
|
-
'past-quarter': [pastQuarter, pastQuarter_plural],
|
|
579
|
-
'past-year': [pastYear, pastYear_plural],
|
|
580
|
-
'next-hour': [nextHour, nextHour_plural],
|
|
581
|
-
'next-day': [nextDay, nextDay_plural],
|
|
582
|
-
'next-week': [nextWeek, nextWeek_plural],
|
|
583
|
-
'next-month': [nextMonth, nextMonth_plural],
|
|
584
|
-
'next-quarter': [nextQuarter, nextQuarter_plural],
|
|
585
|
-
'next-year': [nextYear, nextYear_plural],
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Formats a relative date range into a human-readable string.
|
|
591
|
-
* @param {RelativeDate} begin The beginning of the relative date range.
|
|
592
|
-
* @param {RelativeDate} end The end of the relative date range.
|
|
593
|
-
* @returns {string} The formatted human-readable date range.
|
|
594
|
-
* @throws {Error} If the provided relative date range is invalid.
|
|
595
|
-
* @example
|
|
596
|
-
* begin = { period: 'past', unit: 'day', amount: 2 };
|
|
597
|
-
* end = { period: 'now', unit: 'day', amount: 1 };
|
|
598
|
-
* Output: "2 days ago - 1 day ago"
|
|
599
|
-
*/
|
|
600
|
-
formatRange(begin, end) {
|
|
601
|
-
const isPastRange = begin.period === 'past' && end.period === 'now';
|
|
602
|
-
const isNextRange = begin.period === 'now' && end.period === 'next';
|
|
603
|
-
|
|
604
|
-
if (!isPastRange && !isNextRange) {
|
|
605
|
-
throw new Error(
|
|
606
|
-
'The provided relative date range is invalid. Either "begin" or "end" must have the "period" set to "now".'
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
const relativeDate = isPastRange ? begin : end;
|
|
611
|
-
const label =
|
|
612
|
-
this.labels[`${relativeDate.period}-${relativeDate.unit}`][
|
|
613
|
-
I18nUtils.isSingular(relativeDate.amount)
|
|
614
|
-
? this.singularIndex
|
|
615
|
-
: this.pluralIndex
|
|
616
|
-
];
|
|
617
|
-
|
|
618
|
-
return I18nUtils.format(label, relativeDate.amount);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
|
|
622
262
|
/**
|
|
623
263
|
* Utility class for managing a simple in-memory store.
|
|
624
264
|
* Supports registering and retrieving facet and sort option data.
|