@capillarytech/creatives-library 8.0.295 → 8.0.297

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 (39) hide show
  1. package/package.json +1 -1
  2. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +33 -0
  3. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +420 -0
  4. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +36 -0
  5. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +63 -0
  6. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +239 -0
  7. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +111 -0
  8. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +88 -0
  9. package/v2Components/CommonTestAndPreview/SendTestMessage.js +51 -1
  10. package/v2Components/CommonTestAndPreview/actions.js +20 -0
  11. package/v2Components/CommonTestAndPreview/constants.js +15 -0
  12. package/v2Components/CommonTestAndPreview/index.js +200 -16
  13. package/v2Components/CommonTestAndPreview/reducer.js +47 -0
  14. package/v2Components/CommonTestAndPreview/sagas.js +61 -0
  15. package/v2Components/CommonTestAndPreview/selectors.js +51 -0
  16. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +889 -0
  17. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +221 -0
  18. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +235 -0
  19. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +135 -0
  20. package/v2Components/CommonTestAndPreview/tests/actions.test.js +50 -0
  21. package/v2Components/CommonTestAndPreview/tests/constants.test.js +18 -0
  22. package/v2Components/CommonTestAndPreview/tests/index.test.js +783 -2
  23. package/v2Components/CommonTestAndPreview/tests/reducer.test.js +118 -0
  24. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +145 -0
  25. package/v2Components/CommonTestAndPreview/tests/selectors.test.js +146 -0
  26. package/v2Components/FormBuilder/index.js +1 -1
  27. package/v2Components/HtmlEditor/HTMLEditor.js +0 -1
  28. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +0 -1
  29. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +3 -132
  30. package/v2Components/HtmlEditor/hooks/useValidation.js +9 -12
  31. package/v2Components/HtmlEditor/utils/htmlValidator.js +2 -4
  32. package/v2Components/TestAndPreviewSlidebox/index.js +14 -0
  33. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +2 -2
  34. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +18 -110
  35. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +697 -12
  36. package/v2Containers/SmsTrai/Edit/index.js +5 -1
  37. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +201 -0
  38. package/v2Containers/Whatsapp/index.js +1 -1
  39. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +26242 -4225
@@ -65,6 +65,11 @@ import {
65
65
  IN_APP_CHANNEL_NAME,
66
66
  MOBILE_PUSH_CHANNEL_NAME,
67
67
  CHANNEL,
68
+ PHONE_NUMBER,
69
+ DYNAMIC_URL,
70
+ IMAGE,
71
+ VIDEO,
72
+ URL,
68
73
  } from './constants';
69
74
 
70
75
  // Import utilities
@@ -105,6 +110,10 @@ const CommonTestAndPreview = (props) => {
105
110
  updatePreviewErrors,
106
111
  fetchPrefilledValuesError,
107
112
  fetchPrefilledValuesErrors,
113
+ senderDetailsByChannel = {},
114
+ wecrmAccounts = [],
115
+ isLoadingSenderDetails = false,
116
+ orgUnitId = -1,
108
117
  // Email-specific props
109
118
  beeInstance,
110
119
  currentTab = 1,
@@ -146,6 +155,102 @@ const CommonTestAndPreview = (props) => {
146
155
  const [selectedTestEntities, setSelectedTestEntities] = useState([]);
147
156
  const [beeContent, setBeeContent] = useState(''); // Track BEE editor content separately (EMAIL only)
148
157
  const previousBeeContentRef = useRef(''); // Track previous BEE content (EMAIL only)
158
+ // Delivery settings for Test and Preview (SMS, Email, WhatsApp) — user selection only
159
+ const [testPreviewDeliverySettings, setTestPreviewDeliverySettings] = useState({
160
+ [CHANNELS.SMS]: {
161
+ domainId: null, domainGatewayMapId: null, gsmSenderId: '', cdmaSenderId: '',
162
+ },
163
+ [CHANNELS.EMAIL]: {
164
+ domainId: null, domainGatewayMapId: null, senderEmail: '', senderLabel: '', senderReplyTo: '',
165
+ },
166
+ [CHANNELS.WHATSAPP]: {
167
+ domainId: null, senderMobNum: '', sourceAccountIdentifier: '',
168
+ },
169
+ });
170
+
171
+ const channelsWithDeliverySettings = [CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP];
172
+ const formDataForSendTest = formData ?? (content && typeof content === 'object' && !Array.isArray(content) ? content : formData);
173
+ const smsTemplateConfigs = formDataForSendTest?.templateConfigs || {};
174
+ const smsTraiDltEnabled = !!smsTemplateConfigs?.traiDltEnabled;
175
+ const registeredSenderIds = smsTemplateConfigs?.registeredSenderIds || [];
176
+
177
+ // Fetch sender details and WeCRM accounts when Test & Preview opens for SMS/Email/WhatsApp
178
+ useEffect(() => {
179
+ if (!show || !channel) {
180
+ return;
181
+ }
182
+ if (channelsWithDeliverySettings.includes(channel)) {
183
+ if (actions.getSenderDetailsRequested) {
184
+ actions.getSenderDetailsRequested({ channel, orgUnitId: orgUnitId ?? -1 });
185
+ }
186
+ if (channel === CHANNELS.WHATSAPP && actions.getWeCrmAccountsRequested) {
187
+ actions.getWeCrmAccountsRequested({ sourceName: CHANNELS.WHATSAPP });
188
+ }
189
+ }
190
+ }, [show, channel, orgUnitId, actions]);
191
+
192
+ const findDefault = (arr) => (arr && arr.find((x) => x.default)) || (arr && arr[0]) || {};
193
+
194
+ // Auto-set default delivery setting when sender details load (campaigns-style: first domain + default/first sender)
195
+ useEffect(() => {
196
+ if (!channel || !channelsWithDeliverySettings.includes(channel)) return;
197
+ const domains = senderDetailsByChannel[channel];
198
+ if (!domains || domains.length === 0) return;
199
+ const {
200
+ domainId = '', gsmSenderId = '', senderEmail = '', senderMobNum = '',
201
+ } = testPreviewDeliverySettings[channel] || {};
202
+ const isEmptySelection = !domainId && !gsmSenderId && !senderEmail && !senderMobNum;
203
+ if (!isEmptySelection) return;
204
+
205
+ const whatsappAccountFromForm = channel === CHANNELS.WHATSAPP ? formData?.accountName : undefined;
206
+ const matchedWhatsappAccount = whatsappAccountFromForm
207
+ ? (wecrmAccounts || []).find((account) => account?.name === whatsappAccountFromForm)
208
+ : null;
209
+ const smsDomains = channel === CHANNELS.SMS && smsTraiDltEnabled
210
+ ? domains.filter((domain) => (domain.gsmSenders || []).some((gsm) => registeredSenderIds.includes(gsm.value)))
211
+ : domains;
212
+ const [defaultDomain] = domains;
213
+ const [firstSmsDomain] = smsDomains;
214
+ let firstDomain = defaultDomain;
215
+ if (channel === CHANNELS.WHATSAPP && matchedWhatsappAccount?.sourceAccountIdentifier) {
216
+ firstDomain = domains.find((domain) => domain?.sourceAccountIdentifier === matchedWhatsappAccount.sourceAccountIdentifier) || defaultDomain;
217
+ } else if (channel === CHANNELS.SMS) {
218
+ firstDomain = firstSmsDomain;
219
+ }
220
+ if (!firstDomain) return;
221
+ setTestPreviewDeliverySettings((prev) => {
222
+ const next = { ...prev };
223
+ if (channel === CHANNELS.SMS) {
224
+ const smsGsmSenders = smsTraiDltEnabled
225
+ ? (firstDomain.gsmSenders || []).filter((gsm) => registeredSenderIds.includes(gsm.value))
226
+ : firstDomain.gsmSenders;
227
+ next[channel] = {
228
+ domainId: firstDomain.domainId,
229
+ domainGatewayMapId: firstDomain.dgmId,
230
+ gsmSenderId: findDefault(smsGsmSenders)?.value || smsGsmSenders?.[0]?.value || '',
231
+ cdmaSenderId: findDefault(firstDomain.cdmaSenders)?.value || '',
232
+ };
233
+ } else if (channel === CHANNELS.EMAIL) {
234
+ const defSender = findDefault(firstDomain.emailSenders);
235
+ const defReply = findDefault(firstDomain.emailRepliers);
236
+ next[channel] = {
237
+ domainId: firstDomain.domainId,
238
+ domainGatewayMapId: firstDomain.dgmId,
239
+ senderEmail: defSender?.value || '',
240
+ senderLabel: defSender?.label || '',
241
+ senderReplyTo: defReply?.value || '',
242
+ };
243
+ } else if (channel === CHANNELS.WHATSAPP) {
244
+ const accId = firstDomain.sourceAccountIdentifier;
245
+ next[channel] = {
246
+ domainId: firstDomain.domainId,
247
+ senderMobNum: firstDomain.gsmSenders?.[0]?.value || '',
248
+ sourceAccountIdentifier: matchedWhatsappAccount?.sourceAccountIdentifier || accId || '',
249
+ };
250
+ }
251
+ return next;
252
+ });
253
+ }, [channel, formData?.accountName, senderDetailsByChannel, smsTraiDltEnabled, registeredSenderIds, wecrmAccounts]);
149
254
 
150
255
  // ============================================
151
256
  // MEMOIZED VALUES
@@ -442,7 +547,51 @@ const CommonTestAndPreview = (props) => {
442
547
  * Prepare payload for test message sending based on channel
443
548
  * Updated to match API structure with ouId, sourceEntityId, module, deliverySettings, etc.
444
549
  */
445
- const prepareTestMessagePayload = (channelType, formDataObj, contentStr, customValuesObj, recipientDetails, previewDataObj) => {
550
+
551
+ const getCarouselMappedData = (carouselData = []) => carouselData.map((carousel) => {
552
+ const {
553
+ bodyText, imageUrl, videoUrl, videoPreviewImg, buttons, mediaType, cardVarMapped, bodyTemplate,
554
+ } = carousel || {};
555
+ const buttonData = buttons.map((button, index) => {
556
+ const {
557
+ type, text, phone_number, urlType, url,
558
+ } = button || {};
559
+ const buttonObj = {
560
+ type,
561
+ text,
562
+ index,
563
+ };
564
+ if (type === PHONE_NUMBER) {
565
+ buttonObj.phoneNumber = phone_number;
566
+ }
567
+ if (type === URL) {
568
+ buttonObj.url = url;
569
+ if (urlType === DYNAMIC_URL) {
570
+ const dynamicUrlPayload = url?.match(/{{(.*?)}}/g);
571
+ buttonObj.dynamicUrlPayload = dynamicUrlPayload?.length === 1 ? dynamicUrlPayload[0] : '';
572
+ }
573
+ }
574
+ return buttonObj;
575
+ });
576
+ return {
577
+ body: bodyText,
578
+ cardVarMapped,
579
+ bodyTemplate,
580
+ media: {
581
+ ...(mediaType?.toLowerCase() === IMAGE.toLowerCase() && {
582
+ url: imageUrl,
583
+ }),
584
+ ...(mediaType?.toLowerCase() === VIDEO.toLowerCase() && {
585
+ url: videoUrl,
586
+ previewUrl: videoPreviewImg,
587
+ }),
588
+ },
589
+ buttons: buttonData,
590
+ mediaType: mediaType?.toUpperCase(),
591
+ };
592
+ });
593
+
594
+ const prepareTestMessagePayload = (channelType, formDataObj, contentStr, customValuesObj, recipientDetails, previewDataObj, deliverySettingsOverride) => {
446
595
  // Base payload structure common to all channels
447
596
  const basePayload = {
448
597
  ouId: -1,
@@ -468,6 +617,14 @@ const CommonTestAndPreview = (props) => {
468
617
  ? resolveTagsInText(subject, customValuesObj)
469
618
  : subject;
470
619
 
620
+ const emailChannelSettings = {
621
+ channel: CHANNELS.EMAIL,
622
+ senderLabel: deliverySettingsOverride?.senderLabel ?? '',
623
+ senderId: deliverySettingsOverride?.senderEmail ?? '',
624
+ replyToId: deliverySettingsOverride?.senderReplyTo ?? '',
625
+ domainGatewayMapId: deliverySettingsOverride?.domainGatewayMapId ?? '',
626
+ domainId: deliverySettingsOverride?.domainId ?? '',
627
+ };
471
628
  return {
472
629
  ...basePayload,
473
630
  emailDeliverySettings: {
@@ -478,12 +635,7 @@ const CommonTestAndPreview = (props) => {
478
635
  skipRateLimit: false,
479
636
  bypassControlUser: false,
480
637
  },
481
- channelSettings: {
482
- channel: CHANNELS.EMAIL,
483
- senderLabel: '',
484
- senderId: '',
485
- replyToId: '',
486
- },
638
+ channelSettings: emailChannelSettings,
487
639
  },
488
640
  emailMessageContent: {
489
641
  channel: CHANNELS.EMAIL,
@@ -520,8 +672,12 @@ const CommonTestAndPreview = (props) => {
520
672
  },
521
673
  smsDeliverySettings: {
522
674
  channelSettings: {
523
- gsmSenderId: '',
524
- domainId: null,
675
+ gsmSenderId: deliverySettingsOverride?.gsmSenderId ?? '',
676
+ domainId: deliverySettingsOverride?.domainId ?? null,
677
+ domainGatewayMapId: deliverySettingsOverride?.domainGatewayMapId ?? '',
678
+ targetNdnc: false,
679
+ cdmaSenderId: deliverySettingsOverride?.cdmaSenderId ?? '',
680
+ channel: CHANNELS.SMS,
525
681
  },
526
682
  additionalSettings: {
527
683
  useTinyUrl: false,
@@ -653,20 +809,21 @@ const CommonTestAndPreview = (props) => {
653
809
 
654
810
  // Add carousel data if mediaType is CAROUSEL
655
811
  if (mediaType === MEDIA_TYPE_CAROUSEL && formDataObj?.carouselData) {
656
- templateConfigs.cards = formDataObj.carouselData;
812
+ templateConfigs.cards = getCarouselMappedData(formDataObj.carouselData);
657
813
  templateConfigs.mediaType = formDataObj?.carouselMediaType?.toUpperCase() || MEDIA_TYPE_IMAGE;
658
814
  }
659
815
 
660
- // Extract delivery settings
661
- const senderMobNum = formDataObj?.senderMobNum || additionalProps?.senderMobNum || '';
662
- const domainId = formDataObj?.domainId || additionalProps?.domainId || null;
816
+ // Extract delivery settings (override from Test & Preview delivery settings when present)
817
+ const senderMobNum = deliverySettingsOverride?.senderMobNum ?? formDataObj?.senderMobNum ?? additionalProps?.senderMobNum ?? '';
818
+ const domainId = deliverySettingsOverride?.domainId ?? formDataObj?.domainId ?? additionalProps?.domainId ?? null;
819
+ const sourceAccountIdentifier = deliverySettingsOverride?.sourceAccountIdentifier ?? formDataObj?.sourceAccountIdentifier ?? '';
663
820
 
664
821
  return {
665
822
  ...basePayload,
666
823
  whatsappMessageContent: {
667
824
  messageBody: templateEditorValue || '',
668
825
  accountId: formDataObj?.accountId || '',
669
- sourceAccountIdentifier: formDataObj?.sourceAccountIdentifier || '',
826
+ sourceAccountIdentifier: sourceAccountIdentifier || formDataObj?.sourceAccountIdentifier || '',
670
827
  accountName: formDataObj?.accountName || '',
671
828
  templateConfigs,
672
829
  channel: CHANNELS.WHATSAPP,
@@ -2370,6 +2527,10 @@ const CommonTestAndPreview = (props) => {
2370
2527
  });
2371
2528
  const uniqueUserIds = [...new Set(allUserIds)];
2372
2529
 
2530
+ const deliveryOverride = [CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP].includes(channel)
2531
+ ? testPreviewDeliverySettings[channel]
2532
+ : null;
2533
+
2373
2534
  // Create initial payload based on channel
2374
2535
  const initialPayload = prepareTestMessagePayload(
2375
2536
  channel,
@@ -2377,7 +2538,8 @@ const CommonTestAndPreview = (props) => {
2377
2538
  getCurrentContent,
2378
2539
  customValues,
2379
2540
  uniqueUserIds,
2380
- previewData
2541
+ previewData,
2542
+ deliveryOverride
2381
2543
  );
2382
2544
 
2383
2545
  actions.createMessageMetaRequested(
@@ -2449,6 +2611,13 @@ const CommonTestAndPreview = (props) => {
2449
2611
  />
2450
2612
  );
2451
2613
 
2614
+ const handleSaveDeliverySettings = (values) => {
2615
+ setTestPreviewDeliverySettings((prev) => ({
2616
+ ...prev,
2617
+ [channel]: values,
2618
+ }));
2619
+ };
2620
+
2452
2621
  const renderSendTestMessage = () => (
2453
2622
  <SendTestMessage
2454
2623
  isFetchingTestCustomers={isFetchingTestCustomers}
@@ -2457,11 +2626,18 @@ const CommonTestAndPreview = (props) => {
2457
2626
  handleTestEntitiesChange={handleTestEntitiesChange}
2458
2627
  selectedTestEntities={selectedTestEntities}
2459
2628
  handleSendTestMessage={handleSendTestMessage}
2460
- formData={formData}
2629
+ formData={formDataForSendTest}
2461
2630
  content={getCurrentContent}
2462
2631
  channel={channel}
2463
2632
  isSendingTestMessage={isSendingTestMessage}
2464
2633
  formatMessage={formatMessage}
2634
+ deliverySettings={testPreviewDeliverySettings[channel]}
2635
+ senderDetailsOptions={senderDetailsByChannel[channel]}
2636
+ wecrmAccounts={wecrmAccounts}
2637
+ onSaveDeliverySettings={handleSaveDeliverySettings}
2638
+ isLoadingSenderDetails={isLoadingSenderDetails}
2639
+ smsTraiDltEnabled={smsTraiDltEnabled}
2640
+ registeredSenderIds={registeredSenderIds}
2465
2641
  />
2466
2642
  );
2467
2643
 
@@ -2562,6 +2738,10 @@ CommonTestAndPreview.propTypes = {
2562
2738
  })),
2563
2739
  isSendingTestMessage: PropTypes.bool.isRequired,
2564
2740
  intl: PropTypes.object.isRequired,
2741
+ senderDetailsByChannel: PropTypes.object,
2742
+ wecrmAccounts: PropTypes.array,
2743
+ isLoadingSenderDetails: PropTypes.bool,
2744
+ orgUnitId: PropTypes.number,
2565
2745
 
2566
2746
  // Email-specific props
2567
2747
  beeInstance: PropTypes.object,
@@ -2597,6 +2777,10 @@ CommonTestAndPreview.defaultProps = {
2597
2777
  rcsOrientation: null,
2598
2778
  rcsIosPreview: false,
2599
2779
  templateLayoutType: null,
2780
+ senderDetailsByChannel: {},
2781
+ wecrmAccounts: [],
2782
+ isLoadingSenderDetails: false,
2783
+ orgUnitId: -1,
2600
2784
  };
2601
2785
 
2602
2786
  // ============================================
@@ -31,6 +31,13 @@ import {
31
31
  GET_PREFILLED_VALUES_FAILURE,
32
32
  CLEAR_PREFILLED_VALUES,
33
33
  CLEAR_PREVIEW_ERRORS,
34
+ GET_SENDER_DETAILS_REQUESTED,
35
+ GET_SENDER_DETAILS_SUCCESS,
36
+ GET_SENDER_DETAILS_FAILURE,
37
+ GET_WECRM_ACCOUNTS_REQUESTED,
38
+ GET_WECRM_ACCOUNTS_SUCCESS,
39
+ GET_WECRM_ACCOUNTS_FAILURE,
40
+ CHANNELS,
34
41
  } from './constants';
35
42
 
36
43
  const initialState = fromJS({
@@ -85,6 +92,16 @@ const initialState = fromJS({
85
92
  isFetchingPrefilledValues: false,
86
93
  fetchPrefilledValuesError: null,
87
94
  fetchPrefilledValuesErrors: [],
95
+
96
+ senderDetailsByChannel: fromJS({
97
+ [CHANNELS.SMS]: [],
98
+ [CHANNELS.EMAIL]: [],
99
+ [CHANNELS.WHATSAPP]: [],
100
+ }),
101
+ wecrmAccounts: fromJS([]),
102
+ isLoadingSenderDetails: false,
103
+ fetchSenderDetailsError: null,
104
+ fetchWeCrmAccountsError: null,
88
105
  });
89
106
 
90
107
  const previewAndTestReducer = (state = initialState, action) => {
@@ -250,6 +267,36 @@ const previewAndTestReducer = (state = initialState, action) => {
250
267
  .set('fetchPrefilledValuesError', null)
251
268
  .set('fetchPrefilledValuesErrors', fromJS([]));
252
269
 
270
+ case GET_SENDER_DETAILS_REQUESTED:
271
+ return state
272
+ .set('isLoadingSenderDetails', true)
273
+ .set('fetchSenderDetailsError', null);
274
+
275
+ case GET_SENDER_DETAILS_SUCCESS: {
276
+ const { channel, domains } = action.payload || {};
277
+ if (!channel) return state;
278
+ return state
279
+ .setIn(['senderDetailsByChannel', channel], fromJS(domains || []))
280
+ .set('isLoadingSenderDetails', false)
281
+ .set('fetchSenderDetailsError', null);
282
+ }
283
+
284
+ case GET_SENDER_DETAILS_FAILURE:
285
+ return state
286
+ .set('isLoadingSenderDetails', false)
287
+ .set('fetchSenderDetailsError', action.payload?.error ?? action.payload);
288
+
289
+ case GET_WECRM_ACCOUNTS_REQUESTED:
290
+ return state.set('fetchWeCrmAccountsError', null);
291
+
292
+ case GET_WECRM_ACCOUNTS_SUCCESS:
293
+ return state
294
+ .set('wecrmAccounts', fromJS(action.payload?.accounts || []))
295
+ .set('fetchWeCrmAccountsError', null);
296
+
297
+ case GET_WECRM_ACCOUNTS_FAILURE:
298
+ return state.set('fetchWeCrmAccountsError', action.payload?.error ?? action.payload);
299
+
253
300
  default:
254
301
  return state;
255
302
  }
@@ -35,8 +35,16 @@ import {
35
35
  GET_PREFILLED_VALUES_REQUESTED,
36
36
  GET_PREFILLED_VALUES_SUCCESS,
37
37
  GET_PREFILLED_VALUES_FAILURE,
38
+ GET_SENDER_DETAILS_REQUESTED,
39
+ GET_SENDER_DETAILS_SUCCESS,
40
+ GET_SENDER_DETAILS_FAILURE,
41
+ GET_WECRM_ACCOUNTS_REQUESTED,
42
+ GET_WECRM_ACCOUNTS_SUCCESS,
43
+ GET_WECRM_ACCOUNTS_FAILURE,
38
44
  ERROR_MESSAGES,
45
+ CHANNELS,
39
46
  } from './constants';
47
+ import { parseSenderDetailsResponse } from './DeliverySettings/utils/parseSenderDetailsResponse';
40
48
 
41
49
  // Search Customers Saga
42
50
  export function* searchCustomersSaga(action) {
@@ -285,6 +293,57 @@ export function* watchGetPrefilledValues() {
285
293
  yield takeLatest(GET_PREFILLED_VALUES_REQUESTED, getPrefilledValuesSaga);
286
294
  }
287
295
 
296
+ export function* getSenderDetailsSaga(action) {
297
+ const { channel, orgUnitId } = action.payload || {};
298
+ if (!channel) return;
299
+ try {
300
+ const response = yield call(Api.getSenderDetails, channel, orgUnitId ?? -1);
301
+ if (response?.errors?.length) {
302
+ yield put({
303
+ type: GET_SENDER_DETAILS_FAILURE,
304
+ payload: { channel, error: response.errors },
305
+ });
306
+ return;
307
+ }
308
+ const parsed = parseSenderDetailsResponse(channel, response);
309
+ yield put({
310
+ type: GET_SENDER_DETAILS_SUCCESS,
311
+ payload: { channel, domains: parsed.domains || [] },
312
+ });
313
+ } catch (error) {
314
+ yield put({
315
+ type: GET_SENDER_DETAILS_FAILURE,
316
+ payload: { channel, error: error.message || error },
317
+ });
318
+ }
319
+ }
320
+
321
+ export function* getWeCrmAccountsSaga(action) {
322
+ const { sourceName } = action.payload || {};
323
+ try {
324
+ const result = yield call(Api.fetchWeCrmAccounts, sourceName || CHANNELS.WHATSAPP);
325
+ const accounts = get(result, 'response') || get(result, 'entity') || (result?.success ? result.response : null) || [];
326
+ const list = Array.isArray(accounts) ? accounts : (accounts && accounts.data) || [];
327
+ yield put({
328
+ type: GET_WECRM_ACCOUNTS_SUCCESS,
329
+ payload: { accounts: list },
330
+ });
331
+ } catch (error) {
332
+ yield put({
333
+ type: GET_WECRM_ACCOUNTS_FAILURE,
334
+ payload: { error: error.message || error },
335
+ });
336
+ }
337
+ }
338
+
339
+ export function* watchGetSenderDetails() {
340
+ yield takeLatest(GET_SENDER_DETAILS_REQUESTED, getSenderDetailsSaga);
341
+ }
342
+
343
+ export function* watchGetWeCrmAccounts() {
344
+ yield takeLatest(GET_WECRM_ACCOUNTS_REQUESTED, getWeCrmAccountsSaga);
345
+ }
346
+
288
347
  // Root saga
289
348
  export function* commonTestAndPreviewSaga() {
290
349
  yield all([
@@ -296,5 +355,7 @@ export function* commonTestAndPreviewSaga() {
296
355
  watchFetchTestGroups(),
297
356
  watchCreateMessageMeta(),
298
357
  watchGetPrefilledValues(),
358
+ watchGetSenderDetails(),
359
+ watchGetWeCrmAccounts(),
299
360
  ]);
300
361
  }
@@ -144,6 +144,51 @@ const makeSelectFetchPrefilledValuesErrors = () => createSelector(
144
144
  (substate) => substate.get('fetchPrefilledValuesErrors')?.toJS() || [],
145
145
  );
146
146
 
147
+ const makeSelectSenderDetailsForChannel = (channel) => createSelector(
148
+ selectCommonTestAndPreviewDomain,
149
+ (substate) => {
150
+ if (!substate) return [];
151
+ const byChannel = substate.get('senderDetailsByChannel');
152
+ if (!byChannel) return [];
153
+ const list = byChannel.get(channel);
154
+ return list ? list.toJS() : [];
155
+ },
156
+ );
157
+
158
+ const makeSelectSenderDetailsByChannel = () => createSelector(
159
+ selectCommonTestAndPreviewDomain,
160
+ (substate) => {
161
+ if (!substate) return {};
162
+ const byChannel = substate.get('senderDetailsByChannel');
163
+ if (!byChannel) return {};
164
+ return byChannel.toJS ? byChannel.toJS() : {};
165
+ },
166
+ );
167
+
168
+ const makeSelectWeCrmAccounts = () => createSelector(
169
+ selectCommonTestAndPreviewDomain,
170
+ (substate) => {
171
+ if (!substate) return [];
172
+ const list = substate.get('wecrmAccounts');
173
+ return list ? list.toJS() : [];
174
+ },
175
+ );
176
+
177
+ const makeSelectIsLoadingSenderDetails = () => createSelector(
178
+ selectCommonTestAndPreviewDomain,
179
+ (substate) => substate.get('isLoadingSenderDetails') || false,
180
+ );
181
+
182
+ const makeSelectFetchSenderDetailsError = () => createSelector(
183
+ selectCommonTestAndPreviewDomain,
184
+ (substate) => substate.get('fetchSenderDetailsError'),
185
+ );
186
+
187
+ const makeSelectFetchWeCrmAccountsError = () => createSelector(
188
+ selectCommonTestAndPreviewDomain,
189
+ (substate) => substate.get('fetchWeCrmAccountsError'),
190
+ );
191
+
147
192
  export {
148
193
  makeSelectCommonTestAndPreview,
149
194
  makeSelectCustomers,
@@ -171,4 +216,10 @@ export {
171
216
  makeSelectUpdatePreviewErrors,
172
217
  makeSelectFetchPrefilledValuesError,
173
218
  makeSelectFetchPrefilledValuesErrors,
219
+ makeSelectSenderDetailsForChannel,
220
+ makeSelectSenderDetailsByChannel,
221
+ makeSelectWeCrmAccounts,
222
+ makeSelectIsLoadingSenderDetails,
223
+ makeSelectFetchSenderDetailsError,
224
+ makeSelectFetchWeCrmAccountsError,
174
225
  };