@webitel/api-services 26.8.71 → 26.8.72
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/outboundResources/outboundResources.ts +44 -81
- package/src/api/clients/outboundResources/resourceDisplays.ts +106 -32
- 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/outboundResources/outboundResources.d.ts +2 -7
- package/types/api/clients/outboundResources/resourceDisplays.d.ts +7 -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
|
@@ -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
|
};
|
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: {
|
package/src/locale/es/es.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
|
+
`El archivo contiene números incorrectos. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/kz/kz.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
|
+
`Файлда қате нөмірлер бар. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/pl/pl.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
|
+
`Plik zawiera nieprawidłowe numery. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/ro/ro.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
|
+
`Fișierul conține numere incorecte. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/ru/ru.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
|
+
`Файл содержит некорректные номера. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/uk/uk.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
|
+
`Файл містить некоректні номери. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/uz/uz.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
|
+
`Faylda noto'g'ri raqamlar mavjud. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/locale/vi/vi.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
|
+
`Tệp chứa số không hợp lệ. ${linked('validation.phoneNumberSymbolsValidator')}`,
|
|
8
|
+
},
|
|
5
9
|
contacts: {
|
|
6
10
|
search: {
|
|
7
11
|
filters: {
|
package/src/validations/index.ts
CHANGED
|
@@ -45,6 +45,8 @@ export * from './queueMember/memberCommunication.validations';
|
|
|
45
45
|
export * from './queueMember/queueMember.validations';
|
|
46
46
|
export * from './queueResGroup/queueResGroup.validations';
|
|
47
47
|
export * from './queueSkill/queueSkill.validations';
|
|
48
|
+
export * from './resource/resource.validations';
|
|
49
|
+
export * from './resourceDisplay/resourceDisplay.validations';
|
|
48
50
|
export * from './resourceGroup/resourceGroup.validations';
|
|
49
51
|
export * from './resourceInGroup/resourceInGroup.validations';
|
|
50
52
|
export * from './sla/sla.validations';
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { getDefaultsFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { resourceSchema } from '../resource.validations';
|
|
5
|
+
|
|
6
|
+
const filledResource = {
|
|
7
|
+
name: 'Resource',
|
|
8
|
+
gateway: {
|
|
9
|
+
id: 1,
|
|
10
|
+
name: 'Gateway',
|
|
11
|
+
},
|
|
12
|
+
rps: 10,
|
|
13
|
+
limit: 10,
|
|
14
|
+
maxSuccessivelyErrors: 2,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const issuePaths = (value: Record<string, unknown>) =>
|
|
18
|
+
resourceSchema
|
|
19
|
+
.safeParse(value)
|
|
20
|
+
.error?.issues.map((issue) => issue.path.join('.')) ?? [];
|
|
21
|
+
|
|
22
|
+
describe('resourceSchema', () => {
|
|
23
|
+
it('seeds a new resource with the defaults the form expects', () => {
|
|
24
|
+
expect(getDefaultsFromZodSchema(resourceSchema, {})).toMatchObject({
|
|
25
|
+
name: '',
|
|
26
|
+
rps: 10,
|
|
27
|
+
limit: 10,
|
|
28
|
+
description: '',
|
|
29
|
+
maxSuccessivelyErrors: 2,
|
|
30
|
+
errorIds: [],
|
|
31
|
+
patterns: [],
|
|
32
|
+
failureDialDelay: 0,
|
|
33
|
+
parameters: {
|
|
34
|
+
cidType: '',
|
|
35
|
+
ignoreEarlyMedia: '',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('accepts a filled resource', () => {
|
|
41
|
+
expect(resourceSchema.safeParse(filledResource).success).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('requires a name, a gateway, rps, limit and max successive errors', () => {
|
|
45
|
+
const paths = issuePaths({
|
|
46
|
+
name: '',
|
|
47
|
+
gateway: {},
|
|
48
|
+
rps: null,
|
|
49
|
+
limit: null,
|
|
50
|
+
maxSuccessivelyErrors: null,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(paths).toEqual(
|
|
54
|
+
expect.arrayContaining([
|
|
55
|
+
'name',
|
|
56
|
+
'gateway',
|
|
57
|
+
'rps',
|
|
58
|
+
'limit',
|
|
59
|
+
'maxSuccessivelyErrors',
|
|
60
|
+
]),
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('keeps rps and limit within their ranges', () => {
|
|
65
|
+
expect(
|
|
66
|
+
issuePaths({
|
|
67
|
+
...filledResource,
|
|
68
|
+
rps: 1001,
|
|
69
|
+
limit: 5001,
|
|
70
|
+
}),
|
|
71
|
+
).toEqual([
|
|
72
|
+
'rps',
|
|
73
|
+
'limit',
|
|
74
|
+
]);
|
|
75
|
+
expect(
|
|
76
|
+
issuePaths({
|
|
77
|
+
...filledResource,
|
|
78
|
+
rps: -2,
|
|
79
|
+
limit: -2,
|
|
80
|
+
}),
|
|
81
|
+
).toEqual([
|
|
82
|
+
'rps',
|
|
83
|
+
'limit',
|
|
84
|
+
]);
|
|
85
|
+
expect(
|
|
86
|
+
issuePaths({
|
|
87
|
+
...filledResource,
|
|
88
|
+
rps: -1,
|
|
89
|
+
limit: -1,
|
|
90
|
+
}),
|
|
91
|
+
).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('lets the failure dial delay be cleared', () => {
|
|
95
|
+
expect(
|
|
96
|
+
resourceSchema.safeParse({
|
|
97
|
+
...filledResource,
|
|
98
|
+
failureDialDelay: null,
|
|
99
|
+
}).success,
|
|
100
|
+
).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
});
|