@webitel/api-services 26.8.31 → 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 +2 -1
- package/src/api/clients/activeCalls/__tests__/activeCalls.spec.ts +51 -0
- package/src/api/clients/activeCalls/activeCalls.ts +15 -5
- package/src/api/clients/devices/devices.ts +4 -0
- package/src/enums/FormatDateMode/FormatDateMode.ts +10 -0
- package/src/enums/index.ts +2 -0
- package/src/utils/formatDate.ts +44 -0
- package/src/utils/index.ts +1 -0
- package/src/validations/device/device.validations.ts +4 -2
- package/types/.tsbuildinfo +1 -1
- package/types/enums/FormatDateMode/FormatDateMode.d.ts +8 -0
- package/types/enums/index.d.ts +2 -1
- package/types/gen-wire/articles/articles.zod.d.ts +9 -9
- package/types/gen-wire/dictionaries/dictionaries.zod.d.ts +11 -11
- package/types/gen-wire/extensions/extensions.zod.d.ts +8 -8
- package/types/gen-wire/pdf-service/pdf-service.zod.d.ts +4 -4
- package/types/gen-wire/records/records.zod.d.ts +2 -2
- package/types/gen-wire/types/types.zod.d.ts +2 -2
- package/types/utils/formatDate.d.ts +4 -0
- package/types/utils/index.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/api-services",
|
|
3
|
-
"version": "26.8.
|
|
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) {
|
|
@@ -107,6 +107,10 @@ const getDevice = async ({ itemId: id }: GetItemParams) => {
|
|
|
107
107
|
const preRequestHandler = (item: ApiParams) => {
|
|
108
108
|
const copy = deepCopy(item);
|
|
109
109
|
if (!copy.password) copy.password = undefined;
|
|
110
|
+
if (!copy.hotdesk) {
|
|
111
|
+
delete copy.hotdesk;
|
|
112
|
+
delete copy.hotdesks;
|
|
113
|
+
}
|
|
110
114
|
return copy;
|
|
111
115
|
};
|
|
112
116
|
|
package/src/enums/index.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -43,8 +43,10 @@ export const deviceSchema = z
|
|
|
43
43
|
brand: z.string().optional().default(''),
|
|
44
44
|
model: z.string().optional().default(''),
|
|
45
45
|
mac: optionalMacSchema,
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
// No defaults — regular devices must omit these (see DevicesAPI.preRequestHandler / WTEL-10460).
|
|
47
|
+
// Hotdesk create sets them in opened-device via applyHotdeskDefaults.
|
|
48
|
+
hotdesk: z.boolean().optional(),
|
|
49
|
+
hotdesks: z.array(z.string()).optional(),
|
|
48
50
|
})
|
|
49
51
|
.superRefine((data, ctx) => {
|
|
50
52
|
if (!data.id && !data.password) {
|