@webitel/api-services 0.1.69 → 0.1.70

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.
Files changed (89) hide show
  1. package/package.json +3 -1
  2. package/src/api/clients/_shared/types.ts +25 -0
  3. package/src/api/clients/index.ts +8 -0
  4. package/src/api/clients/queues/__tests__/fieldsToSend.spec.ts +135 -0
  5. package/src/api/clients/queues/__tests__/queueLogs.spec.ts +132 -0
  6. package/src/api/clients/queues/__tests__/queueMembers.spec.ts +175 -0
  7. package/src/api/clients/queues/__tests__/queues.spec.ts +130 -0
  8. package/src/api/clients/queues/defaults/__tests__/queueTypeDefaults.spec.ts +143 -0
  9. package/src/api/clients/queues/defaults/amd.ts +17 -0
  10. package/src/api/clients/queues/defaults/defaultQueue.ts +9 -0
  11. package/src/api/clients/queues/defaults/processing.ts +8 -4
  12. package/src/api/clients/queues/defaults/queueTypeDefaults.ts +305 -0
  13. package/src/api/clients/queues/queueAgents.ts +48 -0
  14. package/src/api/clients/queues/queueBuckets.ts +187 -0
  15. package/src/api/clients/queues/queueHooks.ts +184 -0
  16. package/src/api/clients/queues/queueLogs.ts +80 -0
  17. package/src/api/clients/queues/queueMembers.ts +426 -0
  18. package/src/api/clients/queues/queueResGroups.ts +176 -0
  19. package/src/api/clients/queues/queueSkills.ts +183 -0
  20. package/src/api/clients/queues/queueState.ts +97 -0
  21. package/src/api/clients/queues/queues.ts +124 -94
  22. package/src/api/clients/queues/scripts/__tests__/mapResetMembersFilters.spec.ts +132 -0
  23. package/src/api/clients/queues/scripts/mapResetMembersFilters.ts +52 -0
  24. package/src/enums/CallReportingStatus/CallReportingStatus.ts +13 -0
  25. package/src/enums/MemberStopCause/MemberStopCause.ts +13 -0
  26. package/src/enums/QueueStrategy/QueueStrategy.ts +27 -0
  27. package/src/enums/QueueType/QueueType.ts +31 -0
  28. package/src/enums/TimeBaseScore/TimeBaseScore.ts +6 -0
  29. package/src/enums/TypesResourceStrategy/TypesResourceStrategy.ts +7 -0
  30. package/src/enums/index.ts +21 -1
  31. package/src/scripts/index.ts +19 -1
  32. package/src/scripts/normalizeDatetime/normalizeDatetime.ts +132 -0
  33. package/src/validations/_shared/isFilled.ts +15 -0
  34. package/src/validations/_shared/lookup.validations.ts +28 -0
  35. package/src/validations/_shared/variablePair.validations.ts +18 -0
  36. package/src/validations/index.ts +12 -0
  37. package/src/validations/queue/__tests__/queue.validations.spec.ts +159 -0
  38. package/src/validations/queue/queue.rules.ts +166 -0
  39. package/src/validations/queue/queue.validations.ts +105 -0
  40. package/src/validations/queue/queueAmd.validations.ts +22 -0
  41. package/src/validations/queue/queuePayload.validations.ts +71 -0
  42. package/src/validations/queue/taskProcessing.validations.ts +21 -0
  43. package/src/validations/queueBucket/queueBucket.validations.ts +10 -0
  44. package/src/validations/queueHook/queueHook.validations.ts +10 -0
  45. package/src/validations/queueMember/memberCommunication.validations.ts +25 -0
  46. package/src/validations/queueMember/queueMember.validations.ts +38 -0
  47. package/src/validations/queueResGroup/queueResGroup.validations.ts +15 -0
  48. package/src/validations/queueSkill/queueSkill.validations.ts +42 -0
  49. package/types/.tsbuildinfo +1 -1
  50. package/types/api/clients/_shared/types.d.ts +20 -0
  51. package/types/api/clients/index.d.ts +8 -0
  52. package/types/api/clients/queues/defaults/amd.d.ts +17 -0
  53. package/types/api/clients/queues/defaults/defaultQueue.d.ts +9 -0
  54. package/types/api/clients/queues/defaults/processing.d.ts +7 -2
  55. package/types/api/clients/queues/defaults/queueTypeDefaults.d.ts +31 -0
  56. package/types/api/clients/queues/queueAgents.d.ts +7 -0
  57. package/types/api/clients/queues/queueBuckets.d.ts +12 -0
  58. package/types/api/clients/queues/queueHooks.d.ts +12 -0
  59. package/types/api/clients/queues/queueLogs.d.ts +7 -0
  60. package/types/api/clients/queues/queueMembers.d.ts +30 -0
  61. package/types/api/clients/queues/queueResGroups.d.ts +15 -0
  62. package/types/api/clients/queues/queueSkills.d.ts +12 -0
  63. package/types/api/clients/queues/queueState.d.ts +8 -0
  64. package/types/api/clients/queues/queues.d.ts +9 -1
  65. package/types/api/clients/queues/scripts/mapResetMembersFilters.d.ts +30 -0
  66. package/types/enums/CallReportingStatus/CallReportingStatus.d.ts +11 -0
  67. package/types/enums/MemberStopCause/MemberStopCause.d.ts +11 -0
  68. package/types/enums/QueueStrategy/QueueStrategy.d.ts +21 -0
  69. package/types/enums/QueueType/QueueType.d.ts +28 -0
  70. package/types/enums/TimeBaseScore/TimeBaseScore.d.ts +5 -0
  71. package/types/enums/TypesResourceStrategy/TypesResourceStrategy.d.ts +5 -0
  72. package/types/enums/index.d.ts +7 -1
  73. package/types/scripts/index.d.ts +3 -1
  74. package/types/scripts/normalizeDatetime/normalizeDatetime.d.ts +14 -0
  75. package/types/validations/_shared/isFilled.d.ts +9 -0
  76. package/types/validations/_shared/lookup.validations.d.ts +18 -0
  77. package/types/validations/_shared/variablePair.validations.d.ts +16 -0
  78. package/types/validations/index.d.ts +12 -0
  79. package/types/validations/queue/queue.rules.d.ts +21 -0
  80. package/types/validations/queue/queue.validations.d.ts +285 -0
  81. package/types/validations/queue/queueAmd.validations.d.ts +22 -0
  82. package/types/validations/queue/queuePayload.validations.d.ts +75 -0
  83. package/types/validations/queue/taskProcessing.validations.d.ts +22 -0
  84. package/types/validations/queueBucket/queueBucket.validations.d.ts +9 -0
  85. package/types/validations/queueHook/queueHook.validations.d.ts +10 -0
  86. package/types/validations/queueMember/memberCommunication.validations.d.ts +16 -0
  87. package/types/validations/queueMember/queueMember.validations.d.ts +48 -0
  88. package/types/validations/queueResGroup/queueResGroup.validations.d.ts +11 -0
  89. package/types/validations/queueSkill/queueSkill.validations.d.ts +34 -0
@@ -0,0 +1,143 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { QueueType } from '../../../../../enums';
4
+ import { processing } from '../processing';
5
+ import {
6
+ getQueueDefaults,
7
+ hasQueueTypeDefaults,
8
+ QueueTypeDefaults,
9
+ } from '../queueTypeDefaults';
10
+
11
+ const allQueueTypes = Object.values(QueueType);
12
+
13
+ /** The two types whose legacy schema deliberately has no `taskProcessing`. */
14
+ const typesWithoutTaskProcessing = [
15
+ QueueType.OUTBOUND_IVR_QUEUE,
16
+ QueueType.OUTBOUND_JOB_QUEUE,
17
+ ];
18
+
19
+ /** The three types whose legacy schema carries `payload.amd`. */
20
+ const typesWithAmd = [
21
+ QueueType.OUTBOUND_IVR_QUEUE,
22
+ QueueType.PROGRESSIVE_DIALER,
23
+ QueueType.PREDICTIVE_DIALER,
24
+ ];
25
+
26
+ describe('queue type defaults', () => {
27
+ it('has a factory for every QueueType', () => {
28
+ for (const type of allQueueTypes) {
29
+ expect(QueueTypeDefaults[type], `missing factory for ${type}`).toBeTypeOf(
30
+ 'function',
31
+ );
32
+ }
33
+ expect(Object.keys(QueueTypeDefaults)).toHaveLength(allQueueTypes.length);
34
+ });
35
+
36
+ it('stamps each factory with its own type', () => {
37
+ for (const type of allQueueTypes) {
38
+ expect(QueueTypeDefaults[type]().type).toBe(type);
39
+ }
40
+ });
41
+
42
+ /**
43
+ * The legacy code used factories precisely so two queues never shared a
44
+ * nested object. A plain object export would let edits on one new queue
45
+ * leak into the next one opened.
46
+ */
47
+ it('returns a fresh deep object on every call', () => {
48
+ for (const type of allQueueTypes) {
49
+ const a = QueueTypeDefaults[type]();
50
+ const b = QueueTypeDefaults[type]();
51
+
52
+ expect(a).not.toBe(b);
53
+ expect(a).toEqual(b);
54
+ expect(a.payload).not.toBe(b.payload);
55
+ expect(a.variables).not.toBe(b.variables);
56
+ }
57
+ });
58
+
59
+ it('keeps taskProcessing exactly where the legacy schema had it', () => {
60
+ for (const type of allQueueTypes) {
61
+ const defaults = QueueTypeDefaults[type]();
62
+
63
+ if (typesWithoutTaskProcessing.includes(type)) {
64
+ expect(defaults.taskProcessing, `${type}`).toBeUndefined();
65
+ } else {
66
+ expect(defaults.taskProcessing, `${type}`).toBeDefined();
67
+ }
68
+ }
69
+ });
70
+
71
+ it('keeps payload.amd exactly where the legacy schema had it', () => {
72
+ for (const type of allQueueTypes) {
73
+ const { payload } = QueueTypeDefaults[type]();
74
+
75
+ expect(Boolean(payload.amd), `${type}`).toBe(typesWithAmd.includes(type));
76
+ }
77
+ });
78
+
79
+ /**
80
+ * Regression guard: api-services' `processing()` used to omit
81
+ * `prolongationOptions`, which left the Processing tab's prolongation block
82
+ * without Regle `$fields` — no required markers, no error text.
83
+ */
84
+ it('seeds taskProcessing.prolongationOptions', () => {
85
+ expect(processing().prolongationOptions).toEqual({
86
+ enabled: false,
87
+ isTimeoutRetry: false,
88
+ prolongationTimeSec: 30,
89
+ repeatsNumber: 1,
90
+ });
91
+
92
+ const defaults = QueueTypeDefaults[QueueType.INBOUND_QUEUE]();
93
+
94
+ expect(defaults.taskProcessing).toMatchObject({
95
+ prolongationOptions: {
96
+ repeatsNumber: 1,
97
+ },
98
+ });
99
+ });
100
+
101
+ it('treats IM_CHAT_QUEUE as CHAT_INBOUND_QUEUE apart from the type', () => {
102
+ const chat = QueueTypeDefaults[QueueType.CHAT_INBOUND_QUEUE]();
103
+ const imChat = QueueTypeDefaults[QueueType.IM_CHAT_QUEUE]();
104
+
105
+ expect({
106
+ ...imChat,
107
+ type: chat.type,
108
+ }).toEqual(chat);
109
+ });
110
+ });
111
+
112
+ describe('getQueueDefaults', () => {
113
+ it('resolves a numeric type', () => {
114
+ expect(getQueueDefaults(QueueType.PREVIEW_DIALER).type).toBe(
115
+ QueueType.PREVIEW_DIALER,
116
+ );
117
+ });
118
+
119
+ /** The card page reads `?type=` off the route, so it arrives as a string. */
120
+ it('resolves a stringified type from the route query', () => {
121
+ expect(getQueueDefaults(String(QueueType.PREDICTIVE_DIALER)).type).toBe(
122
+ QueueType.PREDICTIVE_DIALER,
123
+ );
124
+ });
125
+
126
+ it('falls back to the base queue shape for an unknown type', () => {
127
+ const defaults = getQueueDefaults(undefined);
128
+
129
+ expect(defaults.type).toBeUndefined();
130
+ expect(defaults).toMatchObject({
131
+ name: '',
132
+ priority: 0,
133
+ variables: [],
134
+ });
135
+ });
136
+
137
+ it('reports whether a type has defaults', () => {
138
+ expect(hasQueueTypeDefaults(QueueType.OFFLINE_QUEUE)).toBe(true);
139
+ expect(hasQueueTypeDefaults('4')).toBe(true);
140
+ expect(hasQueueTypeDefaults(42)).toBe(false);
141
+ expect(hasQueueTypeDefaults(undefined)).toBe(false);
142
+ });
143
+ });
@@ -0,0 +1,17 @@
1
+ export const amd = () => ({
2
+ enabled: false,
3
+ ai: false,
4
+ positive: [],
5
+ playback: {},
6
+ allowNotSure: false,
7
+ silenceNotSure: false,
8
+ maxWordLength: 5000,
9
+ maxNumberOfWords: 3,
10
+ betweenWordsSilence: 50,
11
+ minWordLength: 100,
12
+ totalAnalysisTime: 5000,
13
+ silenceThreshold: 256,
14
+ afterGreetingSilence: 800,
15
+ greeting: 1500,
16
+ initialSilence: 2500,
17
+ });
@@ -0,0 +1,9 @@
1
+ export const defaultQueue = () => ({
2
+ name: '',
3
+ description: '',
4
+ priority: 0,
5
+ tags: [],
6
+ dncList: {},
7
+ calendar: {},
8
+ variables: [],
9
+ });
@@ -1,14 +1,18 @@
1
1
  import deepmerge from 'deepmerge';
2
2
 
3
- const processing = (processing = {}) =>
3
+ export const processing = (overrides = {}) =>
4
4
  deepmerge(
5
5
  {
6
6
  enabled: false,
7
7
  formSchema: {},
8
8
  sec: 30,
9
9
  renewalSec: 15,
10
+ prolongationOptions: {
11
+ enabled: false,
12
+ isTimeoutRetry: false,
13
+ prolongationTimeSec: 30,
14
+ repeatsNumber: 1,
15
+ },
10
16
  },
11
- processing,
17
+ overrides,
12
18
  );
13
-
14
- export default processing;
@@ -0,0 +1,305 @@
1
+ import {
2
+ QueueStrategy,
3
+ QueueType,
4
+ TimeBaseScore,
5
+ TypesResourceStrategy,
6
+ } from '../../../../enums';
7
+ import { amd } from './amd';
8
+ import { defaultQueue } from './defaultQueue';
9
+ import { processing } from './processing';
10
+
11
+ /**
12
+ * @description
13
+ * The default field set a queue of a given type is created with.
14
+ *
15
+ * These are NOT cosmetic. Regle builds its nested `$fields` from the *state*
16
+ * keys, not from the Zod schema shape — a field that is declared in
17
+ * `queueSchema` but missing from the draft has no validation entry at all, so
18
+ * its required marker and error text silently disappear from the form.
19
+ * Every key a queue type's UI can touch must therefore be seeded here, on
20
+ * create (via the card store) and on read (see `QueuesAPI.get`).
21
+ *
22
+ * Ported 1:1 from the admin app's legacy `store/_internals/queueSchema/*.js`.
23
+ * Keep the per-type key sets exactly as they are: `sanitize(fieldsToSend)` only
24
+ * filters top-level keys, so `payload` is sent whole and a stray cross-type
25
+ * field (e.g. `progressiveCount` on an inbound queue) would reach the backend.
26
+ */
27
+ export interface QueueDefaults {
28
+ [key: string]: unknown;
29
+ type: QueueType;
30
+ payload: Record<string, unknown>;
31
+ }
32
+
33
+ const offlineQueue = (): QueueDefaults => ({
34
+ ...defaultQueue(),
35
+ type: QueueType.OFFLINE_QUEUE,
36
+ team: {},
37
+ strategy: QueueStrategy.FIFO,
38
+ doSchema: {},
39
+ afterSchema: {},
40
+ grantee: {},
41
+ taskProcessing: processing(),
42
+ payload: {
43
+ maxAttempts: 3,
44
+ waitBetweenRetries: 30 * 60,
45
+ originateTimeout: 60,
46
+ recordings: false,
47
+ recordAll: false,
48
+ perNumbers: false,
49
+ minOnlineAgents: 0,
50
+ maxMemberLimit: 0,
51
+ },
52
+ });
53
+
54
+ const inboundQueue = (): QueueDefaults => ({
55
+ ...defaultQueue(),
56
+ type: QueueType.INBOUND_QUEUE,
57
+ team: {},
58
+ ringtone: {},
59
+ grantee: {},
60
+ stickyAgent: false,
61
+ taskProcessing: processing(),
62
+ payload: {
63
+ discardAbandonedAfter: 0,
64
+ timeBaseScore: TimeBaseScore.QUEUE,
65
+ maxWaitTime: 60 * 60,
66
+ allowGreetingAgent: false,
67
+ stickyIgnoreStatus: false,
68
+ ignoreCalendar: false,
69
+ stickyAgentSec: 5,
70
+ maxWaitingSize: 0,
71
+ autoAnswerTone: null,
72
+ minOnlineAgents: 0,
73
+ manualDistribution: false,
74
+ maxMemberLimit: 0,
75
+ },
76
+ });
77
+
78
+ /** NB: no `taskProcessing` — matches the legacy schema exactly. */
79
+ const outboundIVRQueue = (): QueueDefaults => ({
80
+ ...defaultQueue(),
81
+ type: QueueType.OUTBOUND_IVR_QUEUE,
82
+ strategy: QueueStrategy.FIFO,
83
+ schema: {},
84
+ doSchema: {},
85
+ afterSchema: {},
86
+ grantee: {},
87
+ payload: {
88
+ minDuration: 3,
89
+ maxAttempts: 3,
90
+ originateTimeout: 60,
91
+ waitBetweenRetries: 30 * 60,
92
+ waitBetweenRetriesDesc: false,
93
+ maxCalls: 10,
94
+ recordings: false,
95
+ recordAll: false,
96
+ amd: amd(),
97
+ strictCircuit: false,
98
+ perNumbers: false,
99
+ resourceStrategy: TypesResourceStrategy.EVEN_DISTRIBUTION,
100
+ maxMemberLimit: 0,
101
+ },
102
+ });
103
+
104
+ const previewDialer = (): QueueDefaults => ({
105
+ ...defaultQueue(),
106
+ type: QueueType.PREVIEW_DIALER,
107
+ team: {},
108
+ strategy: QueueStrategy.FIFO,
109
+ doSchema: {},
110
+ afterSchema: {},
111
+ grantee: {},
112
+ stickyAgent: false,
113
+ taskProcessing: processing(),
114
+ payload: {
115
+ maxAttempts: 3,
116
+ originateTimeout: 60,
117
+ waitBetweenRetries: 30 * 60,
118
+ waitBetweenRetriesDesc: false,
119
+ maxCalls: 10,
120
+ recordings: false,
121
+ recordAll: false,
122
+ allowGreetingAgent: false,
123
+ strictCircuit: false,
124
+ endless: false,
125
+ perNumbers: false,
126
+ minOnlineAgents: 0,
127
+ resourceStrategy: TypesResourceStrategy.EVEN_DISTRIBUTION,
128
+ maxMemberLimit: 0,
129
+ },
130
+ });
131
+
132
+ const progressiveDialer = (): QueueDefaults => ({
133
+ ...defaultQueue(),
134
+ type: QueueType.PROGRESSIVE_DIALER,
135
+ team: {},
136
+ strategy: QueueStrategy.FIFO,
137
+ doSchema: {},
138
+ afterSchema: {},
139
+ ringtone: {},
140
+ grantee: {},
141
+ stickyAgent: false,
142
+ taskProcessing: processing(),
143
+ payload: {
144
+ maxAttempts: 3,
145
+ originateTimeout: 60,
146
+ waitBetweenRetries: 30 * 60,
147
+ progressiveCount: 1,
148
+ waitBetweenRetriesDesc: false,
149
+ recordings: false,
150
+ recordAll: false,
151
+ allowGreetingAgent: false,
152
+ maxCalls: 10,
153
+ amd: amd(),
154
+ strictCircuit: false,
155
+ endless: false,
156
+ perNumbers: false,
157
+ autoAnswerTone: null,
158
+ minOnlineAgents: 0,
159
+ resourceStrategy: TypesResourceStrategy.EVEN_DISTRIBUTION,
160
+ maxMemberLimit: 0,
161
+ },
162
+ });
163
+
164
+ const predictiveDialer = (): QueueDefaults => ({
165
+ ...defaultQueue(),
166
+ type: QueueType.PREDICTIVE_DIALER,
167
+ strategy: QueueStrategy.FIFO,
168
+ team: {},
169
+ doSchema: {},
170
+ afterSchema: {},
171
+ ringtone: {},
172
+ grantee: {},
173
+ stickyAgent: false,
174
+ taskProcessing: processing(),
175
+ payload: {
176
+ maxWaitTime: 10,
177
+ maxAttempts: 3,
178
+ originateTimeout: 60,
179
+ waitBetweenRetries: 30 * 60,
180
+ progressiveCount: 1,
181
+ waitBetweenRetriesDesc: false,
182
+ retryAbandoned: false,
183
+ recordings: false,
184
+ recordAll: false,
185
+ allowGreetingAgent: false,
186
+ maxCalls: 10,
187
+ dialingRate: 5,
188
+ amd: amd(),
189
+ maxAgentLine: 5,
190
+ minAttempts: 3,
191
+ maxAbandonedRate: 5.0,
192
+ targetAbandonedRate: 3.0,
193
+ loadFactor: 10,
194
+ maxAgentLose: 1,
195
+ abandonRateAdjustment: 0,
196
+ playbackSilence: 0,
197
+ strictCircuit: false,
198
+ statisticTime: 60,
199
+ endless: false,
200
+ perNumbers: false,
201
+ stickyAgentSec: 5,
202
+ autoAnswerTone: null,
203
+ minOnlineAgents: 0,
204
+ resourceStrategy: TypesResourceStrategy.EVEN_DISTRIBUTION,
205
+ maxMemberLimit: 0,
206
+ },
207
+ });
208
+
209
+ const chatInboundQueue = (): QueueDefaults => ({
210
+ ...defaultQueue(),
211
+ type: QueueType.CHAT_INBOUND_QUEUE,
212
+ team: {},
213
+ strategy: QueueStrategy.FIFO,
214
+ formSchema: {},
215
+ stickyAgent: false,
216
+ taskProcessing: processing(),
217
+ payload: {
218
+ discardAbandonedAfter: 0,
219
+ timeBaseScore: TimeBaseScore.QUEUE,
220
+ maxWaitTime: 60 * 60,
221
+ stickyAgentSec: 5,
222
+ stickyIgnoreStatus: false,
223
+ ignoreCalendar: false,
224
+ maxIdleAgent: 60 * 60,
225
+ maxIdleClient: 60 * 60,
226
+ maxIdleDialog: 0,
227
+ maxWaitingSize: 0,
228
+ minOnlineAgents: 0,
229
+ manualDistribution: false,
230
+ lastMessageTimeout: false,
231
+ maxMemberLimit: 0,
232
+ },
233
+ });
234
+
235
+ /** Identical to CHAT_INBOUND_QUEUE apart from `type` — as in the legacy schema. */
236
+ const imChatQueue = (): QueueDefaults => ({
237
+ ...chatInboundQueue(),
238
+ type: QueueType.IM_CHAT_QUEUE,
239
+ });
240
+
241
+ const inboundJobQueue = (): QueueDefaults => ({
242
+ ...defaultQueue(),
243
+ type: QueueType.INBOUND_JOB_QUEUE,
244
+ team: {},
245
+ strategy: QueueStrategy.FIFO,
246
+ doSchema: {},
247
+ afterSchema: {},
248
+ stickyAgent: false,
249
+ taskProcessing: processing(),
250
+ payload: {
251
+ maxAttempts: 3,
252
+ waitBetweenRetries: 30 * 60,
253
+ maxCalls: 10,
254
+ waitBetweenRetriesDesc: false,
255
+ minOnlineAgents: 0,
256
+ maxMemberLimit: 0,
257
+ },
258
+ });
259
+
260
+ /** NB: no `taskProcessing` — matches the legacy schema exactly. */
261
+ const outboundJobQueue = (): QueueDefaults => ({
262
+ ...defaultQueue(),
263
+ type: QueueType.OUTBOUND_JOB_QUEUE,
264
+ strategy: QueueStrategy.FIFO,
265
+ schema: {},
266
+ doSchema: {},
267
+ afterSchema: {},
268
+ payload: {
269
+ maxAttempts: 3,
270
+ originateTimeout: 60,
271
+ waitBetweenRetries: 30 * 60,
272
+ waitBetweenRetriesDesc: false,
273
+ maxCalls: 10,
274
+ strictCircuit: false,
275
+ perNumbers: false,
276
+ maxMemberLimit: 0,
277
+ },
278
+ });
279
+
280
+ export const QueueTypeDefaults: Record<number, () => QueueDefaults> = {
281
+ [QueueType.OFFLINE_QUEUE]: offlineQueue,
282
+ [QueueType.INBOUND_QUEUE]: inboundQueue,
283
+ [QueueType.OUTBOUND_IVR_QUEUE]: outboundIVRQueue,
284
+ [QueueType.PREVIEW_DIALER]: previewDialer,
285
+ [QueueType.PROGRESSIVE_DIALER]: progressiveDialer,
286
+ [QueueType.PREDICTIVE_DIALER]: predictiveDialer,
287
+ [QueueType.CHAT_INBOUND_QUEUE]: chatInboundQueue,
288
+ [QueueType.IM_CHAT_QUEUE]: imChatQueue,
289
+ [QueueType.INBOUND_JOB_QUEUE]: inboundJobQueue,
290
+ [QueueType.OUTBOUND_JOB_QUEUE]: outboundJobQueue,
291
+ };
292
+
293
+ export const hasQueueTypeDefaults = (type: number | string | undefined) =>
294
+ Number(type) in QueueTypeDefaults;
295
+
296
+ /**
297
+ * @description
298
+ * A fresh defaults object for `type`. Always a new object — callers deepmerge
299
+ * into it, and the legacy code relied on factories for exactly this reason.
300
+ * Falls back to the type-agnostic base when `type` is unknown.
301
+ */
302
+ export const getQueueDefaults = (
303
+ type: number | string | undefined,
304
+ ): Partial<QueueDefaults> =>
305
+ QueueTypeDefaults[Number(type)]?.() ?? defaultQueue();
@@ -0,0 +1,48 @@
1
+ import { getAgentService } from '@webitel/api-services/gen';
2
+ import { getDefaultGetListResponse, getDefaultGetParams } from '../../defaults';
3
+ import {
4
+ applyTransform,
5
+ merge,
6
+ notify,
7
+ snakeToCamel,
8
+ } from '../../transformers';
9
+ import type { ApiParams } from '../_shared/types';
10
+
11
+ const getQueueAgentsList = async (params: ApiParams) => {
12
+ const { parentId, page, size, search, fields, sort } = applyTransform(
13
+ params,
14
+ [
15
+ merge(getDefaultGetParams()),
16
+ ],
17
+ );
18
+
19
+ try {
20
+ const response = await getAgentService().searchAgent({
21
+ page,
22
+ size,
23
+ // the generated param is `q`; `search` is what the datalist store sends
24
+ q: search,
25
+ sort,
26
+ fields,
27
+ queueId: [
28
+ Number(parentId),
29
+ ],
30
+ });
31
+ const { items, next } = applyTransform(response.data, [
32
+ snakeToCamel(),
33
+ merge(getDefaultGetListResponse()),
34
+ ]);
35
+ return {
36
+ items,
37
+ next,
38
+ };
39
+ } catch (err) {
40
+ throw applyTransform(err, [
41
+ notify,
42
+ ]);
43
+ }
44
+ };
45
+
46
+ export const QueueAgentsAPI = {
47
+ getList: getQueueAgentsList,
48
+ };