@webitel/api-services 26.8.71 → 26.8.73
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 +1 -1
- package/src/api/clients/fileServices/__tests__/fileServices.spec.ts +20 -0
- package/src/api/clients/fileServices/fileServices.ts +53 -0
- package/src/api/clients/outboundResources/outboundResources.ts +44 -81
- package/src/api/clients/outboundResources/resourceDisplays.ts +106 -32
- package/src/api/clients/pdfServices/__tests__/downloadCallScreenrecordingArchive.spec.ts +60 -0
- package/src/api/clients/pdfServices/pdfServices.ts +42 -0
- package/src/enums/ResourceCidType/ResourceCidType.ts +8 -0
- package/src/enums/ResourceIgnoreEarlyMedia/ResourceIgnoreEarlyMedia.ts +9 -0
- package/src/enums/index.ts +4 -0
- package/src/locale/en/en.ts +4 -0
- package/src/locale/es/es.ts +4 -0
- package/src/locale/kz/kz.ts +4 -0
- package/src/locale/pl/pl.ts +4 -0
- package/src/locale/ro/ro.ts +4 -0
- package/src/locale/ru/ru.ts +4 -0
- package/src/locale/uk/uk.ts +4 -0
- package/src/locale/uz/uz.ts +4 -0
- package/src/locale/vi/vi.ts +4 -0
- package/src/validations/index.ts +2 -0
- package/src/validations/resource/__tests__/resource.validations.spec.ts +102 -0
- package/src/validations/resource/resource.validations.ts +28 -0
- package/src/validations/resourceDisplay/__tests__/resourceDisplay.validations.spec.ts +45 -0
- package/src/validations/resourceDisplay/resourceDisplay.validations.ts +9 -0
- package/types/.tsbuildinfo +1 -1
- package/types/api/clients/fileServices/fileServices.d.ts +8 -1
- package/types/api/clients/outboundResources/outboundResources.d.ts +2 -7
- package/types/api/clients/outboundResources/resourceDisplays.d.ts +7 -1
- package/types/api/clients/pdfServices/pdfServices.d.ts +4 -1
- package/types/enums/ResourceCidType/ResourceCidType.d.ts +6 -0
- package/types/enums/ResourceIgnoreEarlyMedia/ResourceIgnoreEarlyMedia.d.ts +7 -0
- package/types/enums/index.d.ts +3 -1
- package/types/locale/en/en.d.ts +3 -0
- package/types/locale/es/es.d.ts +3 -0
- package/types/locale/index.d.ts +27 -0
- package/types/locale/kz/kz.d.ts +3 -0
- package/types/locale/pl/pl.d.ts +3 -0
- package/types/locale/ro/ro.d.ts +3 -0
- package/types/locale/ru/ru.d.ts +3 -0
- package/types/locale/uk/uk.d.ts +3 -0
- package/types/locale/uz/uz.d.ts +3 -0
- package/types/locale/vi/vi.d.ts +3 -0
- package/types/validations/index.d.ts +2 -0
- package/types/validations/resource/resource.validations.d.ts +26 -0
- package/types/validations/resourceDisplay/resourceDisplay.validations.d.ts +5 -0
package/package.json
CHANGED
|
@@ -129,3 +129,23 @@ describe('FileServicesAPI.getListByCall', () => {
|
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
131
|
});
|
|
132
|
+
|
|
133
|
+
describe('FileServicesAPI.getScreenRecordingsByCall', () => {
|
|
134
|
+
it('sends start_at range filters for call screen recordings', async () => {
|
|
135
|
+
await FileServicesAPI.getScreenRecordingsByCall({
|
|
136
|
+
callId: 'call-1',
|
|
137
|
+
startAtFrom: '1700000000000',
|
|
138
|
+
startAtTo: '1700000009999',
|
|
139
|
+
type: 'SCREENSHARING',
|
|
140
|
+
channel: 'SCREENRECORDING',
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(captured[0].url).toBe('/storage/call/call-1');
|
|
144
|
+
expect(sentParams()).toMatchObject({
|
|
145
|
+
'start_at.from': '1700000000000',
|
|
146
|
+
'start_at.to': '1700000009999',
|
|
147
|
+
type: 'SCREENSHARING',
|
|
148
|
+
channel: 'SCREENRECORDING',
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
SearchFilesByCallParams,
|
|
3
3
|
SearchFilesParams,
|
|
4
4
|
SearchScreenRecordingsByAgentParams,
|
|
5
|
+
SearchScreenRecordingsByCallParams,
|
|
5
6
|
SearchScreenRecordingsParams,
|
|
6
7
|
} from '@webitel/api-services/gen/models';
|
|
7
8
|
import { getShallowFieldsToSendFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
@@ -10,12 +11,14 @@ import {
|
|
|
10
11
|
SearchFilesByCallQueryParams,
|
|
11
12
|
SearchFilesQueryParams,
|
|
12
13
|
SearchScreenRecordingsByAgentQueryParams,
|
|
14
|
+
SearchScreenRecordingsByCallQueryParams,
|
|
13
15
|
SearchScreenRecordingsQueryParams,
|
|
14
16
|
} from '../../../gen-wire';
|
|
15
17
|
import type {
|
|
16
18
|
SearchFilesByCallParams as SearchFilesByCallWireParams,
|
|
17
19
|
SearchFilesParams as SearchFilesWireParams,
|
|
18
20
|
SearchScreenRecordingsByAgentParams as SearchScreenRecordingsByAgentWireParams,
|
|
21
|
+
SearchScreenRecordingsByCallParams as SearchScreenRecordingsByCallWireParams,
|
|
19
22
|
SearchScreenRecordingsParams as SearchScreenRecordingsWireParams,
|
|
20
23
|
} from '../../../gen-wire/_models';
|
|
21
24
|
import type {
|
|
@@ -222,6 +225,55 @@ const getScreenRecordingsByAgent = async (
|
|
|
222
225
|
}
|
|
223
226
|
};
|
|
224
227
|
|
|
228
|
+
const getScreenRecordingsByCall = async (
|
|
229
|
+
params: SearchScreenRecordingsByCallParams & {
|
|
230
|
+
callId: ApiId;
|
|
231
|
+
search?: string;
|
|
232
|
+
},
|
|
233
|
+
) => {
|
|
234
|
+
const fieldsToSend = getShallowFieldsToSendFromZodSchema(
|
|
235
|
+
SearchScreenRecordingsByCallQueryParams,
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
const requestParams = applyTransform<SearchScreenRecordingsByCallWireParams>(
|
|
239
|
+
params,
|
|
240
|
+
[
|
|
241
|
+
merge(getDefaultGetParams()),
|
|
242
|
+
sanitizeToWire(fieldsToSend),
|
|
243
|
+
camelToSnake(),
|
|
244
|
+
],
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
const response = await getFileService().searchScreenRecordingsByCall(
|
|
249
|
+
String(params.callId),
|
|
250
|
+
{
|
|
251
|
+
...requestParams,
|
|
252
|
+
q: requestParams.q || params.search,
|
|
253
|
+
fields: [
|
|
254
|
+
'id',
|
|
255
|
+
'view_name',
|
|
256
|
+
'mime_type',
|
|
257
|
+
...(requestParams.fields ?? []),
|
|
258
|
+
],
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
const { items, next } = applyTransform(response.data, [
|
|
262
|
+
merge(getDefaultGetListResponse()),
|
|
263
|
+
]);
|
|
264
|
+
return {
|
|
265
|
+
items: applyTransform(items, [
|
|
266
|
+
snakeToCamel(),
|
|
267
|
+
]),
|
|
268
|
+
next,
|
|
269
|
+
};
|
|
270
|
+
} catch (err) {
|
|
271
|
+
throw applyTransform(err, [
|
|
272
|
+
notify,
|
|
273
|
+
]);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
225
277
|
const deleteScreenRecordingsByAgent = async ({
|
|
226
278
|
agentId,
|
|
227
279
|
id,
|
|
@@ -295,6 +347,7 @@ export const FileServicesAPI = {
|
|
|
295
347
|
getScreenRecordingsByUser,
|
|
296
348
|
deleteScreenRecordingsByUser,
|
|
297
349
|
getScreenRecordingsByAgent,
|
|
350
|
+
getScreenRecordingsByCall,
|
|
298
351
|
deleteScreenRecordingsByAgent,
|
|
299
352
|
getListByCall: getFilesListByCall,
|
|
300
353
|
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { getShallowFieldsToSendFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
2
|
+
import {
|
|
3
|
+
CreateOutboundResourceBody,
|
|
4
|
+
getOutboundResourceService,
|
|
5
|
+
PatchOutboundResourceBody,
|
|
6
|
+
SearchOutboundResourceQueryParams,
|
|
7
|
+
UpdateOutboundResourceBody,
|
|
8
|
+
} from '../../../gen-wire';
|
|
3
9
|
import { getDefaultGetListResponse, getDefaultGetParams } from '../../defaults';
|
|
4
10
|
import {
|
|
5
11
|
applyTransform,
|
|
@@ -7,7 +13,7 @@ import {
|
|
|
7
13
|
merge,
|
|
8
14
|
mergeEach,
|
|
9
15
|
notify,
|
|
10
|
-
|
|
16
|
+
sanitizeToWire,
|
|
11
17
|
snakeToCamel,
|
|
12
18
|
starToSearch,
|
|
13
19
|
} from '../../transformers';
|
|
@@ -23,54 +29,28 @@ import type {
|
|
|
23
29
|
|
|
24
30
|
const baseUrl = '/call_center/resources';
|
|
25
31
|
|
|
26
|
-
const
|
|
27
|
-
'limit',
|
|
28
|
-
'enabled',
|
|
29
|
-
'rps',
|
|
30
|
-
'maxSuccessivelyErrors',
|
|
31
|
-
'name',
|
|
32
|
-
'errorIds',
|
|
33
|
-
'display',
|
|
34
|
-
'description',
|
|
35
|
-
'resourceId',
|
|
36
|
-
'gateway',
|
|
37
|
-
'patterns',
|
|
38
|
-
'failureDialDelay',
|
|
39
|
-
'parameters',
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
/*
|
|
43
|
-
* The form binds `maxErrors` / `cps`, the API expects
|
|
44
|
-
* `maxSuccessivelyErrors` / `rps`. `getResource` maps them back.
|
|
45
|
-
*/
|
|
46
|
-
const preRequestHandler = (item: ApiParams) => {
|
|
47
|
-
const copy = deepCopy(item);
|
|
48
|
-
copy.maxSuccessivelyErrors = copy.maxErrors;
|
|
49
|
-
copy.rps = copy.cps;
|
|
50
|
-
return copy;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const getResourcesList = async (params: ApiParams) => {
|
|
32
|
+
const getOutboundResourcesList = async (params: ApiParams) => {
|
|
54
33
|
const defaultObject = {
|
|
55
34
|
gateway: null,
|
|
56
35
|
enabled: false,
|
|
57
36
|
};
|
|
58
37
|
|
|
59
|
-
const
|
|
38
|
+
const requestParams = applyTransform(params, [
|
|
60
39
|
merge(getDefaultGetParams()),
|
|
61
40
|
starToSearch('search'),
|
|
41
|
+
(params: ApiParams) => ({
|
|
42
|
+
...params,
|
|
43
|
+
q: params.q ?? params.search,
|
|
44
|
+
}),
|
|
45
|
+
sanitizeToWire(
|
|
46
|
+
getShallowFieldsToSendFromZodSchema(SearchOutboundResourceQueryParams),
|
|
47
|
+
),
|
|
48
|
+
camelToSnake(),
|
|
62
49
|
]);
|
|
63
50
|
|
|
64
51
|
try {
|
|
65
|
-
const response =
|
|
66
|
-
|
|
67
|
-
size,
|
|
68
|
-
// the generated param is `q`; `search` is what the datalist store sends
|
|
69
|
-
q: search,
|
|
70
|
-
sort,
|
|
71
|
-
fields,
|
|
72
|
-
id,
|
|
73
|
-
});
|
|
52
|
+
const response =
|
|
53
|
+
await getOutboundResourceService().searchOutboundResource(requestParams);
|
|
74
54
|
const { items, next } = applyTransform(response.data, [
|
|
75
55
|
snakeToCamel(),
|
|
76
56
|
merge(getDefaultGetListResponse()),
|
|
@@ -88,34 +68,14 @@ const getResourcesList = async (params: ApiParams) => {
|
|
|
88
68
|
}
|
|
89
69
|
};
|
|
90
70
|
|
|
91
|
-
const
|
|
71
|
+
const getOutboundResource = async ({ itemId: id }: GetItemParams) => {
|
|
92
72
|
const defaultObject = {
|
|
93
|
-
name: '',
|
|
94
|
-
gateway: {},
|
|
95
|
-
rps: 0,
|
|
96
|
-
limit: 0,
|
|
97
|
-
description: '',
|
|
98
|
-
maxSuccessivelyErrors: 0,
|
|
99
|
-
errorIds: [],
|
|
100
|
-
patterns: [],
|
|
101
|
-
failureDialDelay: 0,
|
|
102
73
|
parameters: {
|
|
103
74
|
cidType: '',
|
|
104
75
|
ignoreEarlyMedia: '',
|
|
105
76
|
},
|
|
106
77
|
};
|
|
107
78
|
|
|
108
|
-
const responseHandler = (response: ApiParams) => {
|
|
109
|
-
const copy = deepCopy(response);
|
|
110
|
-
copy.maxErrors = copy.maxSuccessivelyErrors;
|
|
111
|
-
copy.cps = copy.rps;
|
|
112
|
-
copy.parameters = {
|
|
113
|
-
...defaultObject.parameters,
|
|
114
|
-
...copy.parameters,
|
|
115
|
-
};
|
|
116
|
-
return copy;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
79
|
try {
|
|
120
80
|
const response = await getOutboundResourceService().readOutboundResource(
|
|
121
81
|
String(id),
|
|
@@ -123,7 +83,6 @@ const getResource = async ({ itemId: id }: GetItemParams) => {
|
|
|
123
83
|
return applyTransform(response.data, [
|
|
124
84
|
snakeToCamel(),
|
|
125
85
|
merge(defaultObject),
|
|
126
|
-
responseHandler,
|
|
127
86
|
]);
|
|
128
87
|
} catch (err) {
|
|
129
88
|
throw applyTransform(err, [
|
|
@@ -132,10 +91,11 @@ const getResource = async ({ itemId: id }: GetItemParams) => {
|
|
|
132
91
|
}
|
|
133
92
|
};
|
|
134
93
|
|
|
135
|
-
const
|
|
94
|
+
const addOutboundResource = async ({ itemInstance }: AddItemParams) => {
|
|
136
95
|
const item = applyTransform(itemInstance, [
|
|
137
|
-
|
|
138
|
-
|
|
96
|
+
sanitizeToWire(
|
|
97
|
+
getShallowFieldsToSendFromZodSchema(CreateOutboundResourceBody),
|
|
98
|
+
),
|
|
139
99
|
camelToSnake(),
|
|
140
100
|
]);
|
|
141
101
|
try {
|
|
@@ -151,13 +111,14 @@ const addResource = async ({ itemInstance }: AddItemParams) => {
|
|
|
151
111
|
}
|
|
152
112
|
};
|
|
153
113
|
|
|
154
|
-
const
|
|
114
|
+
const updateOutboundResource = async ({
|
|
155
115
|
itemInstance,
|
|
156
116
|
itemId: id,
|
|
157
117
|
}: UpdateItemParams) => {
|
|
158
118
|
const item = applyTransform(itemInstance, [
|
|
159
|
-
|
|
160
|
-
|
|
119
|
+
sanitizeToWire(
|
|
120
|
+
getShallowFieldsToSendFromZodSchema(UpdateOutboundResourceBody),
|
|
121
|
+
),
|
|
161
122
|
camelToSnake(),
|
|
162
123
|
]);
|
|
163
124
|
try {
|
|
@@ -175,9 +136,11 @@ const updateResource = async ({
|
|
|
175
136
|
}
|
|
176
137
|
};
|
|
177
138
|
|
|
178
|
-
const
|
|
139
|
+
const patchOutboundResource = async ({ changes, id }: PatchItemParams) => {
|
|
179
140
|
const body = applyTransform(changes, [
|
|
180
|
-
|
|
141
|
+
sanitizeToWire(
|
|
142
|
+
getShallowFieldsToSendFromZodSchema(PatchOutboundResourceBody),
|
|
143
|
+
),
|
|
181
144
|
camelToSnake(),
|
|
182
145
|
]);
|
|
183
146
|
try {
|
|
@@ -195,7 +158,7 @@ const patchResource = async ({ changes, id }: PatchItemParams) => {
|
|
|
195
158
|
}
|
|
196
159
|
};
|
|
197
160
|
|
|
198
|
-
const
|
|
161
|
+
const deleteOutboundResource = async ({ id }: DeleteItemParams) => {
|
|
199
162
|
try {
|
|
200
163
|
const response = await getOutboundResourceService().deleteOutboundResource(
|
|
201
164
|
String(id),
|
|
@@ -208,8 +171,8 @@ const deleteResource = async ({ id }: DeleteItemParams) => {
|
|
|
208
171
|
}
|
|
209
172
|
};
|
|
210
173
|
|
|
211
|
-
const
|
|
212
|
-
|
|
174
|
+
const getOutboundResourcesLookup = (params: ApiParams) =>
|
|
175
|
+
getOutboundResourcesList({
|
|
213
176
|
...params,
|
|
214
177
|
fields: params.fields || [
|
|
215
178
|
'id',
|
|
@@ -218,13 +181,13 @@ const getResourcesLookup = (params: Parameters<typeof getResourcesList>[0]) =>
|
|
|
218
181
|
});
|
|
219
182
|
|
|
220
183
|
export const OutboundResourcesAPI = {
|
|
221
|
-
getList:
|
|
222
|
-
get:
|
|
223
|
-
add:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
delete:
|
|
227
|
-
getLookup:
|
|
184
|
+
getList: getOutboundResourcesList,
|
|
185
|
+
get: getOutboundResource,
|
|
186
|
+
add: addOutboundResource,
|
|
187
|
+
update: updateOutboundResource,
|
|
188
|
+
patch: patchOutboundResource,
|
|
189
|
+
delete: deleteOutboundResource,
|
|
190
|
+
getLookup: getOutboundResourcesLookup,
|
|
228
191
|
|
|
229
192
|
...generatePermissionsApi(baseUrl),
|
|
230
193
|
};
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getShallowFieldsToSendFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
2
|
+
import type { AxiosError } from 'axios';
|
|
3
|
+
import type { Composer } from 'vue-i18n';
|
|
4
|
+
import { config } from '../../../config/config';
|
|
5
|
+
import {
|
|
6
|
+
CreateOutboundResourceDisplayBody,
|
|
7
|
+
getOutboundResourceService,
|
|
8
|
+
SearchOutboundResourceDisplayQueryParams,
|
|
9
|
+
UpdateOutboundResourceDisplayBody,
|
|
10
|
+
} from '../../../gen-wire';
|
|
11
|
+
import {
|
|
12
|
+
getDefaultGetListResponse,
|
|
13
|
+
getDefaultGetParams,
|
|
14
|
+
getDefaultInstance,
|
|
15
|
+
} from '../../defaults';
|
|
3
16
|
import {
|
|
4
17
|
applyTransform,
|
|
5
18
|
camelToSnake,
|
|
6
19
|
merge,
|
|
7
20
|
notify,
|
|
8
|
-
|
|
21
|
+
sanitizeToWire,
|
|
9
22
|
snakeToCamel,
|
|
10
23
|
starToSearch,
|
|
11
24
|
} from '../../transformers';
|
|
@@ -18,38 +31,30 @@ import type {
|
|
|
18
31
|
NestedUpdateItemParams,
|
|
19
32
|
} from '../_shared/types';
|
|
20
33
|
|
|
21
|
-
const
|
|
22
|
-
'display',
|
|
23
|
-
'resourceId',
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const preRequestHandler = (parentId: ApiId) => (item: ApiParams) => ({
|
|
27
|
-
...item,
|
|
28
|
-
resourceId: parentId,
|
|
29
|
-
});
|
|
34
|
+
const instance = getDefaultInstance();
|
|
30
35
|
|
|
31
36
|
const getResourceDisplaysList = async (params: ApiParams) => {
|
|
32
|
-
const {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const { parentId, ...rest } = params;
|
|
38
|
+
const requestParams = applyTransform(rest, [
|
|
39
|
+
merge(getDefaultGetParams()),
|
|
40
|
+
starToSearch('search'),
|
|
41
|
+
(params: ApiParams) => ({
|
|
42
|
+
...params,
|
|
43
|
+
q: params.q ?? params.search,
|
|
44
|
+
}),
|
|
45
|
+
sanitizeToWire(
|
|
46
|
+
getShallowFieldsToSendFromZodSchema(
|
|
47
|
+
SearchOutboundResourceDisplayQueryParams,
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
camelToSnake(),
|
|
51
|
+
]);
|
|
39
52
|
|
|
40
53
|
try {
|
|
41
54
|
const response =
|
|
42
55
|
await getOutboundResourceService().searchOutboundResourceDisplay(
|
|
43
56
|
String(parentId),
|
|
44
|
-
|
|
45
|
-
page,
|
|
46
|
-
size,
|
|
47
|
-
// the generated param is `q`; `search` is what the datalist store sends
|
|
48
|
-
q: search,
|
|
49
|
-
sort,
|
|
50
|
-
fields,
|
|
51
|
-
id,
|
|
52
|
-
},
|
|
57
|
+
requestParams,
|
|
53
58
|
);
|
|
54
59
|
const { items, next } = applyTransform(response.data, [
|
|
55
60
|
snakeToCamel(),
|
|
@@ -91,8 +96,9 @@ const addResourceDisplay = async ({
|
|
|
91
96
|
itemInstance,
|
|
92
97
|
}: NestedAddItemParams) => {
|
|
93
98
|
const item = applyTransform(itemInstance, [
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
sanitizeToWire(
|
|
100
|
+
getShallowFieldsToSendFromZodSchema(CreateOutboundResourceDisplayBody),
|
|
101
|
+
),
|
|
96
102
|
camelToSnake(),
|
|
97
103
|
]);
|
|
98
104
|
try {
|
|
@@ -117,8 +123,9 @@ const updateResourceDisplay = async ({
|
|
|
117
123
|
itemId: id,
|
|
118
124
|
}: NestedUpdateItemParams) => {
|
|
119
125
|
const item = applyTransform(itemInstance, [
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
sanitizeToWire(
|
|
127
|
+
getShallowFieldsToSendFromZodSchema(UpdateOutboundResourceDisplayBody),
|
|
128
|
+
),
|
|
122
129
|
camelToSnake(),
|
|
123
130
|
]);
|
|
124
131
|
try {
|
|
@@ -156,10 +163,77 @@ const deleteResourceDisplay = async ({
|
|
|
156
163
|
}
|
|
157
164
|
};
|
|
158
165
|
|
|
166
|
+
/**
|
|
167
|
+
* [Claude] Invalid numbers in an uploaded file come back with an id that starts
|
|
168
|
+
* with `cc_outbound_resource.validatePhoneNumber`. Only the prefix is known, so
|
|
169
|
+
* `translateError`, which looks the translation up by the exact id, does not fit.
|
|
170
|
+
*
|
|
171
|
+
* [WTEL-10579](https://webitel.atlassian.net/browse/WTEL-10579)
|
|
172
|
+
*/
|
|
173
|
+
const translatePhoneNumberError = (
|
|
174
|
+
err: AxiosError<{
|
|
175
|
+
id?: string;
|
|
176
|
+
translation?: string;
|
|
177
|
+
}>,
|
|
178
|
+
) => {
|
|
179
|
+
const data = err.response?.data;
|
|
180
|
+
if (
|
|
181
|
+
data?.id?.startsWith('cc_outbound_resource.validatePhoneNumber') &&
|
|
182
|
+
config.i18n?.global
|
|
183
|
+
) {
|
|
184
|
+
data.translation = (config.i18n.global as Composer).t(
|
|
185
|
+
'backendErrors.ccOutboundResource.validatePhoneNumber',
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return err;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* [Claude] Bulk number import from a csv file: the file itself is sent, and the
|
|
193
|
+
* backend parses it and validates the numbers. `POST /displays/:id` is not in
|
|
194
|
+
* the OpenAPI spec, so there is no generated method for it — the request goes
|
|
195
|
+
* through the default instance instead.
|
|
196
|
+
*
|
|
197
|
+
* [WTEL-10579](https://webitel.atlassian.net/browse/WTEL-10579)
|
|
198
|
+
*/
|
|
199
|
+
const uploadResourceDisplays = async ({
|
|
200
|
+
parentId,
|
|
201
|
+
file,
|
|
202
|
+
delimiter,
|
|
203
|
+
map,
|
|
204
|
+
}: {
|
|
205
|
+
parentId: ApiId;
|
|
206
|
+
file: File;
|
|
207
|
+
delimiter: string;
|
|
208
|
+
map: string;
|
|
209
|
+
}) => {
|
|
210
|
+
const formData = new FormData();
|
|
211
|
+
formData.append('file', file);
|
|
212
|
+
formData.append('delimiter', delimiter);
|
|
213
|
+
formData.append('map', map);
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
const response = await instance.post(`/displays/${parentId}`, formData, {
|
|
217
|
+
headers: {
|
|
218
|
+
'Content-Type': 'multipart/form-data',
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
return applyTransform(response.data, [
|
|
222
|
+
snakeToCamel(),
|
|
223
|
+
]);
|
|
224
|
+
} catch (err) {
|
|
225
|
+
throw applyTransform(err, [
|
|
226
|
+
translatePhoneNumberError,
|
|
227
|
+
notify,
|
|
228
|
+
]);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
159
232
|
export const ResourceDisplaysAPI = {
|
|
160
233
|
getList: getResourceDisplaysList,
|
|
161
234
|
get: getResourceDisplay,
|
|
162
235
|
add: addResourceDisplay,
|
|
163
236
|
update: updateResourceDisplay,
|
|
164
237
|
delete: deleteResourceDisplay,
|
|
238
|
+
upload: uploadResourceDisplays,
|
|
165
239
|
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
const downloadCallScreenrecordingArchive = vi.fn();
|
|
4
|
+
|
|
5
|
+
vi.mock('../../../../gen-wire', async () => {
|
|
6
|
+
const actual = await vi.importActual<typeof import('../../../../gen-wire')>(
|
|
7
|
+
'../../../../gen-wire',
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
getPdfService: () => ({
|
|
13
|
+
downloadCallScreenrecordingArchive,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const { PdfServicesAPI } = await import('../pdfServices');
|
|
19
|
+
|
|
20
|
+
describe('PdfServicesAPI.downloadCallScreenrecordingArchive', () => {
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
downloadCallScreenrecordingArchive.mockReset();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('requests a blob archive with snake_case query params', async () => {
|
|
26
|
+
const response = {
|
|
27
|
+
data: new Blob([
|
|
28
|
+
'zip',
|
|
29
|
+
]),
|
|
30
|
+
};
|
|
31
|
+
downloadCallScreenrecordingArchive.mockResolvedValue(response);
|
|
32
|
+
|
|
33
|
+
await expect(
|
|
34
|
+
PdfServicesAPI.downloadCallScreenrecordingArchive({
|
|
35
|
+
callId: 'call-1',
|
|
36
|
+
fileIds: [
|
|
37
|
+
'123',
|
|
38
|
+
'456',
|
|
39
|
+
],
|
|
40
|
+
from: '1700000000000',
|
|
41
|
+
to: '170000000100000',
|
|
42
|
+
}),
|
|
43
|
+
).resolves.toBe(response);
|
|
44
|
+
|
|
45
|
+
expect(downloadCallScreenrecordingArchive).toHaveBeenCalledWith(
|
|
46
|
+
'call-1',
|
|
47
|
+
{
|
|
48
|
+
file_ids: [
|
|
49
|
+
'123',
|
|
50
|
+
'456',
|
|
51
|
+
],
|
|
52
|
+
from: '1700000000000',
|
|
53
|
+
to: '170000000100000',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
responseType: 'blob',
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
DownloadCallScreenrecordingArchiveParams,
|
|
2
3
|
ListCallExportsParams,
|
|
3
4
|
ListScreenrecordingExportsParams,
|
|
4
5
|
} from '@webitel/api-services/gen/models';
|
|
@@ -7,6 +8,7 @@ import {
|
|
|
7
8
|
CreateCallExportBody,
|
|
8
9
|
CreateScreenrecordingExportBody,
|
|
9
10
|
DownloadCallArchiveQueryParams,
|
|
11
|
+
DownloadCallScreenrecordingArchiveQueryParams,
|
|
10
12
|
DownloadScreenrecordingArchiveQueryParams,
|
|
11
13
|
DownloadScreenshotArchiveQueryParams,
|
|
12
14
|
getPdfService,
|
|
@@ -211,6 +213,45 @@ const downloadCallArchive = async ({
|
|
|
211
213
|
}
|
|
212
214
|
};
|
|
213
215
|
|
|
216
|
+
const downloadCallScreenrecordingArchive = async ({
|
|
217
|
+
callId,
|
|
218
|
+
fileIds,
|
|
219
|
+
from,
|
|
220
|
+
to,
|
|
221
|
+
}: DownloadCallScreenrecordingArchiveParams & {
|
|
222
|
+
callId: ApiId;
|
|
223
|
+
}) => {
|
|
224
|
+
const fieldsToSend = getShallowFieldsToSendFromZodSchema(
|
|
225
|
+
DownloadCallScreenrecordingArchiveQueryParams,
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const params = applyTransform(
|
|
229
|
+
{
|
|
230
|
+
fileIds,
|
|
231
|
+
from,
|
|
232
|
+
to,
|
|
233
|
+
},
|
|
234
|
+
[
|
|
235
|
+
sanitizeToWire(fieldsToSend),
|
|
236
|
+
camelToSnake(),
|
|
237
|
+
],
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
return await getPdfService().downloadCallScreenrecordingArchive(
|
|
242
|
+
String(callId),
|
|
243
|
+
params,
|
|
244
|
+
{
|
|
245
|
+
responseType: 'blob',
|
|
246
|
+
},
|
|
247
|
+
);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
throw applyTransform(err, [
|
|
250
|
+
notify,
|
|
251
|
+
]);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
214
255
|
const downloadScreenrecordingArchive = async ({
|
|
215
256
|
agentId,
|
|
216
257
|
fileIds,
|
|
@@ -314,6 +355,7 @@ export const PdfServicesAPI = {
|
|
|
314
355
|
createCallExport,
|
|
315
356
|
listCallExports,
|
|
316
357
|
downloadCallArchive,
|
|
358
|
+
downloadCallScreenrecordingArchive,
|
|
317
359
|
downloadScreenrecordingArchive,
|
|
318
360
|
downloadScreenshotArchive,
|
|
319
361
|
delete: deleteExport,
|
package/src/enums/index.ts
CHANGED
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
} from './QueueStrategy/QueueStrategy';
|
|
13
13
|
import { QueueType, QueueTypeName } from './QueueType/QueueType';
|
|
14
14
|
import { RelativeDatetimeValue } from './RelativeDatetimeValue/RelativeDatetimeValue';
|
|
15
|
+
import { ResourceCidType } from './ResourceCidType/ResourceCidType';
|
|
16
|
+
import { ResourceIgnoreEarlyMedia } from './ResourceIgnoreEarlyMedia/ResourceIgnoreEarlyMedia';
|
|
15
17
|
import { TimeBaseScore } from './TimeBaseScore/TimeBaseScore';
|
|
16
18
|
import { TypesResourceStrategy } from './TypesResourceStrategy/TypesResourceStrategy';
|
|
17
19
|
import { UrlProtocol } from './UrlProtocol/UrlProtocol';
|
|
@@ -31,6 +33,8 @@ export {
|
|
|
31
33
|
QueueType,
|
|
32
34
|
QueueTypeName,
|
|
33
35
|
RelativeDatetimeValue,
|
|
36
|
+
ResourceCidType,
|
|
37
|
+
ResourceIgnoreEarlyMedia,
|
|
34
38
|
TimeBaseScore,
|
|
35
39
|
TypesResourceStrategy,
|
|
36
40
|
UrlProtocol,
|
package/src/locale/en/en.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type { MessageContext } from 'vue-i18n';
|
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
backendErrors: {
|
|
5
|
+
ccOutboundResource: {
|
|
6
|
+
validatePhoneNumber: ({ linked }: MessageContext) =>
|
|
7
|
+
`File contains invalid numbers. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|