@capillarytech/creatives-library 8.0.345-alpha.13 → 8.0.345-alpha.15
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 +29 -0
- package/package.json +1 -1
- package/services/api.js +0 -20
- package/services/tests/api.test.js +13 -59
- package/utils/commonUtils.js +19 -1
- package/utils/rcsPayloadUtils.js +92 -0
- package/utils/templateVarUtils.js +201 -0
- package/utils/tests/templateVarUtils.test.js +204 -0
- package/v2Components/CapActionButton/constants.js +7 -0
- package/v2Components/CapActionButton/index.js +167 -109
- package/v2Components/CapActionButton/index.scss +157 -6
- package/v2Components/CapActionButton/messages.js +19 -3
- package/v2Components/CapActionButton/tests/index.test.js +41 -17
- package/v2Components/CapCustomSkeleton/index.js +1 -1
- package/v2Components/CapCustomSkeleton/tests/__snapshots__/index.test.js.snap +12 -12
- package/v2Components/CapTagList/index.js +10 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +207 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +160 -15
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +18 -0
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +341 -76
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
- package/v2Components/CommonTestAndPreview/constants.js +38 -2
- package/v2Components/CommonTestAndPreview/index.js +676 -186
- package/v2Components/CommonTestAndPreview/messages.js +49 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +15 -6
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +308 -284
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +231 -65
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +34 -13
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +8 -10
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
- package/v2Components/SmsFallback/constants.js +73 -0
- package/v2Components/SmsFallback/index.js +955 -0
- package/v2Components/SmsFallback/index.scss +265 -0
- package/v2Components/SmsFallback/messages.js +78 -0
- package/v2Components/SmsFallback/smsFallbackUtils.js +118 -0
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +277 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +33 -23
- package/v2Components/TemplatePreview/constants.js +2 -0
- package/v2Components/TemplatePreview/index.js +143 -28
- package/v2Components/TemplatePreview/tests/index.test.js +142 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
- package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +36 -4
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +11 -4
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
- package/v2Containers/CreativesContainer/constants.js +9 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
- package/v2Containers/CreativesContainer/index.js +300 -108
- package/v2Containers/CreativesContainer/index.scss +51 -1
- package/v2Containers/CreativesContainer/messages.js +0 -4
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +78 -34
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +79 -16
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +357 -98
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -18
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/v2Containers/Rcs/constants.js +119 -8
- package/v2Containers/Rcs/index.js +2379 -807
- package/v2Containers/Rcs/index.js.rej +1336 -0
- package/v2Containers/Rcs/index.scss +276 -6
- package/v2Containers/Rcs/index.scss.rej +74 -0
- package/v2Containers/Rcs/messages.js +38 -3
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +225 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +98018 -70073
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +128 -0
- package/v2Containers/Rcs/tests/index.test.js +152 -121
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +318 -0
- package/v2Containers/Rcs/tests/utils.test.js +646 -30
- package/v2Containers/Rcs/utils.js +478 -11
- package/v2Containers/Sms/Create/index.js +100 -40
- package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/v2Containers/SmsTrai/Create/index.js +9 -4
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/index.js +636 -130
- package/v2Containers/SmsTrai/Edit/index.scss +121 -0
- package/v2Containers/SmsTrai/Edit/messages.js +14 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4328 -2375
- package/v2Containers/SmsWrapper/index.js +37 -8
- package/v2Containers/TagList/index.js +6 -0
- package/v2Containers/Templates/ChannelTypeIllustration.js +6 -23
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +181 -126
- package/v2Containers/Templates/actions.js +11 -36
- package/v2Containers/Templates/constants.js +2 -23
- package/v2Containers/Templates/index.js +142 -333
- package/v2Containers/Templates/messages.js +0 -68
- package/v2Containers/Templates/reducer.js +0 -68
- package/v2Containers/Templates/sagas.js +55 -98
- package/v2Containers/Templates/selectors.js +0 -12
- package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +0 -12
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1042 -1256
- package/v2Containers/Templates/tests/index.test.js +0 -6
- package/v2Containers/Templates/tests/reducer.test.js +0 -178
- package/v2Containers/Templates/tests/sagas.test.js +200 -436
- package/v2Containers/Templates/tests/selector.test.js +0 -32
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/v2Containers/TemplatesV2/index.js +86 -23
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/v2Containers/Whatsapp/index.js +3 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
- package/v2Containers/Assets/images/archive_Empty_Illustration.svg +0 -9
|
@@ -618,72 +618,4 @@ export default defineMessages({
|
|
|
618
618
|
id: `${scope}.templateUpdateSuccess`,
|
|
619
619
|
defaultMessage: 'Template updated successfully',
|
|
620
620
|
},
|
|
621
|
-
"archiveTemplates": {
|
|
622
|
-
id: `${scope}.archiveTemplates`,
|
|
623
|
-
defaultMessage: 'Archive templates',
|
|
624
|
-
},
|
|
625
|
-
"archiveTemplateContent": {
|
|
626
|
-
id: `${scope}.archiveTemplateContent`,
|
|
627
|
-
defaultMessage: 'These templates will be archived and unavailable for use. You can restore them anytime.',
|
|
628
|
-
},
|
|
629
|
-
"archiveTemplateSingleContent": {
|
|
630
|
-
id: `${scope}.archiveTemplateSingleContent`,
|
|
631
|
-
defaultMessage: 'This template will be archived and unavailable for use. You can restore it anytime.',
|
|
632
|
-
},
|
|
633
|
-
"unarchiveTemplates": {
|
|
634
|
-
id: `${scope}.unarchiveTemplates`,
|
|
635
|
-
defaultMessage: 'Unarchive templates',
|
|
636
|
-
},
|
|
637
|
-
"unarchiveTemplateContent": {
|
|
638
|
-
id: `${scope}.unarchiveTemplateContent`,
|
|
639
|
-
defaultMessage: 'These templates will be unarchived and available for use again.',
|
|
640
|
-
},
|
|
641
|
-
"unarchiveTemplateSingleContent": {
|
|
642
|
-
id: `${scope}.unarchiveTemplateSingleContent`,
|
|
643
|
-
defaultMessage: 'This template will be unarchived and available for use again.',
|
|
644
|
-
},
|
|
645
|
-
"archiveConfirmOk": {
|
|
646
|
-
id: `${scope}.archiveConfirmOk`,
|
|
647
|
-
defaultMessage: 'Confirm',
|
|
648
|
-
},
|
|
649
|
-
"archiveConfirmCancel": {
|
|
650
|
-
id: `${scope}.archiveConfirmCancel`,
|
|
651
|
-
defaultMessage: 'Cancel',
|
|
652
|
-
},
|
|
653
|
-
"archiveButton": {
|
|
654
|
-
id: `${scope}.archiveButton`,
|
|
655
|
-
defaultMessage: 'Archive',
|
|
656
|
-
},
|
|
657
|
-
"unarchiveButton": {
|
|
658
|
-
id: `${scope}.unarchiveButton`,
|
|
659
|
-
defaultMessage: 'Unarchive',
|
|
660
|
-
},
|
|
661
|
-
"archivedTag": {
|
|
662
|
-
id: `${scope}.archivedTag`,
|
|
663
|
-
defaultMessage: 'Archived',
|
|
664
|
-
},
|
|
665
|
-
"archivedTemplates": {
|
|
666
|
-
id: `${scope}.archivedTemplates`,
|
|
667
|
-
defaultMessage: 'Archived templates',
|
|
668
|
-
},
|
|
669
|
-
"searchArchivedTemplates": {
|
|
670
|
-
id: `${scope}.searchArchivedTemplates`,
|
|
671
|
-
defaultMessage: 'Search archived templates...',
|
|
672
|
-
},
|
|
673
|
-
"templatesSelected": {
|
|
674
|
-
id: `${scope}.templatesSelected`,
|
|
675
|
-
defaultMessage: '{count} {count, plural, one {template} other {templates}} selected',
|
|
676
|
-
},
|
|
677
|
-
"cannotEditArchivedTemplate": {
|
|
678
|
-
id: `${scope}.cannotEditArchivedTemplate`,
|
|
679
|
-
defaultMessage: 'Cannot edit an archived template. Please unarchive it first.',
|
|
680
|
-
},
|
|
681
|
-
"noArchivedCreatives": {
|
|
682
|
-
id: `${scope}.noArchivedCreatives`,
|
|
683
|
-
defaultMessage: 'No archived creatives',
|
|
684
|
-
},
|
|
685
|
-
"noArchivedCreativesDesc": {
|
|
686
|
-
id: `${scope}.noArchivedCreativesDesc`,
|
|
687
|
-
defaultMessage: 'Creatives you archive will appear here',
|
|
688
|
-
},
|
|
689
621
|
});
|
|
@@ -26,13 +26,6 @@ export const initialState = fromJS({
|
|
|
26
26
|
reportsSettings: {},
|
|
27
27
|
},
|
|
28
28
|
senderDetails: {},
|
|
29
|
-
archiveFilter: 'active',
|
|
30
|
-
isArchivedMode: false,
|
|
31
|
-
selectedTemplateIds: fromJS([]),
|
|
32
|
-
archiveInProgress: false,
|
|
33
|
-
unarchiveInProgress: false,
|
|
34
|
-
bulkArchiveInProgress: false,
|
|
35
|
-
bulkUnarchiveInProgress: false,
|
|
36
29
|
});
|
|
37
30
|
|
|
38
31
|
function templatesReducer(state = initialState, action) {
|
|
@@ -238,67 +231,6 @@ function templatesReducer(state = initialState, action) {
|
|
|
238
231
|
hostName: '',
|
|
239
232
|
errors: action.payload,
|
|
240
233
|
});
|
|
241
|
-
case types.SET_ARCHIVE_FILTER:
|
|
242
|
-
return state
|
|
243
|
-
.set('archiveFilter', action.filter)
|
|
244
|
-
.set('templates', [])
|
|
245
|
-
.set('selectedTemplateIds', fromJS([]));
|
|
246
|
-
case types.SET_ARCHIVED_MODE:
|
|
247
|
-
return state
|
|
248
|
-
.set('isArchivedMode', action.isArchived)
|
|
249
|
-
.set('archiveFilter', action.isArchived ? 'archived' : 'active')
|
|
250
|
-
.set('templates', [])
|
|
251
|
-
.set('selectedTemplateIds', fromJS([]));
|
|
252
|
-
case types.TOGGLE_TEMPLATE_SELECTION: {
|
|
253
|
-
const rawSelected = state.get('selectedTemplateIds');
|
|
254
|
-
// Defensive: handle undefined (stale persisted state) or plain array (pre-fromJS migration)
|
|
255
|
-
const currentSelected = rawSelected && typeof rawSelected.toJS === 'function'
|
|
256
|
-
? rawSelected.toJS()
|
|
257
|
-
: (Array.isArray(rawSelected) ? rawSelected : []);
|
|
258
|
-
const idx = currentSelected.indexOf(action.id);
|
|
259
|
-
const newSelected = idx === -1
|
|
260
|
-
? [...currentSelected, action.id]
|
|
261
|
-
: currentSelected.filter((id) => id !== action.id);
|
|
262
|
-
return state.set('selectedTemplateIds', fromJS(newSelected));
|
|
263
|
-
}
|
|
264
|
-
case types.SELECT_ALL_TEMPLATES:
|
|
265
|
-
return state.set('selectedTemplateIds', fromJS(action.ids));
|
|
266
|
-
case types.CLEAR_TEMPLATE_SELECTION:
|
|
267
|
-
return state.set('selectedTemplateIds', fromJS([]));
|
|
268
|
-
case types.ARCHIVE_TEMPLATE_REQUEST:
|
|
269
|
-
return state.set('archiveInProgress', true);
|
|
270
|
-
case types.ARCHIVE_TEMPLATE_SUCCESS: {
|
|
271
|
-
const afterArchive = state.get('selectedTemplateIds');
|
|
272
|
-
const archiveSelected = afterArchive && typeof afterArchive.toJS === 'function' ? afterArchive.toJS() : [];
|
|
273
|
-
return state
|
|
274
|
-
.set('archiveInProgress', false)
|
|
275
|
-
.set('selectedTemplateIds', fromJS(archiveSelected.filter((sid) => sid !== action.id)));
|
|
276
|
-
}
|
|
277
|
-
case types.ARCHIVE_TEMPLATE_FAILURE:
|
|
278
|
-
return state.set('archiveInProgress', false);
|
|
279
|
-
case types.UNARCHIVE_TEMPLATE_REQUEST:
|
|
280
|
-
return state.set('unarchiveInProgress', true);
|
|
281
|
-
case types.UNARCHIVE_TEMPLATE_SUCCESS: {
|
|
282
|
-
const afterUnarchive = state.get('selectedTemplateIds');
|
|
283
|
-
const unarchiveSelected = afterUnarchive && typeof afterUnarchive.toJS === 'function' ? afterUnarchive.toJS() : [];
|
|
284
|
-
return state
|
|
285
|
-
.set('unarchiveInProgress', false)
|
|
286
|
-
.set('selectedTemplateIds', fromJS(unarchiveSelected.filter((sid) => sid !== action.id)));
|
|
287
|
-
}
|
|
288
|
-
case types.UNARCHIVE_TEMPLATE_FAILURE:
|
|
289
|
-
return state.set('unarchiveInProgress', false);
|
|
290
|
-
case types.BULK_ARCHIVE_REQUEST:
|
|
291
|
-
return state.set('bulkArchiveInProgress', true);
|
|
292
|
-
case types.BULK_ARCHIVE_SUCCESS:
|
|
293
|
-
return state.set('bulkArchiveInProgress', false).set('selectedTemplateIds', fromJS([]));
|
|
294
|
-
case types.BULK_ARCHIVE_FAILURE:
|
|
295
|
-
return state.set('bulkArchiveInProgress', false);
|
|
296
|
-
case types.BULK_UNARCHIVE_REQUEST:
|
|
297
|
-
return state.set('bulkUnarchiveInProgress', true);
|
|
298
|
-
case types.BULK_UNARCHIVE_SUCCESS:
|
|
299
|
-
return state.set('bulkUnarchiveInProgress', false).set('selectedTemplateIds', fromJS([]));
|
|
300
|
-
case types.BULK_UNARCHIVE_FAILURE:
|
|
301
|
-
return state.set('bulkUnarchiveInProgress', false);
|
|
302
234
|
default:
|
|
303
235
|
return state;
|
|
304
236
|
}
|
|
@@ -1,51 +1,75 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import {
|
|
3
|
-
call, put,
|
|
2
|
+
call, put, takeLatest, takeEvery, all,
|
|
4
3
|
} from 'redux-saga/effects';
|
|
5
4
|
import get from 'lodash/get';
|
|
6
|
-
import { CapNotification } from '@capillarytech/cap-ui-library';
|
|
7
5
|
// import { schema, normalize } from 'normalizr';
|
|
8
6
|
import * as Api from '../../services/api';
|
|
9
7
|
import * as types from './constants';
|
|
10
8
|
import { saveCdnConfigs, removeAllCdnLocalStorageItems } from '../../utils/cdnTransformation';
|
|
11
9
|
import { COPY_OF } from '../../constants/unified';
|
|
10
|
+
import { fetchSmsTemplatesFromQuery } from './utils/smsTemplatesListApi';
|
|
12
11
|
import { ZALO_TEMPLATE_INFO_REQUEST } from '../Zalo/constants';
|
|
13
12
|
import { getTemplateInfoById } from '../Zalo/saga';
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
templateName
|
|
17
|
-
? (
|
|
18
|
-
<span>
|
|
19
|
-
<span className="notification-template-label">Template name </span>
|
|
20
|
-
<span className="notification-template-name">{templateName}</span>
|
|
21
|
-
</span>
|
|
22
|
-
)
|
|
23
|
-
: undefined
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
// Individual exports for testing
|
|
27
|
-
export function* getAllTemplates(channel, queryParams) {
|
|
14
|
+
export function* getLocalSmsTemplates(action) {
|
|
28
15
|
try {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
const fetched = yield call(
|
|
17
|
+
fetchSmsTemplatesFromQuery,
|
|
18
|
+
action.queryParams,
|
|
19
|
+
action.intlCopyOf,
|
|
20
|
+
);
|
|
21
|
+
if (typeof action.onSuccess === 'function') {
|
|
22
|
+
yield call(action.onSuccess, fetched);
|
|
23
|
+
}
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (typeof action.onFailure === 'function') {
|
|
26
|
+
yield call(action.onFailure, error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function* getAllTemplates(action) {
|
|
32
|
+
try {
|
|
33
|
+
if (action.channel && String(action.channel).toLowerCase() === 'sms') {
|
|
34
|
+
const fetched = yield call(
|
|
35
|
+
fetchSmsTemplatesFromQuery,
|
|
36
|
+
action.queryParams,
|
|
37
|
+
action.intlCopyOf,
|
|
38
|
+
);
|
|
39
|
+
yield put({
|
|
40
|
+
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
41
|
+
data: fetched.channelTemplates,
|
|
42
|
+
weCRMTemplate: fetched.weCRMTemplate,
|
|
43
|
+
isReset: get(action, 'queryParams.page') === 1,
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const result = yield call(Api.getAllTemplates, action);
|
|
49
|
+
const channelTemplates = (action.channel === 'wechat')
|
|
50
|
+
? { templates: [...result.response.mapped, ...result.response.richmedia] }
|
|
51
|
+
: result.response;
|
|
52
|
+
if (action.channel === 'wechat' && action.queryParams && action.queryParams.sortBy && action.queryParams.sortBy.toLocaleLowerCase() === ("Most Recent").toLocaleLowerCase()) {
|
|
33
53
|
channelTemplates.templates.sort((a, b) => {
|
|
34
54
|
const dateA = new Date(a.updatedAt);
|
|
35
55
|
const dateB = new Date(b.updatedAt);
|
|
36
56
|
return dateB - dateA;
|
|
37
57
|
});
|
|
38
|
-
} else if (
|
|
58
|
+
} else if (action.channel === 'wechat' && action.queryParams && action.queryParams.sortBy && action.queryParams.sortBy.toLocaleLowerCase() === ("Alphabetically").toLocaleLowerCase()) {
|
|
39
59
|
channelTemplates.templates.sort((a, b) => b.name - a.name);
|
|
40
60
|
}
|
|
41
|
-
|
|
42
|
-
if (channel.intlCopyOf && channelTemplates?.templates) {
|
|
61
|
+
if (action.intlCopyOf && channelTemplates?.templates) {
|
|
43
62
|
channelTemplates.templates = channelTemplates.templates.map((template) => ({
|
|
44
63
|
...template,
|
|
45
|
-
name: template.name.replace(new RegExp(COPY_OF, 'g'),
|
|
64
|
+
name: template.name.replace(new RegExp(COPY_OF, 'g'), action.intlCopyOf),
|
|
46
65
|
}));
|
|
47
66
|
}
|
|
48
|
-
yield put({
|
|
67
|
+
yield put({
|
|
68
|
+
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
69
|
+
data: channelTemplates,
|
|
70
|
+
weCRMTemplate: result.response.unMapped,
|
|
71
|
+
isReset: get(action, 'queryParams.page') === 1,
|
|
72
|
+
});
|
|
49
73
|
} catch (error) {
|
|
50
74
|
yield put({ type: types.GET_ALL_TEMPLATES_FAILURE, error });
|
|
51
75
|
}
|
|
@@ -215,78 +239,13 @@ export function* getSenderDetails({
|
|
|
215
239
|
}
|
|
216
240
|
}
|
|
217
241
|
|
|
218
|
-
export function*
|
|
219
|
-
|
|
220
|
-
yield call(Api.archiveTemplate, { channel, id });
|
|
221
|
-
yield put({ type: types.ARCHIVE_TEMPLATE_SUCCESS, id });
|
|
222
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
223
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
224
|
-
CapNotification.success({ message: 'Template archived successfully', description: templateNameDescription(templateName) });
|
|
225
|
-
} catch (error) {
|
|
226
|
-
yield put({ type: types.ARCHIVE_TEMPLATE_FAILURE, error });
|
|
227
|
-
CapNotification.error({ message: 'Failed to archive template' });
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export function* unarchiveTemplateSaga({ channel, id, templateName }) {
|
|
232
|
-
try {
|
|
233
|
-
yield call(Api.unarchiveTemplate, { channel, id });
|
|
234
|
-
yield put({ type: types.UNARCHIVE_TEMPLATE_SUCCESS, id });
|
|
235
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
236
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
237
|
-
CapNotification.success({ message: 'Template unarchived successfully', description: templateNameDescription(templateName) });
|
|
238
|
-
} catch (error) {
|
|
239
|
-
yield put({ type: types.UNARCHIVE_TEMPLATE_FAILURE, error });
|
|
240
|
-
CapNotification.error({ message: 'Failed to unarchive template' });
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export function* bulkArchiveTemplatesSaga({ channel, ids }) {
|
|
245
|
-
try {
|
|
246
|
-
const result = yield call(Api.bulkArchiveTemplates, { channel, ids });
|
|
247
|
-
yield put({ type: types.BULK_ARCHIVE_SUCCESS });
|
|
248
|
-
const count = get(result, 'response.modifiedCount', ids.length);
|
|
249
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
250
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
251
|
-
CapNotification.success({ message: `${count} templates archived successfully` });
|
|
252
|
-
} catch (error) {
|
|
253
|
-
yield put({ type: types.BULK_ARCHIVE_FAILURE, error });
|
|
254
|
-
CapNotification.error({ message: 'Failed to archive templates' });
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export function* bulkUnarchiveTemplatesSaga({ channel, ids }) {
|
|
259
|
-
try {
|
|
260
|
-
const result = yield call(Api.bulkUnarchiveTemplates, { channel, ids });
|
|
261
|
-
yield put({ type: types.BULK_UNARCHIVE_SUCCESS });
|
|
262
|
-
const count = get(result, 'response.modifiedCount', ids.length);
|
|
263
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
264
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
265
|
-
CapNotification.success({ message: `${count} templates unarchived successfully` });
|
|
266
|
-
} catch (error) {
|
|
267
|
-
yield put({ type: types.BULK_UNARCHIVE_FAILURE, error });
|
|
268
|
-
CapNotification.error({ message: 'Failed to unarchive templates' });
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export function* watchArchiveTemplate() {
|
|
273
|
-
yield takeLatest(types.ARCHIVE_TEMPLATE_REQUEST, archiveTemplateSaga);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export function* watchUnarchiveTemplate() {
|
|
277
|
-
yield takeLatest(types.UNARCHIVE_TEMPLATE_REQUEST, unarchiveTemplateSaga);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export function* watchBulkArchive() {
|
|
281
|
-
yield takeLatest(types.BULK_ARCHIVE_REQUEST, bulkArchiveTemplatesSaga);
|
|
242
|
+
export function* watchGetAllTemplates() {
|
|
243
|
+
yield takeLatest(types.GET_ALL_TEMPLATES_REQUEST, getAllTemplates);
|
|
282
244
|
}
|
|
283
245
|
|
|
284
|
-
export function* watchBulkUnarchive() {
|
|
285
|
-
yield takeLatest(types.BULK_UNARCHIVE_REQUEST, bulkUnarchiveTemplatesSaga);
|
|
286
|
-
}
|
|
287
246
|
|
|
288
|
-
export function*
|
|
289
|
-
yield
|
|
247
|
+
export function* watchGetLocalSmsTemplates() {
|
|
248
|
+
yield takeEvery(types.GET_LOCAL_SMS_TEMPLATES_REQUEST, getLocalSmsTemplates);
|
|
290
249
|
}
|
|
291
250
|
|
|
292
251
|
export function* watchDeleteTemplate() {
|
|
@@ -342,6 +301,7 @@ export function* watchForGetTemplateInfoById() {
|
|
|
342
301
|
// All sagas to be loaded
|
|
343
302
|
export default [
|
|
344
303
|
watchGetAllTemplates,
|
|
304
|
+
watchGetLocalSmsTemplates,
|
|
345
305
|
watchDeleteTemplate,
|
|
346
306
|
watchDeleteRcsTemplate,
|
|
347
307
|
watchGetUserList,
|
|
@@ -358,6 +318,7 @@ export default [
|
|
|
358
318
|
export function* v2TemplateSaga() {
|
|
359
319
|
yield all([
|
|
360
320
|
watchGetAllTemplates(),
|
|
321
|
+
watchGetLocalSmsTemplates(),
|
|
361
322
|
watchDeleteTemplate(),
|
|
362
323
|
watchDeleteRcsTemplate(),
|
|
363
324
|
watchGetUserList(),
|
|
@@ -367,10 +328,6 @@ export function* v2TemplateSaga() {
|
|
|
367
328
|
watchFetchWeCrmAccounts(),
|
|
368
329
|
watchGetSenderDetails(),
|
|
369
330
|
watchForGetTemplateInfoById(), // Zalo preview functionality from Templates component
|
|
370
|
-
watchArchiveTemplate(),
|
|
371
|
-
watchUnarchiveTemplate(),
|
|
372
|
-
watchBulkArchive(),
|
|
373
|
-
watchBulkUnarchive(),
|
|
374
331
|
]);
|
|
375
332
|
}
|
|
376
333
|
|
|
@@ -72,16 +72,6 @@ const selectBEEEditor = () => createSelector(makeSelectTemplates(), (templates)
|
|
|
72
72
|
return BEETemplate || null;
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
const selectArchiveFilter = () => createSelector(
|
|
76
|
-
makeSelectTemplates(),
|
|
77
|
-
(substate) => substate.archiveFilter || 'active',
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
const selectSelectedTemplateIds = () => createSelector(
|
|
81
|
-
makeSelectTemplates(),
|
|
82
|
-
(substate) => substate.selectedTemplateIds || [],
|
|
83
|
-
);
|
|
84
|
-
|
|
85
75
|
export {
|
|
86
76
|
uploadSelector,
|
|
87
77
|
templateUserList,
|
|
@@ -93,6 +83,4 @@ export {
|
|
|
93
83
|
selectEdmEditor,
|
|
94
84
|
selectBEEEditor,
|
|
95
85
|
selectCmsTemplatesLoader,
|
|
96
|
-
selectArchiveFilter,
|
|
97
|
-
selectSelectedTemplateIds,
|
|
98
86
|
};
|
|
@@ -320,16 +320,4 @@ describe('ChannelTypeIllustration', () => {
|
|
|
320
320
|
}).not.toThrow();
|
|
321
321
|
});
|
|
322
322
|
});
|
|
323
|
-
|
|
324
|
-
describe('isArchivedMode', () => {
|
|
325
|
-
it('should render CapIllustration when isArchivedMode is true', () => {
|
|
326
|
-
const wrapper = renderComponent({ isArchivedMode: true });
|
|
327
|
-
expect(wrapper.find('CapIllustration').exists()).toBe(true);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it('should render CapIllustration when isArchivedMode is false', () => {
|
|
331
|
-
const wrapper = renderComponent({ isArchivedMode: false, currentChannel: SMS });
|
|
332
|
-
expect(wrapper.find('CapIllustration').exists()).toBe(true);
|
|
333
|
-
});
|
|
334
|
-
});
|
|
335
323
|
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
6
|
+
import '@testing-library/jest-dom';
|
|
7
|
+
import TemplatesActionBar from '../TemplatesActionBar';
|
|
8
|
+
|
|
9
|
+
jest.mock('@capillarytech/cap-ui-library/CapInput', () => {
|
|
10
|
+
const React = require('react');
|
|
11
|
+
function Search(props) {
|
|
12
|
+
return React.createElement('input', {
|
|
13
|
+
'data-testid': 'cap-input-search',
|
|
14
|
+
value: props?.value,
|
|
15
|
+
placeholder: props?.placeholder,
|
|
16
|
+
onChange: props?.onChange,
|
|
17
|
+
onKeyDown: (e) => {
|
|
18
|
+
if (e.key === 'Enter' && props.onPressEnter) {
|
|
19
|
+
props.onPressEnter(e);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function CapInput() {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
CapInput.Search = Search;
|
|
28
|
+
return { __esModule: true, default: CapInput };
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
jest.mock('@capillarytech/cap-ui-library/CapButton', () => {
|
|
32
|
+
const React = require('react');
|
|
33
|
+
return function CapButton(props) {
|
|
34
|
+
return React.createElement('button', {
|
|
35
|
+
type: 'button',
|
|
36
|
+
'data-testid': 'cta',
|
|
37
|
+
onClick: props?.onClick,
|
|
38
|
+
disabled: props?.disabled,
|
|
39
|
+
}, props?.children);
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('TemplatesActionBar', () => {
|
|
44
|
+
it('renders search when searchPlaceholder is set', () => {
|
|
45
|
+
render(
|
|
46
|
+
<TemplatesActionBar
|
|
47
|
+
searchPlaceholder="Find templates"
|
|
48
|
+
searchValue="hi"
|
|
49
|
+
ctaLabel="Create"
|
|
50
|
+
/>,
|
|
51
|
+
);
|
|
52
|
+
expect(screen.getByTestId('cap-input-search')).toHaveAttribute('placeholder', 'Find templates');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('omits search when searchPlaceholder is empty', () => {
|
|
56
|
+
const { container } = render(
|
|
57
|
+
<TemplatesActionBar searchPlaceholder="" ctaLabel="Go" />,
|
|
58
|
+
);
|
|
59
|
+
expect(container.querySelector('[data-testid="cap-input-search"]')).toBeNull();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('fires onSearchChange and onCtaClick', () => {
|
|
63
|
+
const onSearchChange = jest.fn();
|
|
64
|
+
const onCtaClick = jest.fn();
|
|
65
|
+
render(
|
|
66
|
+
<TemplatesActionBar
|
|
67
|
+
searchPlaceholder="S"
|
|
68
|
+
onSearchChange={onSearchChange}
|
|
69
|
+
ctaLabel="New"
|
|
70
|
+
onCtaClick={onCtaClick}
|
|
71
|
+
/>,
|
|
72
|
+
);
|
|
73
|
+
fireEvent.change(screen.getByTestId('cap-input-search'), { target: { value: 'x' } });
|
|
74
|
+
fireEvent.click(screen.getByTestId('cta'));
|
|
75
|
+
expect(onSearchChange).toHaveBeenCalled();
|
|
76
|
+
expect(onCtaClick).toHaveBeenCalled();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('fires onSearch when Enter is pressed (antd Input has no native onSearch)', () => {
|
|
80
|
+
const onSearch = jest.fn();
|
|
81
|
+
render(
|
|
82
|
+
<TemplatesActionBar
|
|
83
|
+
searchPlaceholder="S"
|
|
84
|
+
searchValue="query"
|
|
85
|
+
onSearch={onSearch}
|
|
86
|
+
ctaLabel="New"
|
|
87
|
+
/>,
|
|
88
|
+
);
|
|
89
|
+
const input = screen.getByTestId('cap-input-search');
|
|
90
|
+
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
|
91
|
+
expect(onSearch).toHaveBeenCalledWith('query');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('renders ctaNode instead of default button when provided', () => {
|
|
95
|
+
render(
|
|
96
|
+
<TemplatesActionBar
|
|
97
|
+
searchPlaceholder="S"
|
|
98
|
+
ctaNode={<span data-testid="custom-cta">Custom</span>}
|
|
99
|
+
/>,
|
|
100
|
+
);
|
|
101
|
+
expect(screen.getByTestId('custom-cta')).toBeInTheDocument();
|
|
102
|
+
expect(screen.queryByTestId('cta')).toBeNull();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('hides CTA area when showCta is false', () => {
|
|
106
|
+
const { container } = render(
|
|
107
|
+
<TemplatesActionBar searchPlaceholder="S" showCta={false} ctaLabel="X" />,
|
|
108
|
+
);
|
|
109
|
+
expect(container.querySelector('[data-testid="cta"]')).toBeNull();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('renders children in toolbar row', () => {
|
|
113
|
+
render(
|
|
114
|
+
<TemplatesActionBar searchPlaceholder="S" ctaLabel="C">
|
|
115
|
+
<span data-testid="child">extra</span>
|
|
116
|
+
</TemplatesActionBar>,
|
|
117
|
+
);
|
|
118
|
+
expect(screen.getByTestId('child')).toBeInTheDocument();
|
|
119
|
+
});
|
|
120
|
+
});
|