@webitel/api-services 26.8.32 → 26.8.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/api-services",
3
- "version": "26.8.32",
3
+ "version": "26.8.33",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -72,6 +72,7 @@
72
72
  },
73
73
  "dependencies": {
74
74
  "date-fns": "^4.1.0",
75
+ "date-fns-tz": "^3.2.0",
75
76
  "lodash-es": "^4.17.21",
76
77
  "qs-esm": "^7.0.2"
77
78
  },
@@ -0,0 +1,51 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+
3
+ const time = 123;
4
+
5
+ const searchActiveCall = vi.fn(() =>
6
+ Promise.resolve({
7
+ data: {
8
+ items: [
9
+ {
10
+ created_at: time,
11
+ duration: 0,
12
+ },
13
+ ],
14
+ next: false,
15
+ },
16
+ }),
17
+ );
18
+
19
+ vi.mock('../../../../gen-wire', async (importOriginal) => ({
20
+ ...(await importOriginal<Record<string, unknown>>()),
21
+ getCallService: () => ({
22
+ searchActiveCall,
23
+ }),
24
+ }));
25
+
26
+ const { FormatDateMode } = await import('../../../../enums');
27
+ const { convertDuration } = await import('../../../../scripts');
28
+ const { formatDate } = await import('../../../../utils');
29
+ const { ActiveCallsAPI } = await import('../activeCalls');
30
+
31
+ /**
32
+ * getList owns the display formatting: createdAt as a full DATETIME and
33
+ * duration through the shared convertDuration helper.
34
+ */
35
+ describe('ActiveCallsAPI.getList', () => {
36
+ beforeEach(() => searchActiveCall.mockClear());
37
+
38
+ it('formats duration and createdAt on each item', async () => {
39
+ const response = await ActiveCallsAPI.getList({});
40
+
41
+ expect(response).toEqual({
42
+ items: [
43
+ {
44
+ createdAt: formatDate(+time, FormatDateMode.DATETIME),
45
+ duration: convertDuration(0),
46
+ },
47
+ ],
48
+ next: false,
49
+ });
50
+ });
51
+ });
@@ -1,4 +1,7 @@
1
+ import { FormatDateMode } from '../../../enums';
1
2
  import { getCallService } from '../../../gen-wire';
3
+ import { convertDuration } from '../../../scripts';
4
+ import { formatDate } from '../../../utils';
2
5
  import { getDefaultGetListResponse, getDefaultGetParams } from '../../defaults';
3
6
  import {
4
7
  applyTransform,
@@ -9,10 +12,7 @@ import {
9
12
  } from '../../transformers';
10
13
  import type { ApiParams } from '../_shared/types';
11
14
 
12
- /**
13
- * Calls currently in progress. Durations and timestamps come back raw;
14
- * formatting them is the caller's job.
15
- */
15
+ /** Calls currently in progress. */
16
16
  const getActiveCallsList = async (params: ApiParams) => {
17
17
  const {
18
18
  page,
@@ -34,6 +34,14 @@ const getActiveCallsList = async (params: ApiParams) => {
34
34
  starToSearch('search'),
35
35
  ]);
36
36
 
37
+ const listResponseHandler = (items: ApiParams[]) => {
38
+ return items.map((item) => ({
39
+ ...item,
40
+ duration: convertDuration(Number(item.duration ?? 0)),
41
+ createdAt: formatDate(Number(item.createdAt), FormatDateMode.DATETIME),
42
+ }));
43
+ };
44
+
37
45
  try {
38
46
  const response = await getCallService().searchActiveCall({
39
47
  page,
@@ -57,7 +65,9 @@ const getActiveCallsList = async (params: ApiParams) => {
57
65
  merge(getDefaultGetListResponse()),
58
66
  ]);
59
67
  return {
60
- items,
68
+ items: applyTransform(items, [
69
+ listResponseHandler,
70
+ ]),
61
71
  next,
62
72
  };
63
73
  } catch (err) {
@@ -0,0 +1,10 @@
1
+ export const FormatDateMode = {
2
+ DATE: 'date',
3
+ TIME: 'time',
4
+ TIME_SEC: 'timeSec',
5
+ DATETIME: 'datetime',
6
+ DATETIME_SHORT: 'datetimeShort',
7
+ } as const;
8
+
9
+ export type FormatDateMode =
10
+ (typeof FormatDateMode)[keyof typeof FormatDateMode];
@@ -1,5 +1,6 @@
1
1
  import { CallReportingStatus } from './CallReportingStatus/CallReportingStatus';
2
2
  import { ChatGatewayProvider } from './ChatGatewayProvider/ChatGatewayPrivider';
3
+ import { FormatDateMode } from './FormatDateMode/FormatDateMode';
3
4
  import { MemberStopCause } from './MemberStopCause/MemberStopCause';
4
5
  import {
5
6
  QueueStrategy,
@@ -13,6 +14,7 @@ import { TypesResourceStrategy } from './TypesResourceStrategy/TypesResourceStra
13
14
  export {
14
15
  CallReportingStatus,
15
16
  ChatGatewayProvider,
17
+ FormatDateMode,
16
18
  MemberStopCause,
17
19
  QueueStrategy,
18
20
  QueueStrategyList,
@@ -0,0 +1,44 @@
1
+ import { uk } from 'date-fns/locale';
2
+ import { formatInTimeZone } from 'date-fns-tz';
3
+
4
+ import type { FormatDateMode } from '../enums/FormatDateMode/FormatDateMode';
5
+
6
+ /**
7
+ * Mirrors @webitel/ui-sdk's Userinfo TIMEZONE_STORAGE_KEY constant —
8
+ * duplicated here rather than imported to avoid a circular dependency
9
+ * (api-services must not depend on ui-sdk). Keep the literal in sync with
10
+ * ui-sdk/src/modules/Userinfo/constants/UserSettingsConstants.ts.
11
+ */
12
+ const TIMEZONE_STORAGE_KEY = 'user-timezone-setting';
13
+
14
+ function getUserTimeZone(): string {
15
+ return (
16
+ localStorage.getItem(TIMEZONE_STORAGE_KEY) ||
17
+ Intl.DateTimeFormat().resolvedOptions().timeZone
18
+ );
19
+ }
20
+
21
+ // https://date-fns.org/v4.1.0/docs/format
22
+ const formatStringMap = {
23
+ date: 'P', // dd.MM.yyyy (13.11.2025)
24
+ time: 'p', // HH:mm (15:53)
25
+ timeSec: 'pp', // HH:mm:ss (15:53:00)
26
+ datetime: 'Ppp', // dd.MM.yyyy, HH:mm:ss (13.11.2025, 15:53:00)
27
+ datetimeShort: 'Pp', // dd.MM.yyyy, HH:mm (13.11.2025, 15:53)
28
+ };
29
+
30
+ export function formatDate(
31
+ date: string | number | Date,
32
+ to: (typeof FormatDateMode)[keyof typeof FormatDateMode],
33
+ {
34
+ timezone = undefined,
35
+ }: {
36
+ timezone?: string;
37
+ } = {},
38
+ ): string {
39
+ const timeZone = timezone ?? getUserTimeZone();
40
+
41
+ return formatInTimeZone(date, timeZone, formatStringMap[to], {
42
+ locale: uk,
43
+ });
44
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './api';
2
+ export * from './formatDate';
2
3
  export * from './gen';