@capillarytech/creatives-library 8.0.345-alpha.15 → 8.0.345-alpha.16

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 (130) hide show
  1. package/constants/unified.js +0 -29
  2. package/package.json +1 -1
  3. package/services/tests/api.test.js +0 -13
  4. package/utils/commonUtils.js +1 -19
  5. package/v2Components/CapActionButton/constants.js +0 -7
  6. package/v2Components/CapActionButton/index.js +109 -167
  7. package/v2Components/CapActionButton/index.scss +6 -157
  8. package/v2Components/CapActionButton/messages.js +3 -19
  9. package/v2Components/CapActionButton/tests/index.test.js +17 -41
  10. package/v2Components/CapTagList/index.js +0 -10
  11. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
  12. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  13. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
  14. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  18. package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
  19. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
  20. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
  21. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  22. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
  23. package/v2Components/CommonTestAndPreview/constants.js +2 -38
  24. package/v2Components/CommonTestAndPreview/index.js +186 -676
  25. package/v2Components/CommonTestAndPreview/messages.js +3 -49
  26. package/v2Components/CommonTestAndPreview/sagas.js +6 -15
  27. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
  28. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  29. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  30. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  31. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
  32. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
  33. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
  34. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  35. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
  36. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  37. package/v2Components/FormBuilder/index.js +10 -8
  38. package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
  39. package/v2Components/TemplatePreview/index.js +28 -143
  40. package/v2Components/TemplatePreview/tests/index.test.js +0 -142
  41. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  42. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  43. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  44. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  45. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
  46. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  47. package/v2Containers/CreativesContainer/constants.js +0 -9
  48. package/v2Containers/CreativesContainer/index.js +103 -300
  49. package/v2Containers/CreativesContainer/index.scss +1 -51
  50. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  51. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  52. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  53. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  54. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
  55. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  56. package/v2Containers/Email/reducer.js +12 -3
  57. package/v2Containers/Email/sagas.js +9 -4
  58. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
  59. package/v2Containers/Email/tests/reducer.test.js +47 -0
  60. package/v2Containers/Email/tests/sagas.test.js +146 -6
  61. package/v2Containers/Rcs/constants.js +8 -119
  62. package/v2Containers/Rcs/index.js +811 -2383
  63. package/v2Containers/Rcs/index.scss +6 -276
  64. package/v2Containers/Rcs/messages.js +3 -38
  65. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70073 -98018
  66. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  67. package/v2Containers/Rcs/tests/index.test.js +121 -152
  68. package/v2Containers/Rcs/tests/mockData.js +0 -38
  69. package/v2Containers/Rcs/tests/utils.test.js +30 -646
  70. package/v2Containers/Rcs/utils.js +11 -478
  71. package/v2Containers/Sms/Create/index.js +40 -100
  72. package/v2Containers/SmsTrai/Create/index.js +4 -9
  73. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  74. package/v2Containers/SmsTrai/Edit/index.js +130 -636
  75. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  76. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
  77. package/v2Containers/SmsWrapper/index.js +8 -37
  78. package/v2Containers/TagList/index.js +0 -6
  79. package/v2Containers/Templates/_templates.scss +2 -163
  80. package/v2Containers/Templates/actions.js +0 -11
  81. package/v2Containers/Templates/constants.js +0 -2
  82. package/v2Containers/Templates/index.js +54 -119
  83. package/v2Containers/Templates/sagas.js +12 -57
  84. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
  85. package/v2Containers/Templates/tests/sagas.test.js +123 -193
  86. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  87. package/v2Containers/TemplatesV2/index.js +23 -86
  88. package/v2Containers/Whatsapp/index.js +20 -3
  89. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
  90. package/utils/rcsPayloadUtils.js +0 -92
  91. package/utils/templateVarUtils.js +0 -201
  92. package/utils/tests/templateVarUtils.test.js +0 -204
  93. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
  94. package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
  95. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
  96. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
  97. package/v2Components/SmsFallback/constants.js +0 -73
  98. package/v2Components/SmsFallback/index.js +0 -955
  99. package/v2Components/SmsFallback/index.scss +0 -265
  100. package/v2Components/SmsFallback/messages.js +0 -78
  101. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
  102. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
  103. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
  104. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
  105. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
  106. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
  107. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
  108. package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
  109. package/v2Components/TemplatePreview/constants.js +0 -2
  110. package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
  111. package/v2Components/VarSegmentMessageEditor/index.js +0 -125
  112. package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
  113. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
  114. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
  115. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
  116. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
  117. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
  118. package/v2Containers/Rcs/index.js.rej +0 -1336
  119. package/v2Containers/Rcs/index.scss.rej +0 -74
  120. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  121. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
  122. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  123. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  124. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  125. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  126. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  127. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  128. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  129. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  130. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -173,35 +173,19 @@ describe('Test SlideBoxContent container', () => {
173
173
  expect(getCreativesData).toHaveBeenCalledWith({ channel: 'RCS' });
174
174
  });
175
175
 
176
- it('RCS getFormData mirrors smsFallBackContent onto templateData for library round-trip', async () => {
177
- renderedComponent = shallowWithIntl(
178
- <Creatives
179
- loyaltyMetaData={loyaltyMetaData}
180
- Templates={rcsTemplates}
181
- channel="RCS"
182
- slidBoxContent="editTemplate"
183
- templateData={rcsEditTemplateData}
184
- handleCloseCreatives={handleCloseCreatives}
185
- getCreativesData={getCreativesData}
186
- isFullMode={false}
187
- templateActions={{
188
- getCdnTransformationConfig,
189
- }}
190
- />,
191
- );
176
+ it('RCS getFormData does not attach smsFallBackContent to templateData', async () => {
177
+ renderFunction('RCS', 'editTemplate', rcsTemplates, rcsEditTemplateData);
192
178
  renderedComponent.instance().onEditTemplate();
193
179
 
194
180
  const mockValue = {
195
- validity: true,
196
181
  value: {
197
182
  name: 'rcs_creative_name',
198
- type: 'RCS',
199
183
  versions: {
200
184
  base: {
201
185
  content: {
202
186
  RCS: {
203
187
  rcsContent: { contentType: 'RICHCARD', cardType: 'STANDALONE', cardSettings: {}, cardContent: [{}] },
204
- smsFallBackContent: { message: 'fallback-body' },
188
+ smsFallBackContent: { message: 'should-not-be-copied' },
205
189
  },
206
190
  },
207
191
  },
@@ -209,62 +193,16 @@ describe('Test SlideBoxContent container', () => {
209
193
  },
210
194
  };
211
195
 
212
- // Call getFormData on the container instance — shallow CapSlideBox `content` shape can differ across wrappers
213
- renderedComponent.instance().getFormData(mockValue);
196
+ renderedComponent
197
+ .find('CapSlideBox')
198
+ .props()
199
+ .content.props.getFormData(mockValue);
214
200
  await tick();
215
201
 
216
202
  const instance = renderedComponent.instance();
217
203
  expect(instance.state.templateData).toBeDefined();
218
- expect(instance.state.templateData.smsFallBackContent).toEqual({ message: 'fallback-body' });
219
- });
220
-
221
- it('RCS getFormData mirrors rcsCardVarMapped onto templateData for campaign reopen', async () => {
222
- renderedComponent = shallowWithIntl(
223
- <Creatives
224
- loyaltyMetaData={loyaltyMetaData}
225
- Templates={rcsTemplates}
226
- channel="RCS"
227
- slidBoxContent="editTemplate"
228
- templateData={rcsEditTemplateData}
229
- handleCloseCreatives={handleCloseCreatives}
230
- getCreativesData={getCreativesData}
231
- isFullMode={false}
232
- templateActions={{
233
- getCdnTransformationConfig,
234
- }}
235
- />,
236
- );
237
- renderedComponent.instance().onEditTemplate();
238
-
239
- const cardVarMapped = { 1: '[Name]', user_name: '[Name]' };
240
- const mockValue = {
241
- validity: true,
242
- value: {
243
- name: 'rcs_creative_name',
244
- type: 'RCS',
245
- versions: {
246
- base: {
247
- content: {
248
- RCS: {
249
- rcsContent: {
250
- contentType: 'RICHCARD',
251
- cardType: 'STANDALONE',
252
- cardSettings: {},
253
- cardContent: [{ title: 'Hi {{user_name}}', cardVarMapped }],
254
- },
255
- smsFallBackContent: {},
256
- },
257
- },
258
- },
259
- },
260
- },
261
- };
262
-
263
- renderedComponent.instance().getFormData(mockValue);
264
- await tick();
265
-
266
- const instance = renderedComponent.instance();
267
- expect(instance.state.templateData.rcsCardVarMapped).toEqual(cardVarMapped);
204
+ // sms fallback content should not be set on templateData per current logic
205
+ expect(instance.state.templateData.smsFallBackContent).toBeUndefined();
268
206
  });
269
207
 
270
208
  it('Text getCreatives data for rcs, data from creatives done to campaigns', async () => {
@@ -12,6 +12,8 @@ const initialState = fromJS({
12
12
  createTemplateInProgress: false,
13
13
  createResponse: {},
14
14
  isBeeEnabled: null,
15
+ fetchingCmsAccounts: false,
16
+ cmsAccountsLoaded: false,
15
17
  });
16
18
 
17
19
  function emailReducer(state = initialState, action) {
@@ -85,6 +87,7 @@ function emailReducer(state = initialState, action) {
85
87
  case types.GET_CMS_EDITOR_DETAILS_SUCCESS:
86
88
  return state
87
89
  .set('fetchingCmsSettings', false)
90
+ .set('isBeeEnabled', action.isBeeEnabled)
88
91
  .set('CmsSettings', fromJS(action.settings));
89
92
  case types.GET_CMS_EDITOR_DETAILS_FAILURE:
90
93
  return state
@@ -110,13 +113,19 @@ function emailReducer(state = initialState, action) {
110
113
  .set('fetchingCmsDataFailed', true);
111
114
  case types.GET_CMS_ACCOUNTS_REQUEST:
112
115
  return state
113
- .set('isBeeEnabled', false); // default to false
116
+ .set('isBeeEnabled', false)
117
+ .set('fetchingCmsAccounts', true)
118
+ .set('cmsAccountsLoaded', false);
114
119
  case types.GET_CMS_ACCOUNTS_SUCCESS:
115
120
  return state
116
- .set('isBeeEnabled', action.isBeeEnabled);
121
+ .set('isBeeEnabled', action.isBeeEnabled)
122
+ .set('fetchingCmsAccounts', false)
123
+ .set('cmsAccountsLoaded', true);
117
124
  case types.GET_CMS_ACCOUNTS_FAILURE:
118
125
  return state
119
- .set('isBeeEnabled', false);
126
+ .set('isBeeEnabled', false)
127
+ .set('fetchingCmsAccounts', false)
128
+ .set('cmsAccountsLoaded', true);
120
129
  case types.CLEAR_EMAIL_CRUD_RESPONSE_REQUEST:
121
130
  return state
122
131
  .set('createResponse', fromJS({}));
@@ -1,5 +1,5 @@
1
1
  import {
2
- call, put, takeLatest, takeEvery, all,
2
+ call, put, takeLatest, takeEvery, all, select, take,
3
3
  } from 'redux-saga/effects';
4
4
  import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
5
5
  import * as Api from '../../services/api';
@@ -103,14 +103,19 @@ export function* getAllAssets(assetType, queryParams) {
103
103
  }
104
104
 
105
105
  export function* getCmsSetting({
106
- cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable,
106
+ cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable: isBEEAppEnableFromAction,
107
107
  }) {
108
108
  try {
109
+ const emailState = yield select((state) => state.get('email'));
110
+ if (!emailState.get('cmsAccountsLoaded') && emailState.get('fetchingCmsAccounts')) {
111
+ yield take([types.GET_CMS_ACCOUNTS_SUCCESS, types.GET_CMS_ACCOUNTS_FAILURE]);
112
+ }
113
+ const updatedState = yield select((state) => state.get('email'));
114
+ const isBEEAppEnable = updatedState.get('isBeeEnabled') ?? isBEEAppEnableFromAction;
109
115
  const result = yield call(Api.getCmsTemplateSettingsV2, cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable);
110
116
  const cmsAccountDetail = result.data?.response.cmsDetails || {};
111
117
  const isBeeEnabled = cmsAccountDetail?.type === cmsType;
112
- yield put({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled });
113
- yield put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: result.data.response.cmsDetails });
118
+ yield put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: cmsAccountDetail, isBeeEnabled });
114
119
  } catch (error) {
115
120
  yield put({ type: types.GET_CMS_EDITOR_DETAILS_FAILURE, error });
116
121
  }
@@ -5,6 +5,8 @@ Immutable.Map {
5
5
  "createTemplateInProgress": false,
6
6
  "createResponse": Immutable.Map {},
7
7
  "isBeeEnabled": null,
8
+ "fetchingCmsAccounts": false,
9
+ "cmsAccountsLoaded": false,
8
10
  }
9
11
  `;
10
12
 
@@ -13,5 +15,7 @@ Immutable.Map {
13
15
  "createTemplateInProgress": true,
14
16
  "createResponse": Immutable.Map {},
15
17
  "isBeeEnabled": null,
18
+ "fetchingCmsAccounts": false,
19
+ "cmsAccountsLoaded": false,
16
20
  }
17
21
  `;
@@ -16,6 +16,53 @@ describe('emailReducer', () => {
16
16
  expect(emailReducer(undefined, action)).toMatchSnapshot();
17
17
  });
18
18
 
19
+ it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets isBeeEnabled true and CmsSettings', () => {
20
+ const initialState = fromJS({ isBeeEnabled: null, fetchingCmsSettings: true });
21
+ const action = {
22
+ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
23
+ isBeeEnabled: true,
24
+ settings: { isDragDrop: true, editorType: 'bee' },
25
+ };
26
+ const result = emailReducer(initialState, action);
27
+ expect(result.get('fetchingCmsSettings')).toBe(false);
28
+ expect(result.get('isBeeEnabled')).toBe(true);
29
+ expect(result.getIn(['CmsSettings', 'isDragDrop'])).toBe(true);
30
+ });
31
+
32
+ it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets isBeeEnabled false', () => {
33
+ const initialState = fromJS({ isBeeEnabled: true, fetchingCmsSettings: true });
34
+ const action = {
35
+ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
36
+ isBeeEnabled: false,
37
+ settings: {},
38
+ };
39
+ const result = emailReducer(initialState, action);
40
+ expect(result.get('fetchingCmsSettings')).toBe(false);
41
+ expect(result.get('isBeeEnabled')).toBe(false);
42
+ });
43
+
44
+ it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — overwrites stale isBeeEnabled from CLEAR_ALL_VALUES (null)', () => {
45
+ const initialState = fromJS({ isBeeEnabled: null, fetchingCmsSettings: true });
46
+ const action = {
47
+ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
48
+ isBeeEnabled: true,
49
+ settings: { type: 'bee' },
50
+ };
51
+ const result = emailReducer(initialState, action);
52
+ expect(result.get('isBeeEnabled')).toBe(true);
53
+ });
54
+
55
+ it.concurrent('it handles GET_CMS_EDITOR_DETAILS_SUCCESS action — sets CmsSettings to empty object when settings is {}', () => {
56
+ const initialState = fromJS({ CmsSettings: { old: 'data' } });
57
+ const action = {
58
+ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS,
59
+ isBeeEnabled: false,
60
+ settings: {},
61
+ };
62
+ const result = emailReducer(initialState, action);
63
+ expect(result.get('CmsSettings').toJS()).toEqual({});
64
+ });
65
+
19
66
  it.concurrent('it handles GET_CMS_ACCOUNTS_REQUEST action (line 111-113)', () => {
20
67
  const initialState = fromJS({
21
68
  isBeeEnabled: true, // Start with true to verify it gets set to false
@@ -3,6 +3,7 @@ import { expectSaga } from 'redux-saga-test-plan';
3
3
  import { takeLatest } from 'redux-saga/effects';
4
4
  import * as matchers from 'redux-saga-test-plan/matchers';
5
5
  import { throwError } from 'redux-saga-test-plan/providers';
6
+ import { fromJS } from 'immutable';
6
7
  import * as types from '../constants';
7
8
  import * as sagas from '../sagas';
8
9
  import { v2EmailDuplicateTemplateSaga, v2EmailSagas } from '../sagas';
@@ -709,10 +710,14 @@ describe('getCmsSetting saga', () => {
709
710
 
710
711
  return expectSaga(sagas.getCmsSetting, basePayload)
711
712
  .provide([
713
+ {
714
+ select(effect, next) {
715
+ return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: true });
716
+ },
717
+ },
712
718
  [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
713
719
  ])
714
- .put({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled: true })
715
- .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails })
720
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails, isBeeEnabled: true })
716
721
  .run();
717
722
  });
718
723
 
@@ -727,10 +732,14 @@ describe('getCmsSetting saga', () => {
727
732
 
728
733
  return expectSaga(sagas.getCmsSetting, basePayload)
729
734
  .provide([
735
+ {
736
+ select(effect, next) {
737
+ return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: false });
738
+ },
739
+ },
730
740
  [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
731
741
  ])
732
- .put({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled: false })
733
- .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails })
742
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: fakeResponse.data.response.cmsDetails, isBeeEnabled: false })
734
743
  .run();
735
744
  });
736
745
 
@@ -743,10 +752,14 @@ describe('getCmsSetting saga', () => {
743
752
 
744
753
  return expectSaga(sagas.getCmsSetting, basePayload)
745
754
  .provide([
755
+ {
756
+ select(effect, next) {
757
+ return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: false });
758
+ },
759
+ },
746
760
  [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
747
761
  ])
748
- .put({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled: false })
749
- .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: undefined })
762
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: {}, isBeeEnabled: false })
750
763
  .run();
751
764
  });
752
765
 
@@ -755,11 +768,138 @@ describe('getCmsSetting saga', () => {
755
768
 
756
769
  return expectSaga(sagas.getCmsSetting, basePayload)
757
770
  .provide([
771
+ {
772
+ select(effect, next) {
773
+ return fromJS({ cmsAccountsLoaded: true, isBeeEnabled: true });
774
+ },
775
+ },
758
776
  [matchers.call.fn(Api.getCmsTemplateSettingsV2), throwError(fakeError)],
759
777
  ])
760
778
  .put({ type: types.GET_CMS_EDITOR_DETAILS_FAILURE, error: fakeError })
761
779
  .run();
762
780
  });
781
+
782
+ it('should wait for accounts when fetchingCmsAccounts is true and cmsAccountsLoaded is false (accounts succeed)', () => {
783
+ const fakeResponse = {
784
+ data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
785
+ };
786
+ let selectCallCount = 0;
787
+
788
+ return expectSaga(sagas.getCmsSetting, basePayload)
789
+ .provide([
790
+ {
791
+ select(effect, next) {
792
+ selectCallCount += 1;
793
+ if (selectCallCount === 1) {
794
+ return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: true, isBeeEnabled: null });
795
+ }
796
+ return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: true });
797
+ },
798
+ },
799
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
800
+ ])
801
+ .dispatch({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled: true })
802
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
803
+ .run();
804
+ });
805
+
806
+ it('should wait for accounts when fetchingCmsAccounts is true and cmsAccountsLoaded is false (accounts fail)', () => {
807
+ const fakeResponse = {
808
+ data: { response: { cmsDetails: { type: 'ck', settings: {} } } },
809
+ };
810
+ let selectCallCount = 0;
811
+
812
+ return expectSaga(sagas.getCmsSetting, basePayload)
813
+ .provide([
814
+ {
815
+ select(effect, next) {
816
+ selectCallCount += 1;
817
+ if (selectCallCount === 1) {
818
+ return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: true, isBeeEnabled: null });
819
+ }
820
+ return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: false });
821
+ },
822
+ },
823
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
824
+ ])
825
+ .dispatch({ type: types.GET_CMS_ACCOUNTS_FAILURE })
826
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'ck', settings: {} }, isBeeEnabled: false })
827
+ .run();
828
+ });
829
+
830
+ it('should skip wait and use isBEEAppEnableFromAction as fallback when cmsAccountsLoaded is false but fetchingCmsAccounts is false', () => {
831
+ const fakeResponse = {
832
+ data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
833
+ };
834
+
835
+ return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
836
+ .provide([
837
+ {
838
+ select(effect, next) {
839
+ return fromJS({ cmsAccountsLoaded: false, fetchingCmsAccounts: false, isBeeEnabled: null });
840
+ },
841
+ },
842
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
843
+ ])
844
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
845
+ .run();
846
+ });
847
+
848
+ it('should use state isBeeEnabled (null) and fall back to isBEEAppEnableFromAction via ?? operator', () => {
849
+ const fakeResponse = {
850
+ data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
851
+ };
852
+
853
+ return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
854
+ .provide([
855
+ {
856
+ select(effect, next) {
857
+ return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: null });
858
+ },
859
+ },
860
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
861
+ ])
862
+ .call(Api.getCmsTemplateSettingsV2, basePayload.cmsType, basePayload.projectId, basePayload.cmsMode, basePayload.langId, basePayload.isEdmSupport, true)
863
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
864
+ .run();
865
+ });
866
+
867
+ it('should use state isBeeEnabled false over isBEEAppEnableFromAction true via ?? operator (false is not null/undefined)', () => {
868
+ const fakeResponse = {
869
+ data: { response: { cmsDetails: { type: 'bee', settings: {} } } },
870
+ };
871
+
872
+ return expectSaga(sagas.getCmsSetting, { ...basePayload, isBEEAppEnable: true })
873
+ .provide([
874
+ {
875
+ select(effect, next) {
876
+ return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: false });
877
+ },
878
+ },
879
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
880
+ ])
881
+ .call(Api.getCmsTemplateSettingsV2, basePayload.cmsType, basePayload.projectId, basePayload.cmsMode, basePayload.langId, basePayload.isEdmSupport, false)
882
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { type: 'bee', settings: {} }, isBeeEnabled: true })
883
+ .run();
884
+ });
885
+
886
+ it('should derive isBeeEnabled false when cmsDetails type is undefined', () => {
887
+ const fakeResponse = {
888
+ data: { response: { cmsDetails: { settings: {} } } },
889
+ };
890
+
891
+ return expectSaga(sagas.getCmsSetting, basePayload)
892
+ .provide([
893
+ {
894
+ select(effect, next) {
895
+ return fromJS({ cmsAccountsLoaded: true, fetchingCmsAccounts: false, isBeeEnabled: true });
896
+ },
897
+ },
898
+ [matchers.call.fn(Api.getCmsTemplateSettingsV2), fakeResponse],
899
+ ])
900
+ .put({ type: types.GET_CMS_EDITOR_DETAILS_SUCCESS, settings: { settings: {} }, isBeeEnabled: false })
901
+ .run();
902
+ });
763
903
  });
764
904
 
765
905
 
@@ -34,32 +34,18 @@ export const RCS_STATUSES = {
34
34
  awaitingApproval: 'awaitingApproval',
35
35
  };
36
36
 
37
- export const HOST_ICS="rcsicsbulk";
38
- export const HOST_INFOBIP="rcsinfobipbulk";
39
-
40
37
  export const contentType = {
41
38
  text_message: 'text_message',
42
39
  rich_card: 'rich_card',
43
40
  carousel: 'carousel',
44
41
  };
45
42
 
46
- export const CHANNELS = [
47
- 'email',
48
- 'mPush',
49
- 'viber',
50
- 'whatsapp',
51
- 'zalo',
52
- 'facebook',
53
- 'rcs',
54
- 'inApp',
55
- 'line',
56
- 'weChat',
57
- 'callTask',
58
- 'FTP',
59
- 'webpush',
60
- ];
61
-
62
43
  export const STATUS_OPTIONS = [
44
+ // {
45
+ // key: 'created',
46
+ // value: RCS_STATUSES.awaitingApproval,
47
+ // label: <FormattedMessage {...messages.created} />,
48
+ // },
63
49
  {
64
50
  key: 'approved',
65
51
  value: RCS_STATUSES.approved,
@@ -88,31 +74,10 @@ export const RCS_MEDIA_TYPES = {
88
74
  VIDEO: 'VIDEO',
89
75
  };
90
76
 
91
- /** Match `{{}}` placeholders including Liquid-style names (e.g. `tag.FORMAT_1`). Must align with split + `isAnyTemplateVarToken` / SMS fallback. */
92
- export const rcsVarRegex = /\{\{[^}]+\}\}/g;
93
- /** True when the whole string is a single RCS/mustache token (used when testing segment tokens). */
94
- export const rcsVarTestRegex = /^\{\{[^}]+\}\}$/;
95
-
96
- /** Matches all `{{N}}` numeric-index variable tokens in a template string (global). */
97
- export const RCS_NUMERIC_VAR_TOKEN_REGEX = /\{\{(\d+)\}\}/g;
98
- /** `cardVarMapped` slot keys that are numeric only (legacy ordering). */
99
- export const RCS_NUMERIC_VAR_NAME_REGEX = /^\d+$/;
100
- /** Semantic Liquid-style keys on RCS `cardVarMapped` (same class as `{{…}}` inner names in the editor). */
101
- export const RCS_CARD_VAR_MAPPED_SEMANTIC_KEY_REGEX = /^[\w.]+$/;
102
- /** Escape `RegExp` metacharacters when building a pattern from user/tag text. */
103
- export const RCS_REGEX_META_CHARS_PATTERN = /[.*+?^${}()|[\]\\]/g;
104
- /** Entire string is a single `{{tag}}` token (value still a placeholder). */
105
- export const RCS_SINGLE_MUSTACHE_PLACEHOLDER_REGEX = /^\{\{[^}]+\}\}$/;
106
- /** Strip leading `{{` and trailing `}}` from a token. */
107
- export const RCS_STRIP_MUSTACHE_DELIMITERS_REGEX = /^\{\{|\}\}$/g;
108
-
109
- /** Tag-popover target: title vs description field (matches `onTagSelect` `field` argument). */
110
- export const RCS_TAG_AREA_FIELD_TITLE = 'title';
111
- export const RCS_TAG_AREA_FIELD_DESC = 'desc';
112
-
77
+ export const rcsVarRegex = /\{\{\w+\}\}/g;
78
+ export const rcsVarTestRegex = /\{\{\w+\}\}/;
113
79
  export const TEMPLATE_DESC_MAX_LENGTH = 2500;
114
- /** Resolved SMS fallback body cap. Must allow multi-segment DLT (>160); aligns with TRAI / `TEMPLATE_MESSAGE_MAX_LENGTH`. */
115
- export const FALLBACK_MESSAGE_MAX_LENGTH = TEMPLATE_MESSAGE_MAX_LENGTH;
80
+ export const FALLBACK_MESSAGE_MAX_LENGTH = 160;
116
81
  export const TEMPLATE_TITLE_MAX_LENGTH = 200;
117
82
  export const TEMPLATE_BUTTON_TEXT_MAX_LENGTH = 25;
118
83
  export const CTA = 'CTA';
@@ -127,12 +92,10 @@ export const ALLOWED_IMAGE_EXTENSIONS_REGEX = (/\.(png|jpg|jpeg|gif)$/i);
127
92
  export const RCS_IMG_WIDTH = 1440;
128
93
  export const RCS_IMG_HEIGHT = 1024;
129
94
  export const RCS_IMG_SIZE = 2000000; // 2MB
130
- export const RCS_CAROUSEL_IMG_SIZE = 1 * 1024 * 1024; // 1MB
131
95
  export const MAX_FILE_SIZE_MB = 10;
132
96
  export const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
133
97
  export const ALLOWED_EXTENSIONS_VIDEO_REGEX = (/\.(mp4)$/i);
134
98
  export const RCS_VIDEO_SIZE = 10 * 1024 * 1024;
135
- export const RCS_CAROUSEL_VIDEO_SIZE = 5 * 1024 * 1024; // 5MB
136
99
  export const RCS_THUMBNAIL_MIN_SIZE = 40 * 1024;
137
100
  export const RCS_THUMBNAIL_MAX_SIZE = 100 * 1024;
138
101
 
@@ -179,31 +142,6 @@ export const RCS_IMAGE_DIMENSIONS = {
179
142
  },
180
143
  };
181
144
 
182
- // Carousel image dimensions (pixel values shown in UI). Keys follow `${HEIGHT}_${WIDTH}`.
183
- // HEIGHT: SHORT|MEDIUM, WIDTH: SMALL|MEDIUM
184
- export const RCS_CAROUSEL_IMAGE_DIMENSIONS = {
185
- SHORT_SMALL: {
186
- width: 1160,
187
- height: 720,
188
- description: 'Image (1160 x 720)',
189
- },
190
- SHORT_MEDIUM: {
191
- width: 1800,
192
- height: 720,
193
- description: 'Image (1800 x 720)',
194
- },
195
- MEDIUM_SMALL: {
196
- width: 770,
197
- height: 720,
198
- description: 'Image (770 x 720)',
199
- },
200
- MEDIUM_MEDIUM: {
201
- width: 1280,
202
- height: 720,
203
- description: 'Image (1280 x 720)',
204
- },
205
- };
206
-
207
145
  export const RCS_VIDEO_THUMBNAIL_DIMENSIONS = {
208
146
  SHORT_HEIGHT: {
209
147
  width: 770,
@@ -211,8 +149,6 @@ export const RCS_VIDEO_THUMBNAIL_DIMENSIONS = {
211
149
  type: 'SHORT_HEIGHT',
212
150
  heightType: 'SHORT',
213
151
  label: 'Vertical Short',
214
- width: 1140,
215
- height: 448,
216
152
  description: 'Thumbnail (770 x 257)',
217
153
  orientation: 'VERTICAL',
218
154
  maxFileSize: 100 * 1024,
@@ -253,29 +189,6 @@ export const RCS_VIDEO_THUMBNAIL_DIMENSIONS = {
253
189
  },
254
190
  };
255
191
 
256
- // Carousel thumbnail dimensions for video cards (pixel values shown in UI).
257
- // Keys follow `${HEIGHT}_${WIDTH}`.
258
- // Human-readable labels: formatMessage(messages.rcsCarouselVideoThumbnailLabel, { width, height })
259
- // or formatRcsCarouselVideoThumbnailLabel(formatMessage, entry) from ./utils.
260
- export const RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS = {
261
- SHORT_SMALL: {
262
- width: 718,
263
- height: 448,
264
- },
265
- SHORT_MEDIUM: {
266
- width: 1140,
267
- height: 448,
268
- },
269
- MEDIUM_SMALL: {
270
- width: 480,
271
- height: 448,
272
- },
273
- MEDIUM_MEDIUM: {
274
- width: 796,
275
- height: 448,
276
- },
277
- };
278
-
279
192
  const prefix = 'app/v2Containers/Rcs';
280
193
  export const UPLOAD_RCS_ASSET_REQUEST = `${prefix}/UPLOAD_RCS_ASSET_REQUEST`;
281
194
  export const UPLOAD_RCS_ASSET_SUCCESS = `${prefix}/UPLOAD_RCS_ASSET_SUCCESS`;
@@ -302,7 +215,6 @@ export const CLEAR_EDIT_RESPONSE_REQUEST = `${prefix}/Edit/CLEAR_EDIT_RESPONSE_R
302
215
  export const AI_CONTENT_BOT_DISABLED = "AI_CONTENT_BOT_DISABLED";
303
216
 
304
217
  export const RCS_TEXT_MESSAGE_MAX_LENGTH = 160;
305
- export const RCS_TEXT_MESSAGE_MAX_LENGTH_INFOBIP = 3072;
306
218
  export const RCS_RICH_CARD_MAX_LENGTH = 2000;
307
219
  export const MAX_BUTTONS = 4;
308
220
 
@@ -338,26 +250,3 @@ export const RCS_BUTTON_TYPES = {
338
250
  PHONE_NUMBER: 'PHONE_NUMBER',
339
251
  CTA: 'CTA',
340
252
  };
341
-
342
- /** Default action row for carousel card 1 (mandatory button UX): phone CTA, unsaved until user completes + Save. */
343
- export const RCS_CAROUSEL_FIRST_CARD_DEFAULT_SUGGESTIONS = [
344
- {
345
- index: 0,
346
- type: RCS_BUTTON_TYPES.PHONE_NUMBER,
347
- text: '',
348
- phoneNumber: '',
349
- url: null,
350
- postback: '',
351
- isSaved: false,
352
- },
353
- ];
354
-
355
-
356
- export const CAROUSEL_HEIGHT_OPTIONS = [
357
- { value: 'SHORT', label: 'Short' },
358
- { value: 'MEDIUM', label: 'Medium' },
359
- ];
360
- export const CAROUSEL_WIDTH_OPTIONS = [
361
- { value: 'SMALL', label: 'Small' },
362
- { value: 'MEDIUM', label: 'Medium' },
363
- ];