@capillarytech/creatives-library 9.0.15-alpha.1 → 9.0.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.
- package/constants/unified.js +0 -29
- package/global-styles.js +1 -1
- package/package.json +1 -1
- package/services/tests/api.test.js +20 -35
- package/utils/commonUtils.js +1 -19
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +109 -168
- package/v2Components/CapActionButton/index.scss +5 -156
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +18 -42
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +48 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -214
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +9 -83
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -60
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +23 -201
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -355
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +8 -155
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +222 -761
- package/v2Components/CommonTestAndPreview/messages.js +3 -45
- package/v2Components/CommonTestAndPreview/sagas.js +6 -25
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -1
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +267 -284
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -133
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +24 -31
- package/v2Components/TemplatePreview/_templatePreview.scss +22 -41
- package/v2Components/TemplatePreview/index.js +31 -143
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +1 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +0 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
- package/v2Containers/CreativesContainer/SlideBoxContent.js +7 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +5 -14
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +5 -36
- package/v2Containers/CreativesContainer/constants.js +0 -11
- package/v2Containers/CreativesContainer/index.js +104 -323
- package/v2Containers/CreativesContainer/index.scss +1 -83
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +90 -333
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Email/index.js +5 -2
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +11 -131
- package/v2Containers/Rcs/index.js +810 -2605
- package/v2Containers/Rcs/index.scss +8 -289
- package/v2Containers/Rcs/messages.js +3 -34
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +38537 -73535
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +8 -0
- package/v2Containers/Rcs/tests/index.test.js +36 -147
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -646
- package/v2Containers/Rcs/utils.js +11 -478
- package/v2Containers/Sms/Create/index.js +48 -115
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +169 -678
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2854 -5455
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +12 -171
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +55 -125
- package/v2Containers/Templates/sagas.js +13 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1015 -1060
- package/v2Containers/Templates/tests/sagas.test.js +16 -199
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/rcsPayloadUtils.test.js +0 -226
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/CommonTestAndPreview/utils.js +0 -84
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -91
- package/v2Components/SmsFallback/constants.js +0 -94
- package/v2Components/SmsFallback/index.js +0 -958
- package/v2Components/SmsFallback/index.scss +0 -266
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -120
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -208
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -309
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -17
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -227
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -126
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { expectSaga } from 'redux-saga-test-plan';
|
|
2
|
-
import {
|
|
3
|
-
take, call, takeLatest, takeEvery, put,
|
|
4
|
-
} from 'redux-saga/effects';
|
|
5
2
|
import * as matchers from 'redux-saga-test-plan/matchers';
|
|
6
3
|
import { throwError } from 'redux-saga-test-plan/providers';
|
|
4
|
+
import { call, takeLatest, put } from 'redux-saga/effects';
|
|
7
5
|
import * as api from '../../../services/api';
|
|
8
6
|
import * as types from '../constants';
|
|
9
7
|
import * as cdnUtils from '../../../utils/cdnTransformation';
|
|
10
8
|
import {
|
|
11
9
|
getCdnTransformationConfig,
|
|
12
10
|
getAllTemplates,
|
|
13
|
-
getLocalSmsTemplates,
|
|
14
11
|
watchGetCdnTransformationConfig,
|
|
15
12
|
watchGetAllTemplates,
|
|
16
13
|
getSenderDetails,
|
|
17
14
|
fetchWeCrmAccounts,
|
|
18
15
|
sendZippedFile,
|
|
19
16
|
fetchUserList,
|
|
17
|
+
watchGetUserList,
|
|
20
18
|
deleteRcsTemplate,
|
|
21
19
|
watchDeleteRcsTemplate,
|
|
22
20
|
watchForGetTemplateInfoById,
|
|
@@ -41,14 +39,10 @@ import {
|
|
|
41
39
|
watchUnarchiveTemplate,
|
|
42
40
|
watchBulkArchive,
|
|
43
41
|
watchBulkUnarchive,
|
|
44
|
-
watchGetUserList,
|
|
45
42
|
} from '../sagas';
|
|
46
|
-
|
|
47
|
-
import * as mockData from './mockData';
|
|
48
|
-
import { fetchSmsTemplatesFromQuery } from '../utils/smsTemplatesListApi';
|
|
49
|
-
import { ZALO } from '../../CreativesContainer/constants';
|
|
50
|
-
import { VIET_GUYS, ZALO_TEMPLATE_INFO_REQUEST } from '../../Zalo/constants';
|
|
51
43
|
import { getTemplateInfoById } from '../../Zalo/saga';
|
|
44
|
+
import { ZALO_TEMPLATE_INFO_REQUEST } from '../../Zalo/constants';
|
|
45
|
+
import * as mockData from './mockData';
|
|
52
46
|
|
|
53
47
|
jest.mock('@capillarytech/cap-ui-library', () => ({
|
|
54
48
|
CapNotification: {
|
|
@@ -173,8 +167,8 @@ describe('templateList saga', () => {
|
|
|
173
167
|
],
|
|
174
168
|
]).put({
|
|
175
169
|
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
176
|
-
data: mockData.getAllTemplatesListSuccess
|
|
177
|
-
weCRMTemplate: mockData.getAllTemplatesListSuccess
|
|
170
|
+
data: mockData.getAllTemplatesListSuccess,
|
|
171
|
+
weCRMTemplate: mockData.getAllTemplatesListSuccess,
|
|
178
172
|
isReset: mockData.getAllTemplatesListSuccess?.queryParams?.page === 1,
|
|
179
173
|
})
|
|
180
174
|
.run();
|
|
@@ -190,8 +184,8 @@ describe('templateList saga', () => {
|
|
|
190
184
|
],
|
|
191
185
|
]).put({
|
|
192
186
|
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
193
|
-
data: mockData.getAllTemplatesListSuccess
|
|
194
|
-
weCRMTemplate: mockData.getAllTemplatesListSuccess
|
|
187
|
+
data: mockData.getAllTemplatesListSuccess,
|
|
188
|
+
weCRMTemplate: mockData.getAllTemplatesListSuccess,
|
|
195
189
|
isReset: mockData.getAllTemplatesListSuccess?.queryParams?.page === 1,
|
|
196
190
|
})
|
|
197
191
|
.run();
|
|
@@ -210,163 +204,6 @@ describe('templateList saga', () => {
|
|
|
210
204
|
})
|
|
211
205
|
.run();
|
|
212
206
|
});
|
|
213
|
-
|
|
214
|
-
it('SMS channel uses fetchSmsTemplatesFromQuery', () => {
|
|
215
|
-
const smsAction = {
|
|
216
|
-
type: types.GET_ALL_TEMPLATES_REQUEST,
|
|
217
|
-
channel: 'Sms',
|
|
218
|
-
queryParams: { page: 1, perPage: 25, name: '', sortBy: 'Most Recent' },
|
|
219
|
-
intlCopyOf: 'Kopie',
|
|
220
|
-
};
|
|
221
|
-
const fetched = {
|
|
222
|
-
channelTemplates: { templates: [{ name: 'Kopie Foo' }], totalCount: 1 },
|
|
223
|
-
weCRMTemplate: undefined,
|
|
224
|
-
raw: {},
|
|
225
|
-
};
|
|
226
|
-
return expectSaga(getAllTemplates, smsAction)
|
|
227
|
-
.provide([
|
|
228
|
-
[call(fetchSmsTemplatesFromQuery, smsAction.queryParams, smsAction.intlCopyOf), fetched],
|
|
229
|
-
])
|
|
230
|
-
.put({
|
|
231
|
-
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
232
|
-
data: fetched.channelTemplates,
|
|
233
|
-
weCRMTemplate: fetched.weCRMTemplate,
|
|
234
|
-
isReset: true,
|
|
235
|
-
})
|
|
236
|
-
.run();
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('SMS channel propagates fetchSmsTemplatesFromQuery errors', () => {
|
|
240
|
-
const smsAction = {
|
|
241
|
-
type: types.GET_ALL_TEMPLATES_REQUEST,
|
|
242
|
-
channel: 'SMS',
|
|
243
|
-
queryParams: { page: 2, perPage: 25 },
|
|
244
|
-
intlCopyOf: '',
|
|
245
|
-
};
|
|
246
|
-
const error = new Error('sms list fail');
|
|
247
|
-
return expectSaga(getAllTemplates, smsAction)
|
|
248
|
-
.provide([
|
|
249
|
-
[call(fetchSmsTemplatesFromQuery, smsAction.queryParams, smsAction.intlCopyOf), throwError(error)],
|
|
250
|
-
])
|
|
251
|
-
.put({
|
|
252
|
-
type: types.GET_ALL_TEMPLATES_FAILURE,
|
|
253
|
-
error,
|
|
254
|
-
})
|
|
255
|
-
.run();
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('wechat channel merges mapped and richmedia and applies Most Recent sort', () => {
|
|
259
|
-
const wechatApiResponse = {
|
|
260
|
-
response: {
|
|
261
|
-
mapped: [
|
|
262
|
-
{ name: 'B', updatedAt: '2024-01-02T00:00:00Z' },
|
|
263
|
-
{ name: 'A', updatedAt: '2024-01-01T00:00:00Z' },
|
|
264
|
-
],
|
|
265
|
-
richmedia: [{ name: 'C', updatedAt: '2024-01-03T00:00:00Z' }],
|
|
266
|
-
unMapped: [],
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
const action = {
|
|
270
|
-
channel: 'wechat',
|
|
271
|
-
queryParams: { sortBy: 'Most Recent', page: 1 },
|
|
272
|
-
intlCopyOf: '',
|
|
273
|
-
};
|
|
274
|
-
return expectSaga(getAllTemplates, action)
|
|
275
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
276
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
277
|
-
.run();
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('wechat channel applies Alphabetically sort', () => {
|
|
281
|
-
const wechatApiResponse = {
|
|
282
|
-
response: {
|
|
283
|
-
mapped: [{ name: 'Zebra', updatedAt: '2024-01-02T00:00:00Z' }],
|
|
284
|
-
richmedia: [{ name: 'Apple', updatedAt: '2024-01-01T00:00:00Z' }],
|
|
285
|
-
unMapped: [],
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
const action = {
|
|
289
|
-
channel: 'wechat',
|
|
290
|
-
queryParams: { sortBy: 'Alphabetically', page: 1 },
|
|
291
|
-
intlCopyOf: '',
|
|
292
|
-
};
|
|
293
|
-
return expectSaga(getAllTemplates, action)
|
|
294
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
295
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
296
|
-
.run();
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('wechat channel replaces Copy-of prefix when intlCopyOf is set', () => {
|
|
300
|
-
const wechatApiResponse = {
|
|
301
|
-
response: {
|
|
302
|
-
mapped: [{ name: 'Copy of Promo', updatedAt: '2024-01-01T00:00:00Z' }],
|
|
303
|
-
richmedia: [],
|
|
304
|
-
unMapped: [],
|
|
305
|
-
},
|
|
306
|
-
};
|
|
307
|
-
const action = {
|
|
308
|
-
channel: 'wechat',
|
|
309
|
-
queryParams: { page: 1 },
|
|
310
|
-
intlCopyOf: 'Kopia av ',
|
|
311
|
-
};
|
|
312
|
-
return expectSaga(getAllTemplates, action)
|
|
313
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
314
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
315
|
-
.run();
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
describe('getLocalSmsTemplates saga', () => {
|
|
320
|
-
it('invokes onSuccess with fetched data', () => {
|
|
321
|
-
const onSuccess = jest.fn();
|
|
322
|
-
const action = {
|
|
323
|
-
queryParams: { page: 1 },
|
|
324
|
-
intlCopyOf: '',
|
|
325
|
-
onSuccess,
|
|
326
|
-
};
|
|
327
|
-
const fetched = { channelTemplates: { templates: [] }, raw: {} };
|
|
328
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
329
|
-
.provide([[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), fetched]])
|
|
330
|
-
.call(onSuccess, fetched)
|
|
331
|
-
.run();
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
it('invokes onFailure when fetch throws', () => {
|
|
335
|
-
const onFailure = jest.fn();
|
|
336
|
-
const error = new Error('local list fail');
|
|
337
|
-
const action = {
|
|
338
|
-
queryParams: { page: 1 },
|
|
339
|
-
intlCopyOf: 'Kopie',
|
|
340
|
-
onFailure,
|
|
341
|
-
};
|
|
342
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
343
|
-
.provide([
|
|
344
|
-
[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), throwError(error)],
|
|
345
|
-
])
|
|
346
|
-
.call(onFailure, error)
|
|
347
|
-
.run();
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it('does not throw when callbacks are omitted', () => {
|
|
351
|
-
const action = { queryParams: { page: 1 }, intlCopyOf: '' };
|
|
352
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
353
|
-
.provide([
|
|
354
|
-
[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), throwError(new Error('x'))],
|
|
355
|
-
])
|
|
356
|
-
.run();
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
it('does not call onSuccess when it is not a function', () => {
|
|
360
|
-
const action = {
|
|
361
|
-
queryParams: { page: 1 },
|
|
362
|
-
intlCopyOf: '',
|
|
363
|
-
onSuccess: 'not-a-fn',
|
|
364
|
-
};
|
|
365
|
-
const fetched = { channelTemplates: { templates: [] } };
|
|
366
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
367
|
-
.provide([[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), fetched]])
|
|
368
|
-
.run();
|
|
369
|
-
});
|
|
370
207
|
});
|
|
371
208
|
|
|
372
209
|
describe('watchForTemplates saga', () => {
|
|
@@ -560,7 +397,7 @@ describe('getSenderDetails Saga', () => {
|
|
|
560
397
|
|
|
561
398
|
describe('fetchWeCrmAccounts Saga', () => {
|
|
562
399
|
const action = { source: 'CRM' };
|
|
563
|
-
|
|
400
|
+
test.concurrent('handles successful fetching of WeCRM accounts', () => {
|
|
564
401
|
const fakeResponse = {
|
|
565
402
|
response: [{ id: 1, name: 'Account One' }]
|
|
566
403
|
};
|
|
@@ -573,11 +410,14 @@ describe('fetchWeCrmAccounts Saga', () => {
|
|
|
573
410
|
})
|
|
574
411
|
);
|
|
575
412
|
});
|
|
576
|
-
|
|
413
|
+
test.concurrent('handles error thrown from api', () => {
|
|
577
414
|
const error = new Error('Fetch failed');
|
|
578
|
-
expectSaga(fetchWeCrmAccounts, action)
|
|
415
|
+
expectSaga(fetchWeCrmAccounts, action.source)
|
|
579
416
|
.provide([
|
|
580
|
-
[
|
|
417
|
+
[
|
|
418
|
+
call(api.fetchWeCrmAccounts),
|
|
419
|
+
throwError(error)
|
|
420
|
+
],
|
|
581
421
|
])
|
|
582
422
|
.put({
|
|
583
423
|
type: types.GET_WECRM_ACCOUNTS_FAILURE,
|
|
@@ -619,29 +459,6 @@ describe('sendZippedFile Saga', () => {
|
|
|
619
459
|
expect(generator.next().value).toEqual(call(api.sendZippedFile, action.selectedFile));
|
|
620
460
|
});
|
|
621
461
|
|
|
622
|
-
it('calls errorHandler with message and returns early when isError is true', () => {
|
|
623
|
-
const errorHandler = jest.fn();
|
|
624
|
-
const successHandler = jest.fn();
|
|
625
|
-
const errorAction = {
|
|
626
|
-
selectedFile: 'upload.zip',
|
|
627
|
-
errorHandler,
|
|
628
|
-
successHandler,
|
|
629
|
-
};
|
|
630
|
-
const fakeErrorResponse = {
|
|
631
|
-
status: { isError: true },
|
|
632
|
-
message: 'Upload failed',
|
|
633
|
-
};
|
|
634
|
-
const generator = sendZippedFile(errorAction);
|
|
635
|
-
expect(generator.next().value).toEqual(call(api.sendZippedFile, errorAction.selectedFile));
|
|
636
|
-
// Advancing with isError response causes the saga to call errorHandler and yield
|
|
637
|
-
const yieldStep = generator.next(fakeErrorResponse);
|
|
638
|
-
expect(errorHandler).toHaveBeenCalledWith('Upload failed');
|
|
639
|
-
expect(yieldStep.done).toBe(false);
|
|
640
|
-
// After resuming from the yield, the return statement completes the generator
|
|
641
|
-
expect(generator.next().done).toBe(true);
|
|
642
|
-
expect(successHandler).not.toHaveBeenCalled();
|
|
643
|
-
});
|
|
644
|
-
|
|
645
462
|
it('handles error thrown from api', () => {
|
|
646
463
|
const error = new Error('Fetch failed');
|
|
647
464
|
expectSaga(sendZippedFile, action)
|
|
@@ -1407,7 +1224,7 @@ describe('v2TemplateSaga', () => {
|
|
|
1407
1224
|
// all() returns an IO object with an ALL key containing the array of effects
|
|
1408
1225
|
expect(step.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1409
1226
|
expect(step.value).toHaveProperty('ALL');
|
|
1410
|
-
expect(step.value.ALL).toHaveLength(
|
|
1227
|
+
expect(step.value.ALL).toHaveLength(14);
|
|
1411
1228
|
expect(step.done).toBe(false);
|
|
1412
1229
|
});
|
|
1413
1230
|
});
|
|
@@ -10,7 +10,7 @@ export default css`
|
|
|
10
10
|
|
|
11
11
|
.component-wrapper {
|
|
12
12
|
${(props) => props.isFullMode ? `
|
|
13
|
-
max-width:
|
|
13
|
+
max-width: 1140px;
|
|
14
14
|
margin: 0 auto;
|
|
15
15
|
width: 100%;
|
|
16
16
|
padding: 0.714rem 0;
|
|
@@ -23,77 +23,6 @@ export default css`
|
|
|
23
23
|
height: calc(100vh - 11.25rem);
|
|
24
24
|
} `}
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
/* SMS fallback / local list: single pane skips .cap-tab-v2, so flex-fill the grid instead of viewport-fixed pagination height */
|
|
28
|
-
.creatives-templates-container--local-sms.library-mode {
|
|
29
|
-
display: flex;
|
|
30
|
-
flex-direction: column;
|
|
31
|
-
flex: 1;
|
|
32
|
-
min-height: 0;
|
|
33
|
-
height: 100%;
|
|
34
|
-
|
|
35
|
-
.component-wrapper {
|
|
36
|
-
display: flex;
|
|
37
|
-
flex-direction: column;
|
|
38
|
-
flex: 1;
|
|
39
|
-
min-height: 0;
|
|
40
|
-
height: 100%;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.templates-v2-local-sms-pane {
|
|
44
|
-
display: flex;
|
|
45
|
-
flex-direction: column;
|
|
46
|
-
flex: 1;
|
|
47
|
-
min-height: 0;
|
|
48
|
-
overflow: hidden;
|
|
49
|
-
height: 100%;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.templates-v2-local-sms-pane .creatives-templates-list.library-mode {
|
|
53
|
-
display: flex;
|
|
54
|
-
flex-direction: column;
|
|
55
|
-
flex: 1;
|
|
56
|
-
min-height: 0;
|
|
57
|
-
overflow: hidden;
|
|
58
|
-
height: 100%;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.templates-v2-local-sms-pane .creatives-templates-list.library-mode > .cap-row:first-of-type {
|
|
62
|
-
flex: 1;
|
|
63
|
-
min-height: 0;
|
|
64
|
-
display: flex;
|
|
65
|
-
flex-direction: column;
|
|
66
|
-
overflow: hidden;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.templates-v2-local-sms-pane .creatives-templates-list.library-mode > .cap-row:first-of-type > div {
|
|
70
|
-
flex: 1;
|
|
71
|
-
min-height: 0;
|
|
72
|
-
display: flex;
|
|
73
|
-
flex-direction: column;
|
|
74
|
-
overflow: hidden;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.templates-v2-local-sms-pane .creatives-templates-list.library-mode > .cap-row:first-of-type > div > div:first-child {
|
|
78
|
-
flex: 1;
|
|
79
|
-
min-height: 0;
|
|
80
|
-
display: flex;
|
|
81
|
-
flex-direction: column;
|
|
82
|
-
overflow: hidden;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.templates-v2-local-sms-pane .v2-pagination-container,
|
|
86
|
-
.templates-v2-local-sms-pane .v2-pagination-container-half {
|
|
87
|
-
/* Match _templates local-SMS: bounded height so overflow-y scroll works (flex+100% alone often doesn’t) */
|
|
88
|
-
flex: 0 1 auto;
|
|
89
|
-
min-height: 0;
|
|
90
|
-
height: calc(100vh - 12rem);
|
|
91
|
-
max-height: calc(100vh - 12rem);
|
|
92
|
-
overflow-y: auto;
|
|
93
|
-
overflow-x: hidden;
|
|
94
|
-
-webkit-overflow-scrolling: touch;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
26
|
`;
|
|
98
27
|
|
|
99
28
|
export const CapTabStyle = css`
|
|
@@ -10,8 +10,8 @@ import { connect } from 'react-redux';
|
|
|
10
10
|
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
|
11
11
|
import { createStructuredSelector } from 'reselect';
|
|
12
12
|
import { bindActionCreators, compose } from 'redux';
|
|
13
|
-
import { CapTab, CapCustomCard, CapButton, CapHeader,
|
|
14
|
-
import { find, get
|
|
13
|
+
import { CapTab, CapCustomCard, CapButton, CapHeader, CapSpin, CapIcon, CapTooltip } from '@capillarytech/cap-ui-library';
|
|
14
|
+
import { find, get } from 'lodash';
|
|
15
15
|
import Helmet from 'react-helmet';
|
|
16
16
|
|
|
17
17
|
import { UserIsAuthenticated } from '../../utils/authWrapper';
|
|
@@ -41,14 +41,13 @@ import { makeSelectAuthenticated, selectCurrentOrgDetails } from "../../v2Contai
|
|
|
41
41
|
import {
|
|
42
42
|
CALL_TASK,
|
|
43
43
|
COMMON_CHANNELS,
|
|
44
|
-
LOCAL_TEMPLATE_CONFIG_KEYS_FOR_PICK,
|
|
45
44
|
LOYALTY_SUPPORTED_ACTION,
|
|
46
45
|
MOBILE_PUSH,
|
|
47
46
|
NORMALIZED_CHANNEL_ALIASES,
|
|
48
47
|
SMS,
|
|
49
48
|
} from "../CreativesContainer/constants";
|
|
50
49
|
|
|
51
|
-
const {
|
|
50
|
+
const {CapCustomCardList} = CapCustomCard;
|
|
52
51
|
|
|
53
52
|
const StyledCapTab = withStyles(CapTab, CapTabStyle);
|
|
54
53
|
export class TemplatesV2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
@@ -125,9 +124,9 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
125
124
|
return !normalizedChannelsToHideSet.has(paneKey);
|
|
126
125
|
});
|
|
127
126
|
|
|
128
|
-
if (isFullMode
|
|
129
|
-
filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.gallery), key:
|
|
130
|
-
} else
|
|
127
|
+
if (isFullMode) {
|
|
128
|
+
filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.gallery), key: 'assets' });
|
|
129
|
+
} else {
|
|
131
130
|
// Add special-mode panes only when not hidden (use normalized checks)
|
|
132
131
|
if (!normalizedChannelsToHideSet.has(CALL_TASK.toLowerCase())) {
|
|
133
132
|
filteredPanes.push({ content: <div></div>, tab: intl.formatMessage(messages.callTask), key: CALL_TASK.toLowerCase() });
|
|
@@ -228,8 +227,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
228
227
|
this.setState({selectedChannel: nextProps.channel, panes });
|
|
229
228
|
}
|
|
230
229
|
}
|
|
231
|
-
|
|
232
|
-
getTemplateDataForGrid = ({ templates, handlers, filterContent, channel, isLoading, loadingTip }) => {
|
|
230
|
+
getTemplateDataForGrid = ({templates, handlers, filterContent, channel, isLoading, loadingTip}) => {
|
|
233
231
|
const currentChannel = channel.toUpperCase();
|
|
234
232
|
const cardDataList = templates.map((template) => {
|
|
235
233
|
const templateData =
|
|
@@ -255,8 +253,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
255
253
|
</CapSpin>
|
|
256
254
|
|
|
257
255
|
</div>);
|
|
258
|
-
}
|
|
259
|
-
|
|
256
|
+
}
|
|
260
257
|
getGalleryComponent = (location) => <Gallery location={location} isFullMode={this.props.isFullMode}/>
|
|
261
258
|
getCallTaskComponent = () => (
|
|
262
259
|
<CallTask
|
|
@@ -320,29 +317,6 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
320
317
|
if (messageStrategy !== "X_ENGAGE" && channel === 'facebook' && !isFullMode) {
|
|
321
318
|
return this.getFacebookComponent();
|
|
322
319
|
}
|
|
323
|
-
const localConfig = this.props.localTemplatesConfig || pick(this.props, LOCAL_TEMPLATE_CONFIG_KEYS_FOR_PICK);
|
|
324
|
-
const useLocalTemplates = localConfig.useLocalTemplates;
|
|
325
|
-
if (useLocalTemplates && channel === (this.props.channel || 'sms')) {
|
|
326
|
-
// Reuse full Templates component (same UI as Redux flow) with local data only
|
|
327
|
-
const location = { pathname: `/${channel}`, search: '', query: !this.props.isFullMode ? { type: 'embedded', module: 'library' } : {} };
|
|
328
|
-
return (
|
|
329
|
-
<Templates
|
|
330
|
-
key={`${channel}-local`}
|
|
331
|
-
location={location}
|
|
332
|
-
route={{ name: channel }}
|
|
333
|
-
router={this.props.router}
|
|
334
|
-
isFullMode={this.props.isFullMode}
|
|
335
|
-
createNew={this.props.createNew}
|
|
336
|
-
onSelectTemplate={this.props.onSelectTemplate}
|
|
337
|
-
handlePeviewTemplate={this.props.handlePeviewTemplate}
|
|
338
|
-
messageStrategy={this.props.messageStrategy}
|
|
339
|
-
smsRegister={this.props.smsRegister}
|
|
340
|
-
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
341
|
-
localTemplatesConfig={localConfig}
|
|
342
|
-
/>
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
320
|
const location = {pathname: `/${channel}`, search: '', query};
|
|
347
321
|
switch (channel) {
|
|
348
322
|
case 'call_task':
|
|
@@ -392,55 +366,29 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
392
366
|
}
|
|
393
367
|
render() {
|
|
394
368
|
const { isFullMode, className, cap = {}, Global = {}} = this.props;
|
|
395
|
-
const useLocalTemplates = get(this.props, 'localTemplatesConfig.useLocalTemplates', false);
|
|
396
369
|
const { accessiblePermissions = []} = cap.user || Global.user || {};
|
|
397
370
|
let isCreativeAccessible = true;
|
|
398
371
|
if (!accessiblePermissions.includes(CREATIVES_UI_VIEW)) {
|
|
399
372
|
isCreativeAccessible = false;
|
|
400
373
|
}
|
|
401
|
-
// Recompute active pane content every render so local-list mode updates
|
|
402
|
-
// (templates/loading/search UI) are not stuck with the initial cached pane.
|
|
403
|
-
const panes = this.setChannelContent(this.state.selectedChannel, this.state.panes);
|
|
404
|
-
const hideChannelTabsForLocalSms = useLocalTemplates && panes.length === 1;
|
|
405
|
-
const activeLocalPane = hideChannelTabsForLocalSms
|
|
406
|
-
? (panes.find(
|
|
407
|
-
(p) => String(p.key).toLowerCase() === String(this.state.selectedChannel).toLowerCase(),
|
|
408
|
-
) || panes[0])
|
|
409
|
-
: null;
|
|
410
374
|
return (
|
|
411
375
|
!isCreativeAccessible ? <AccessForbidden /> : (
|
|
412
|
-
<div
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
meta={[
|
|
420
|
-
{ name: 'description', content: this.props.intl.formatMessage(messages.creativesDesc) },
|
|
421
|
-
]}
|
|
422
|
-
/>
|
|
423
|
-
)}
|
|
376
|
+
<div className={`${className} creatives-templates-container ${isFullMode ? 'fullmode' : 'library-mode'}`} data-testid="cap-wrapper">
|
|
377
|
+
{isFullMode && <Helmet
|
|
378
|
+
title={this.props.intl.formatMessage(messages.creatives)}
|
|
379
|
+
meta={[
|
|
380
|
+
{ name: 'description', content: this.props.intl.formatMessage(messages.creativesDesc) },
|
|
381
|
+
]}
|
|
382
|
+
/>}
|
|
424
383
|
<div className="component-wrapper">
|
|
425
|
-
{isFullMode &&
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
{hideChannelTabsForLocalSms ? (
|
|
434
|
-
<div className="templates-v2-local-sms-pane">{activeLocalPane?.content}</div>
|
|
435
|
-
) : (
|
|
436
|
-
<StyledCapTab
|
|
437
|
-
panes={panes}
|
|
438
|
-
onChange={this.channelChange}
|
|
439
|
-
activeKey={this.state.selectedChannel}
|
|
440
|
-
defaultActiveKey={this.state.selectedChannel}
|
|
441
|
-
isFullMode={isFullMode}
|
|
442
|
-
/>
|
|
443
|
-
)}
|
|
384
|
+
{isFullMode && <CapHeader title={<FormattedMessage {...messages.creatives}/>} description={<FormattedMessage {...messages.creativesDesc}/>}/>}
|
|
385
|
+
<StyledCapTab
|
|
386
|
+
panes={this.state.panes}
|
|
387
|
+
onChange={this.channelChange}
|
|
388
|
+
activeKey={this.state.selectedChannel}
|
|
389
|
+
defaultActiveKey={this.state.selectedChannel}
|
|
390
|
+
isFullMode={isFullMode}
|
|
391
|
+
/>
|
|
444
392
|
</div>
|
|
445
393
|
</div>
|
|
446
394
|
)
|
|
@@ -472,17 +420,6 @@ TemplatesV2.propTypes = {
|
|
|
472
420
|
currentOrgDetails: PropTypes.object,
|
|
473
421
|
restrictPersonalization: PropTypes.bool,
|
|
474
422
|
isAnonymousType: PropTypes.bool,
|
|
475
|
-
// Optional: reuse grid UI with local template list (e.g. SMS fallback). Pass object or same keys as individual props.
|
|
476
|
-
localTemplatesConfig: PropTypes.shape({
|
|
477
|
-
useLocalTemplates: PropTypes.bool,
|
|
478
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
479
|
-
localTemplatesLoading: PropTypes.bool,
|
|
480
|
-
localTemplatesLoadingTip: PropTypes.string,
|
|
481
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
482
|
-
localTemplatesFooterContent: PropTypes.node,
|
|
483
|
-
localTemplatesOnPageChange: PropTypes.func,
|
|
484
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
485
|
-
}),
|
|
486
423
|
};
|
|
487
424
|
|
|
488
425
|
TemplatesV2.defaultProps = {
|
|
@@ -11,7 +11,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
11
11
|
describe('getDefaultWeChatTemplates Saga', () => {
|
|
12
12
|
const params = { channel: 'WeChat', queryParams: { type: 'default' } };
|
|
13
13
|
|
|
14
|
-
it('handles fetching default WeChat templates successfully', () => {
|
|
14
|
+
it.concurrent('handles fetching default WeChat templates successfully', () => {
|
|
15
15
|
const fakeResponse = {
|
|
16
16
|
response: {
|
|
17
17
|
unMapped: [{ id: 1, name: 'Template One' }],
|
|
@@ -31,7 +31,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
31
31
|
.run();
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
it('handles failure in fetching default WeChat templates', () => {
|
|
34
|
+
it.concurrent('handles failure in fetching default WeChat templates', () => {
|
|
35
35
|
const error = new Error('Fetch failed');
|
|
36
36
|
|
|
37
37
|
return expectSaga(sagas.getDefaultWeChatTemplates, params)
|
|
@@ -48,7 +48,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
48
48
|
|
|
49
49
|
describe('createTemplate Saga', () => {
|
|
50
50
|
const template = { name: 'New WeChat Template' };
|
|
51
|
-
test('handles creating a WeChat template successfully', () => {
|
|
51
|
+
test.concurrent('handles creating a WeChat template successfully', () => {
|
|
52
52
|
const fakeResponse = {
|
|
53
53
|
response: template,
|
|
54
54
|
status: { code: 200 }
|
|
@@ -64,7 +64,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
64
64
|
})
|
|
65
65
|
.run();
|
|
66
66
|
});
|
|
67
|
-
test('handles failure when creating a WeChat template', () => {
|
|
67
|
+
test.concurrent('handles failure when creating a WeChat template', () => {
|
|
68
68
|
const error = new Error('Creation failed');
|
|
69
69
|
return expectSaga(sagas.createTemplate, template)
|
|
70
70
|
.provide([
|
|
@@ -79,7 +79,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
describe('fetchWeCrmAccounts Saga', () => {
|
|
82
|
-
it('handles fetching WeCrm accounts successfully', () => {
|
|
82
|
+
it.concurrent('handles fetching WeCrm accounts successfully', () => {
|
|
83
83
|
const fakeResponse = {
|
|
84
84
|
response: [{ id: 1, name: 'Account One' }]
|
|
85
85
|
};
|
|
@@ -95,7 +95,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
95
95
|
.run();
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
it('handles failure in fetching WeCrm accounts', () => {
|
|
98
|
+
it.concurrent('handles failure in fetching WeCrm accounts', () => {
|
|
99
99
|
const error = new Error('Fetch failed');
|
|
100
100
|
|
|
101
101
|
return expectSaga(sagas.fetchWeCrmAccounts)
|
|
@@ -113,7 +113,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
113
113
|
describe('getTemplateDetails Saga', () => {
|
|
114
114
|
const id = '123';
|
|
115
115
|
|
|
116
|
-
it('handles fetching template details successfully', () => {
|
|
116
|
+
it.concurrent('handles fetching template details successfully', () => {
|
|
117
117
|
const fakeResponse = {
|
|
118
118
|
response: { id: 123, name: 'Detailed Template' }
|
|
119
119
|
};
|
|
@@ -129,7 +129,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
129
129
|
.run();
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
it('handles failure in fetching template details', () => {
|
|
132
|
+
it.concurrent('handles failure in fetching template details', () => {
|
|
133
133
|
const error = new Error('Fetch failed');
|
|
134
134
|
|
|
135
135
|
return expectSaga(sagas.getTemplateDetails, id)
|
|
@@ -148,7 +148,7 @@ describe('WeChat Template Management Sagas', () => {
|
|
|
148
148
|
|
|
149
149
|
// Test combined saga
|
|
150
150
|
describe('Combined v2WechatMapTemplatesSagas', () => {
|
|
151
|
-
it('should initialize all WeChat-related watcher sagas without error', () => {
|
|
151
|
+
it.concurrent('should initialize all WeChat-related watcher sagas without error', () => {
|
|
152
152
|
return expectSaga(v2WechatMapTemplatesSagas)
|
|
153
153
|
.run();
|
|
154
154
|
});
|
|
@@ -119,7 +119,6 @@ import { ANDROID } from '../../v2Components/CommonTestAndPreview/constants';
|
|
|
119
119
|
import CapImageUpload from '../../v2Components/CapImageUpload';
|
|
120
120
|
import TagList from '../TagList';
|
|
121
121
|
import { validateTags } from '../../utils/tagValidations';
|
|
122
|
-
import { splitContentByOrderedVarTokens } from '../../utils/templateVarUtils';
|
|
123
122
|
import { capitalizeString } from '../../utils/Formatter';
|
|
124
123
|
import CapWhatsappCTA from '../../v2Components/CapWhatsappCTA';
|
|
125
124
|
import {
|
|
@@ -497,10 +496,28 @@ export const Whatsapp = (props) => {
|
|
|
497
496
|
);
|
|
498
497
|
};
|
|
499
498
|
|
|
499
|
+
const converStringToVarArr = (validVarArr, content) => {
|
|
500
|
+
const templateVarArray = [];
|
|
501
|
+
while (content?.length !== 0) {
|
|
502
|
+
//converting content string to an array split at var
|
|
503
|
+
const index = content.indexOf(validVarArr?.[0]);
|
|
504
|
+
if (index !== -1) {
|
|
505
|
+
templateVarArray.push(content.substring(0, index)); //push string before var
|
|
506
|
+
templateVarArray.push(validVarArr?.[0]); //push var
|
|
507
|
+
content = content.substring(index + validVarArr?.[0]?.length, content?.length); //remaining str
|
|
508
|
+
validVarArr?.shift(); //remove considered var
|
|
509
|
+
} else {
|
|
510
|
+
templateVarArray.push(content); //remaining str
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return templateVarArray;
|
|
515
|
+
}
|
|
516
|
+
|
|
500
517
|
const computeTextMessage = (msg, varMap, regex) => {
|
|
501
518
|
const validVarArr = msg?.match(regex) || [];
|
|
502
519
|
//conerting msg string to variable arr
|
|
503
|
-
const templateHeaderArray =
|
|
520
|
+
const templateHeaderArray = converStringToVarArr(validVarArr, msg);
|
|
504
521
|
if (templateHeaderArray?.length !== 0) {
|
|
505
522
|
let clonedVarMap = {};
|
|
506
523
|
if (!isEmpty(varMap)) {
|
|
@@ -554,7 +571,7 @@ export const Whatsapp = (props) => {
|
|
|
554
571
|
setUnsubscribeRequired(true);
|
|
555
572
|
}
|
|
556
573
|
//converting msg string to variable arr
|
|
557
|
-
const templateMessageArray =
|
|
574
|
+
const templateMessageArray = converStringToVarArr(validVarArr, msg);
|
|
558
575
|
updateTempMsgArray(templateMessageArray.filter((i) => i === 0 || i));
|
|
559
576
|
};
|
|
560
577
|
|