@webitel/ui-sdk 25.4.52 → 25.4.53

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [v25.4.52] - 2025-04-03
2
+ ### :sparkles: New Features
3
+ - [`8497209`](https://github.com/webitel/webitel-ui-sdk/commit/8497209e0a720302242feaf5a2038248f4f0727f) - added new locale and new icon for postprocessing form *(commit by [@liza-pohranichna](https://github.com/liza-pohranichna))*
4
+
5
+
1
6
  ## [v25.4.51] - 2025-04-03
2
7
  ### :bug: Bug Fixes
3
8
  - [`c87b176`](https://github.com/webitel/webitel-ui-sdk/commit/c87b1768de47753ceeb18045a200ded352b8405b) - delete enter days in timepicker component[WTEL-6651](https://webitel.atlassian.net/browse/WTEL-6651) *(commit by [@Lera24](https://github.com/Lera24))*
@@ -1814,3 +1819,4 @@
1814
1819
  [v25.4.48]: https://github.com/webitel/webitel-ui-sdk/compare/v25.4.47...v25.4.48
1815
1820
  [v25.4.49]: https://github.com/webitel/webitel-ui-sdk/compare/v25.4.48...v25.4.49
1816
1821
  [v25.4.51]: https://github.com/webitel/webitel-ui-sdk/compare/v25.4.50...v25.4.51
1822
+ [v25.4.52]: https://github.com/webitel/webitel-ui-sdk/compare/v25.4.51...v25.4.52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "25.4.52",
3
+ "version": "25.4.53",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "npm run docs:dev",
@@ -21,28 +21,26 @@
21
21
 
22
22
  "utils:link": "npm link",
23
23
  "utils:update-node": "nvm install --lts && nvm alias default node",
24
- "utils:i": "npm install",
25
-
26
- "prepare": "husky && husky install"
24
+ "utils:i": "npm install"
27
25
  },
28
26
  "main": "./dist/ui-sdk.js",
29
27
  "type": "module",
30
28
  "exports": {
31
29
  ".": "./dist/ui-sdk.js",
32
30
 
33
- "./store": "./src/store/new/index.js",
31
+ "./store": "./src/store/new/index",
34
32
  "./store*": "./src/store*",
35
33
  "./src/store*": "./src/store*",
36
34
 
37
- "./enums": "./src/enums/index.js",
35
+ "./enums": "./src/enums/index",
38
36
  "./enums*": "./src/enums*",
39
37
  "./src/enums*": "./src/enums*",
40
38
 
41
- "./components": "./src/components/index.js",
39
+ "./components": "./src/components/index",
42
40
  "./components*": "./src/components*",
43
41
  "./src/components*": "./src/components*",
44
42
 
45
- "./scripts": "./src/scripts/index.js",
43
+ "./scripts": "./src/scripts/index",
46
44
  "./scripts*": "./src/scripts*",
47
45
  "./src/scripts*": "./src/scripts*",
48
46
 
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -31,7 +30,6 @@ const getCloseReasonGroupsList = async (params) => {
31
30
 
32
31
  const { page, size, fields, sort, id, q } = applyTransform(params, [
33
32
  merge(getDefaultGetParams()),
34
- starToSearch('search'),
35
33
  (params) => ({ ...params, q: params.search }),
36
34
  sanitize(fieldsToSend),
37
35
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -31,7 +30,6 @@ const getCloseReasonsList = async ({ parentId, ...rest }) => {
31
30
 
32
31
  const { page, size, fields, sort, id, q } = applyTransform(rest, [
33
32
  merge(getDefaultGetParams()),
34
- starToSearch('search'),
35
33
  (params) => ({ ...params, q: params.search }),
36
34
  sanitize(fieldsToSend),
37
35
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -45,7 +44,6 @@ const getPrioritiesList = async (params) => {
45
44
  in_sla_cond: inSlaCond,
46
45
  } = applyTransform(params, [
47
46
  merge(getDefaultGetParams()),
48
- starToSearch('search'),
49
47
  (params) => ({ ...params, q: params.search }),
50
48
  sanitize(fieldsToSend),
51
49
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -34,7 +33,6 @@ const getSourcesList = async (params) => {
34
33
 
35
34
  const { page, size, fields, sort, id, q, type } = applyTransform(params, [
36
35
  merge(getDefaultGetParams()),
37
- starToSearch('search'),
38
36
  (params) => ({ ...params, q: params.search }),
39
37
  sanitize(fieldsToSend),
40
38
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -31,7 +30,6 @@ const getStatusConditionsList = async ({ parentId, ...rest }) => {
31
30
 
32
31
  const { page, size, fields, sort, id, q } = applyTransform(rest, [
33
32
  merge(getDefaultGetParams()),
34
- starToSearch('search'),
35
33
  (params) => ({ ...params, q: params.search }),
36
34
  sanitize(fieldsToSend),
37
35
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -27,7 +26,6 @@ const getStatusesList = async (params) => {
27
26
 
28
27
  const { page, size, fields, sort, id, q } = applyTransform(params, [
29
28
  merge(getDefaultGetParams()),
30
- starToSearch('search'),
31
29
  (params) => ({ ...params, q: params.search }),
32
30
  sanitize(fieldsToSend),
33
31
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -55,7 +54,6 @@ const getConditionsList = async ({ parentId, ...rest }) => {
55
54
  priority_id: priorityId,
56
55
  } = applyTransform(rest, [
57
56
  merge(getDefaultGetParams()),
58
- starToSearch('search'),
59
57
  (params) => ({ ...params, q: params.search }),
60
58
  sanitize(fieldsToSend),
61
59
  camelToSnake(),
@@ -12,7 +12,6 @@ import applyTransform, {
12
12
  notify,
13
13
  sanitize,
14
14
  snakeToCamel,
15
- starToSearch,
16
15
  } from '../../transformers/index.js';
17
16
 
18
17
  const instance = getDefaultInstance();
@@ -35,7 +34,6 @@ const getSlasList = async (params) => {
35
34
 
36
35
  const { page, size, fields, sort, id, q } = applyTransform(params, [
37
36
  merge(getDefaultGetParams()),
38
- starToSearch('search'),
39
37
  (params) => ({ ...params, q: params.search }),
40
38
  sanitize(fieldsToSend),
41
39
  camelToSnake(),
@@ -0,0 +1,11 @@
1
+ const valuePrefix = 'rdt'; /* stands for relative datetime */
2
+
3
+ export const RelativeDatetimeValue = {
4
+ Today: `${valuePrefix}_today`,
5
+ ThisWeek: `${valuePrefix}_this_week`,
6
+ ThisMonth: `${valuePrefix}_this_month`,
7
+ Custom: `${valuePrefix}_custom`,
8
+ } as const;
9
+
10
+ export type RelativeDatetimeValue =
11
+ (typeof RelativeDatetimeValue)[keyof typeof RelativeDatetimeValue];
@@ -5,6 +5,7 @@ import { ComponentSize } from './ComponentSize/ComponentSize';
5
5
  import { CrudAction } from './CrudAction/CrudAction';
6
6
  import IconAction from './IconAction/IconAction.enum.js';
7
7
  import QueueType from './QueueType/QueueType.enum.js';
8
+ import { RelativeDatetimeValue } from './RelativeDatetimeValue/RelativeDatetimeValue';
8
9
  import TypesExportedSettings from './TypesExportedSettings/TypesExportedSettings.enum.js';
9
10
  import { AdminSections } from './WebitelApplications/AdminSections';
10
11
  import { AuditorSections } from './WebitelApplications/AuditorSections';
@@ -13,6 +14,7 @@ import { SupervisorSections } from './WebitelApplications/SupervisorSections';
13
14
  import WebitelApplications from './WebitelApplications/WebitelApplications.enum.js';
14
15
  import { WtApplication } from './WebitelApplications/WtApplication';
15
16
  import { WtObject } from './WtObject/WtObject';
17
+
16
18
  export {
17
19
  AbstractUserStatus,
18
20
  AdminSections,
@@ -24,6 +26,7 @@ export {
24
26
  CrudAction,
25
27
  IconAction,
26
28
  QueueType,
29
+ RelativeDatetimeValue,
27
30
  SupervisorSections,
28
31
  TypesExportedSettings,
29
32
  WebitelApplications,
@@ -5,6 +5,7 @@ import { ComponentSize } from './ComponentSize/ComponentSize';
5
5
  import { CrudAction } from './CrudAction/CrudAction';
6
6
  import IconAction from './IconAction/IconAction.enum.js';
7
7
  import QueueType from './QueueType/QueueType.enum.js';
8
+ import { RelativeDatetimeValue } from './RelativeDatetimeValue/RelativeDatetimeValue';
8
9
  import TypesExportedSettings from './TypesExportedSettings/TypesExportedSettings.enum.js';
9
10
  import { AdminSections } from './WebitelApplications/AdminSections';
10
11
  import { AuditorSections } from './WebitelApplications/AuditorSections';
@@ -25,6 +26,7 @@ export {
25
26
  CrudAction,
26
27
  IconAction,
27
28
  QueueType,
29
+ RelativeDatetimeValue,
28
30
  SupervisorSections,
29
31
  TypesExportedSettings,
30
32
  WebitelApplications,
@@ -6,16 +6,19 @@ import {
6
6
  EngineRoutingSchemaType,
7
7
  } from 'webitel-sdk';
8
8
 
9
- import { IconAction } from '../../enums';
10
- import ChatGatewayProvider from '../../enums/ChatGatewayProvider/ChatGatewayProvider.enum.js';
11
- import QueueType from '../../enums/QueueType/QueueType.enum.js';
12
- import AdminSections from '../../enums/WebitelApplications/AdminSections.enum.js';
13
- import AuditorSections from '../../enums/WebitelApplications/AuditorSections.enum.js';
14
- import CrmSections from '../../enums/WebitelApplications/CrmSections.enum.js';
15
- import SupervisorSections from '../../enums/WebitelApplications/SupervisorSections.enum.js';
16
- import WebitelApplications from '../../enums/WebitelApplications/WebitelApplications.enum.js';
9
+ import {
10
+ SupervisorSections,
11
+ WebitelApplications,
12
+ CrmSections,
13
+ AuditorSections,
14
+ AdminSections,
15
+ QueueType,
16
+ IconAction,
17
+ RelativeDatetimeValue,
18
+ ChatGatewayProvider,
19
+ } from '../../enums';
20
+ import { snakeToCamel } from '../../scripts';
17
21
  import { AccessMode } from '../../modules/ObjectPermissions/_internals/enums/AccessMode.enum.js';
18
- import { snakeToCamel } from '../../scripts/caseConverters.js';
19
22
 
20
23
  export default {
21
24
  // describes reusable buttons, actions, default titles, and other ui elements
@@ -62,7 +65,7 @@ export default {
62
65
  retry: 'Retry',
63
66
  downloadAll: 'Download all',
64
67
  warning: 'Warning',
65
- doNotSave: "Don't save",
68
+ doNotSave: 'Don\'t save',
66
69
  required: 'Required',
67
70
  copy: 'Copy',
68
71
  new: 'New',
@@ -425,10 +428,12 @@ export default {
425
428
  [IconAction.SAVE]: ({ linked }) => linked('reusable.save'),
426
429
  [IconAction.CANCEL]: ({ linked }) => linked('reusable.cancel'),
427
430
  [IconAction.SAVE_PRESET]: ({ linked }) => {
428
- return `${linked('reusable.save')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
431
+ return `${linked('reusable.save')} ${linked('webitelUI.filters.presets.preset')
432
+ .toLowerCase()}`;
429
433
  },
430
434
  [IconAction.APPLY_PRESET]: ({ linked }) => {
431
- return `${linked('vocabulary.apply')} ${linked('webitelUI.filters.presets.preset').toLowerCase()}`;
435
+ return `${linked('vocabulary.apply')} ${linked('webitelUI.filters.presets.preset')
436
+ .toLowerCase()}`;
432
437
  },
433
438
  },
434
439
  },
@@ -439,8 +444,8 @@ export default {
439
444
  text: 'Sorry, you have not enough privileges to see this page.',
440
445
  },
441
446
  page404: {
442
- title: "Looks like you're lost",
443
- text: "Sorry, we can't find the page you want.",
447
+ title: 'Looks like you\'re lost',
448
+ text: 'Sorry, we can\'t find the page you want.',
444
449
  },
445
450
  },
446
451
  copyAction: {
@@ -494,12 +499,11 @@ export default {
494
499
  exportToJson: 'Export to JSON',
495
500
  },
496
501
  filters: {
497
- predefinedLabels: {
498
- /* https://webitel.atlassian.net/browse/WTEL-6308?focusedCommentId=657415 */
499
- createdAt: {
500
- startOfToday: 'From the start of today',
501
- startOfMonth: 'From this month',
502
- },
502
+ datetime: {
503
+ [RelativeDatetimeValue.Today]: 'Today',
504
+ [RelativeDatetimeValue.ThisWeek]: 'This week',
505
+ [RelativeDatetimeValue.ThisMonth]: 'This month',
506
+ [RelativeDatetimeValue.Custom]: 'Custom date range',
503
507
  },
504
508
  addFilter: ({ linked }) => {
505
509
  return `${linked('reusable.add')} a ${linked(
@@ -550,6 +554,9 @@ export default {
550
554
  contactGroup: ({ linked }) => {
551
555
  return linked('cases.groupPerformers');
552
556
  },
557
+ createdAt: ({ linked }) => {
558
+ return linked('reusable.createdAt');
559
+ },
553
560
  createdAtFrom: ({ linked }) => {
554
561
  return linked('reusable.from');
555
562
  },
@@ -6,16 +6,19 @@ import {
6
6
  EngineRoutingSchemaType,
7
7
  } from 'webitel-sdk';
8
8
 
9
- import { IconAction } from '../../enums';
10
- import ChatGatewayProvider from '../../enums/ChatGatewayProvider/ChatGatewayProvider.enum.js';
11
- import QueueType from '../../enums/QueueType/QueueType.enum.js';
12
- import AdminSections from '../../enums/WebitelApplications/AdminSections.enum.js';
13
- import AuditorSections from '../../enums/WebitelApplications/AuditorSections.enum.js';
14
- import CrmSections from '../../enums/WebitelApplications/CrmSections.enum.js';
15
- import SupervisorSections from '../../enums/WebitelApplications/SupervisorSections.enum.js';
16
- import WebitelApplications from '../../enums/WebitelApplications/WebitelApplications.enum.js';
9
+ import {
10
+ AdminSections,
11
+ AuditorSections,
12
+ ChatGatewayProvider,
13
+ CrmSections,
14
+ IconAction,
15
+ QueueType,
16
+ RelativeDatetimeValue,
17
+ SupervisorSections,
18
+ WebitelApplications,
19
+ } from '../../enums';
17
20
  import { AccessMode } from '../../modules/ObjectPermissions/_internals/enums/AccessMode.enum.js';
18
- import { snakeToCamel } from '../../scripts/caseConverters.js';
21
+ import { snakeToCamel } from '../../scripts';
19
22
 
20
23
  export default {
21
24
  // describes reusable buttons, actions, default titles, and other ui elements
@@ -492,12 +495,11 @@ export default {
492
495
  exportToJson: 'Экспортировать в JSON',
493
496
  },
494
497
  filters: {
495
- predefinedLabels: {
496
- /* https://webitel.atlassian.net/browse/WTEL-6308?focusedCommentId=657415 */
497
- createdAt: {
498
- startOfToday: 'С начала дня',
499
- startOfMonth: 'С начала этого месяца',
500
- },
498
+ datetime: {
499
+ [RelativeDatetimeValue.Today]: 'Сегодня',
500
+ [RelativeDatetimeValue.ThisWeek]: 'Эта неделя',
501
+ [RelativeDatetimeValue.ThisMonth]: 'Этот месяц',
502
+ [RelativeDatetimeValue.Custom]: 'Выбранный диапазон дат',
501
503
  },
502
504
  addFilter: ({ linked }) => {
503
505
  return `${linked('reusable.add')} ${linked(
@@ -548,6 +550,9 @@ export default {
548
550
  contactGroup: ({ linked }) => {
549
551
  return linked('cases.groupPerformers');
550
552
  },
553
+ createdAt: ({ linked }) => {
554
+ return linked('reusable.createdAt');
555
+ },
551
556
  createdAtFrom: ({ linked }) => {
552
557
  return linked('reusable.from');
553
558
  },
@@ -6,16 +6,19 @@ import {
6
6
  EngineRoutingSchemaType,
7
7
  } from 'webitel-sdk';
8
8
 
9
- import { IconAction } from '../../enums';
10
- import ChatGatewayProvider from '../../enums/ChatGatewayProvider/ChatGatewayProvider.enum.js';
11
- import QueueType from '../../enums/QueueType/QueueType.enum.js';
12
- import AdminSections from '../../enums/WebitelApplications/AdminSections.enum.js';
13
- import AuditorSections from '../../enums/WebitelApplications/AuditorSections.enum.js';
14
- import CrmSections from '../../enums/WebitelApplications/CrmSections.enum.js';
15
- import SupervisorSections from '../../enums/WebitelApplications/SupervisorSections.enum.js';
16
- import WebitelApplications from '../../enums/WebitelApplications/WebitelApplications.enum.js';
9
+ import {
10
+ AdminSections,
11
+ AuditorSections,
12
+ ChatGatewayProvider,
13
+ CrmSections,
14
+ IconAction,
15
+ QueueType,
16
+ RelativeDatetimeValue,
17
+ SupervisorSections,
18
+ WebitelApplications,
19
+ } from '../../enums';
17
20
  import { AccessMode } from '../../modules/ObjectPermissions/_internals/enums/AccessMode.enum.js';
18
- import { snakeToCamel } from '../../scripts/caseConverters.js';
21
+ import { snakeToCamel } from '../../scripts';
19
22
 
20
23
  export default {
21
24
  // describes reusable buttons, actions, default titles, and other ui elements
@@ -492,12 +495,11 @@ export default {
492
495
  exportToJson: 'Експортувати в JSON',
493
496
  },
494
497
  filters: {
495
- predefinedLabels: {
496
- /* https://webitel.atlassian.net/browse/WTEL-6308?focusedCommentId=657415 */
497
- createdAt: {
498
- startOfToday: 'Від початку дня',
499
- startOfMonth: 'Від початку місяця',
500
- },
498
+ datetime: {
499
+ [RelativeDatetimeValue.Today]: 'Сьогодні',
500
+ [RelativeDatetimeValue.ThisWeek]: 'Цей тиждень',
501
+ [RelativeDatetimeValue.ThisMonth]: 'Цей місяць',
502
+ [RelativeDatetimeValue.Custom]: 'Власний діапазон дат',
501
503
  },
502
504
  addFilter: ({ linked }) => {
503
505
  return `${linked('reusable.add')} ${linked(
@@ -548,6 +550,9 @@ export default {
548
550
  contactGroup: ({ linked }) => {
549
551
  return linked('cases.groupPerformers');
550
552
  },
553
+ createdAt: ({ linked }) => {
554
+ return linked('reusable.createdAt');
555
+ },
551
556
  createdAtFrom: ({ linked }) => {
552
557
  return linked('reusable.from');
553
558
  },
@@ -21,6 +21,10 @@ import debounce from './debounce.js';
21
21
  import eventBus from './eventBus.js';
22
22
  import isEmpty from './isEmpty.js';
23
23
  import { wtlog } from './logger.js';
24
+ import {
25
+ isRelativeDatetimeValue,
26
+ normalizeToTimestamp,
27
+ } from './normalizeDatetime';
24
28
  import prettifyFileSize from './prettifyFileSize.js';
25
29
  import prettifyTime from './prettifyTime.js';
26
30
  import preventHiddenPageCallsDecorator from './preventHiddenPageCallsDecorator.js';
@@ -38,8 +42,10 @@ export {
38
42
  debounce,
39
43
  eventBus,
40
44
  isEmpty,
45
+ isRelativeDatetimeValue,
41
46
  kebabToCamel,
42
47
  kebabToSnake,
48
+ normalizeToTimestamp,
43
49
  objCamelToKebab,
44
50
  objCamelToSnake,
45
51
  objSnakeToCamel,
@@ -0,0 +1,77 @@
1
+ import {
2
+ endOfMonth,
3
+ endOfToday,
4
+ endOfWeek,
5
+ startOfMonth,
6
+ startOfToday,
7
+ startOfWeek,
8
+ } from 'date-fns';
9
+
10
+ import { RelativeDatetimeValue } from '../enums';
11
+
12
+ export type RelativeDatetimeRoundOption =
13
+ | 'start'
14
+ | 'end'; /* for "from" or "to" */
15
+
16
+ export type NormalizeDatetimeValueParam =
17
+ | RelativeDatetimeValue
18
+ | number
19
+ | string
20
+ | null
21
+ | undefined;
22
+
23
+ export type NormalizeDatetimeOptions = {
24
+ round?: RelativeDatetimeRoundOption;
25
+ };
26
+
27
+ export const isRelativeDatetimeValue = (value: string): boolean => {
28
+ return Object.values(RelativeDatetimeValue).includes(value);
29
+ };
30
+
31
+ const convertRelativeDatetimeToTimestamp = (
32
+ relativeValue: RelativeDatetimeValue,
33
+ options?: NormalizeDatetimeOptions,
34
+ ): number => {
35
+ if (options?.round === 'end') {
36
+ switch (relativeValue) {
37
+ case RelativeDatetimeValue.Today:
38
+ return endOfToday().getTime();
39
+ case RelativeDatetimeValue.ThisWeek:
40
+ return endOfWeek(Date.now()).getTime();
41
+ case RelativeDatetimeValue.ThisMonth:
42
+ return endOfMonth(Date.now()).getTime();
43
+ default:
44
+ return Date.now();
45
+ }
46
+ } else {
47
+ switch (relativeValue) {
48
+ case RelativeDatetimeValue.Today:
49
+ return startOfToday().getTime();
50
+ case RelativeDatetimeValue.ThisWeek:
51
+ return startOfWeek(Date.now()).getTime();
52
+ case RelativeDatetimeValue.ThisMonth:
53
+ return startOfMonth(Date.now()).getTime();
54
+ default:
55
+ return Date.now();
56
+ }
57
+ }
58
+ };
59
+
60
+ export const normalizeToTimestamp = (
61
+ value?: NormalizeDatetimeValueParam,
62
+ options: NormalizeDatetimeOptions = {},
63
+ ): number => {
64
+ if (value == null) {
65
+ return 0;
66
+ } else if (typeof value === 'number') {
67
+ return value;
68
+ } else if (isRelativeDatetimeValue(value)) {
69
+ return convertRelativeDatetimeToTimestamp(value, options);
70
+ } else if (typeof value === 'string') {
71
+ if (+value) {
72
+ return +value;
73
+ }
74
+ } else {
75
+ return Date.now();
76
+ }
77
+ };