@capillarytech/creatives-library 8.0.345-alpha.12 → 8.0.345-alpha.13
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/package.json +1 -1
- package/services/api.js +20 -0
- package/services/tests/api.test.js +59 -13
- package/utils/commonUtils.js +1 -19
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +109 -167
- package/v2Components/CapActionButton/index.scss +6 -157
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +17 -41
- package/v2Components/CapCustomSkeleton/index.js +1 -1
- package/v2Components/CapCustomSkeleton/tests/__snapshots__/index.test.js.snap +12 -12
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +186 -676
- package/v2Components/CommonTestAndPreview/messages.js +3 -49
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
- 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 -132
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +10 -8
- package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
- package/v2Components/TemplatePreview/index.js +28 -143
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- 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/Assets/images/archive_Empty_Illustration.svg +9 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +4 -11
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +108 -300
- package/v2Containers/CreativesContainer/index.scss +1 -51
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
- 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 +98 -357
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +18 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Rcs/constants.js +8 -119
- package/v2Containers/Rcs/index.js +812 -2375
- package/v2Containers/Rcs/index.scss +6 -276
- package/v2Containers/Rcs/messages.js +3 -38
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70345 -98302
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +121 -152
- 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 +40 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +130 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/ChannelTypeIllustration.js +23 -6
- package/v2Containers/Templates/_templates.scss +126 -181
- package/v2Containers/Templates/actions.js +36 -11
- package/v2Containers/Templates/constants.js +23 -2
- package/v2Containers/Templates/index.js +333 -142
- package/v2Containers/Templates/messages.js +68 -0
- package/v2Containers/Templates/reducer.js +68 -0
- package/v2Containers/Templates/sagas.js +98 -55
- package/v2Containers/Templates/selectors.js +12 -0
- package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +12 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1256 -1042
- package/v2Containers/Templates/tests/index.test.js +6 -0
- package/v2Containers/Templates/tests/reducer.test.js +178 -0
- package/v2Containers/Templates/tests/sagas.test.js +436 -200
- package/v2Containers/Templates/tests/selector.test.js +32 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- 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/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- 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 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- 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 -43
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
- 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/index.js.rej +0 -1336
- package/v2Containers/Rcs/index.scss.rej +0 -74
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
- 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 -121
- 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
|
@@ -50,9 +50,7 @@ import {
|
|
|
50
50
|
CapStatus,
|
|
51
51
|
CapColoredTag,
|
|
52
52
|
CapSpin,
|
|
53
|
-
|
|
54
|
-
CapColumn,
|
|
55
|
-
CapCarousel
|
|
53
|
+
CapCheckbox,
|
|
56
54
|
} from "@capillarytech/cap-ui-library";
|
|
57
55
|
import { makeSelectTemplates, makeSelectTemplatesResponse } from './selectors';
|
|
58
56
|
import { makeSelectCreate as makeSelectCreateSms } from '../Sms/Create/selectors';
|
|
@@ -116,23 +114,15 @@ import {
|
|
|
116
114
|
STATUS as WHATSAPP_STATUS,
|
|
117
115
|
WHATSAPP_STATUSES,
|
|
118
116
|
HOST_GUPSHUP,
|
|
119
|
-
HOST_HAPTIC,
|
|
120
117
|
CATEGORY_OPTIONS_MAP,
|
|
121
|
-
HOST_TWILIO,
|
|
122
|
-
TWILIO_CATEGORY_OPTIONS,
|
|
123
|
-
KARIX_GUPSHUP_CATEGORY_OPTIONS,
|
|
124
|
-
ICS_CATEGORY_OPTIONS,
|
|
125
|
-
HAPTIC_CATEGORY_OPTIONS,
|
|
126
|
-
HOST_ICS,
|
|
127
118
|
IMAGE,
|
|
128
119
|
VIDEO,
|
|
129
|
-
GIF,
|
|
130
120
|
} from '../Whatsapp/constants';
|
|
131
|
-
import { INAPP_LAYOUT_DETAILS, INAPP_MESSAGE_LAYOUT_TYPES
|
|
121
|
+
import { INAPP_LAYOUT_DETAILS, INAPP_MESSAGE_LAYOUT_TYPES } from '../InApp/constants';
|
|
132
122
|
import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
|
|
133
123
|
import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta, getWhatsappQuickReply, getWhatsappAutoFill, getWhatsappCarouselButtonView } from '../Whatsapp/utils';
|
|
134
124
|
import { getRCSContent } from '../Rcs/utils';
|
|
135
|
-
import {
|
|
125
|
+
import {RCS_STATUSES} from '../Rcs/constants';
|
|
136
126
|
import zaloMessages from '../Zalo/messages';
|
|
137
127
|
import rcsMessages from '../Rcs/messages';
|
|
138
128
|
import inAppMessages from '../InApp/messages';
|
|
@@ -145,7 +135,7 @@ import {CREATIVE} from '../Facebook/constants';
|
|
|
145
135
|
import videoPlay from '../../assets/videoPlay.svg';
|
|
146
136
|
import whatsappImageEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_image_preview.svg';
|
|
147
137
|
import whatsappVideoEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_video_preview.svg';
|
|
148
|
-
import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
138
|
+
import { CAP_SPACE_16, CAP_G08, CAP_G05, CAP_SPACE_08, CAP_SPACE_12 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
149
139
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
150
140
|
import { MAPP_SDK } from '../InApp/constants';
|
|
151
141
|
import injectReducer from '../../utils/injectReducer';
|
|
@@ -154,7 +144,6 @@ import { compose } from 'redux';
|
|
|
154
144
|
import { v2TemplateSaga } from './sagas';
|
|
155
145
|
import injectSaga from '../../utils/injectSaga';
|
|
156
146
|
import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
|
|
157
|
-
import { Rcs } from '../Rcs';
|
|
158
147
|
import { makeSelectRcs } from '../Rcs/selectors';
|
|
159
148
|
import { getRcsStatusType } from '../Rcs/utils';
|
|
160
149
|
import { makeSelectWebPush } from '../WebPush/selectors';
|
|
@@ -437,6 +426,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
437
426
|
channel = '';
|
|
438
427
|
}
|
|
439
428
|
this.setState({ channel, activeMode });
|
|
429
|
+
// Always reset archive mode and selection when mounting a new channel
|
|
430
|
+
this.props.actions.setArchivedMode(false);
|
|
431
|
+
this.props.actions.clearTemplateSelection();
|
|
440
432
|
// Clear templates when entering account selection mode to prevent showing old channel templates
|
|
441
433
|
if (activeMode === ACCOUNT_SELECTION_MODE) {
|
|
442
434
|
this.props.actions.resetTemplate();
|
|
@@ -468,13 +460,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
468
460
|
if (this.props.location.query.type === 'embedded') {
|
|
469
461
|
this.props.actions.resetAccount();
|
|
470
462
|
}
|
|
471
|
-
|
|
472
|
-
const useLocalTemplates = get(
|
|
473
|
-
this.props,
|
|
474
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
475
|
-
get(this.props, 'useLocalTemplates', false),
|
|
476
|
-
);
|
|
477
|
-
if (!useLocalTemplates && ['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill'].includes((this.state.channel || '').toLowerCase())) {
|
|
463
|
+
if (['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill'].includes((this.state.channel || '').toLowerCase())) {
|
|
478
464
|
const queryParams = {
|
|
479
465
|
// name: this.state.searchText,
|
|
480
466
|
// sortBy: this.state.sortBy,
|
|
@@ -987,16 +973,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
987
973
|
|
|
988
974
|
componentWillUnmount() {
|
|
989
975
|
window.removeEventListener("message", this.handleFrameTasks);
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
this.props,
|
|
993
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
994
|
-
get(this.props, 'useLocalTemplates', false),
|
|
995
|
-
);
|
|
996
|
-
if (!useLocalTemplates) {
|
|
997
|
-
this.props.actions.resetTemplateStoreData();
|
|
998
|
-
this.props.globalActions.clearMetaEntities();
|
|
999
|
-
}
|
|
976
|
+
this.props.actions.resetTemplateStoreData();
|
|
977
|
+
this.props.globalActions.clearMetaEntities();
|
|
1000
978
|
// Clear any pending timeouts to prevent memory leaks
|
|
1001
979
|
if (this._clearEditTimeout) {
|
|
1002
980
|
clearTimeout(this._clearEditTimeout);
|
|
@@ -1609,6 +1587,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1609
1587
|
let queryParams = params || {};
|
|
1610
1588
|
let page = this.state.page;
|
|
1611
1589
|
const { activeMode } = this.state;
|
|
1590
|
+
// Archive filter — use explicit param if provided (props may not have updated yet due to async dispatch)
|
|
1591
|
+
if (!queryParams.archiveStatus) {
|
|
1592
|
+
const archiveFilter = get(this.props, 'Templates.archiveFilter', 'active');
|
|
1593
|
+
queryParams.archiveStatus = archiveFilter;
|
|
1594
|
+
}
|
|
1612
1595
|
if (activeMode === ACCOUNT_SELECTION_MODE) {
|
|
1613
1596
|
this.setTemplatesMode();
|
|
1614
1597
|
}
|
|
@@ -1781,20 +1764,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1781
1764
|
}
|
|
1782
1765
|
|
|
1783
1766
|
filterRcsTemplates = (templates) => {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
nextTemplates = nextTemplates.filter(
|
|
1789
|
-
(t) => get(t, 'versions.base.content.RCS.rcsContent.accountName', '') === selectedRcsAccountName
|
|
1790
|
-
);
|
|
1791
|
-
}
|
|
1792
|
-
if (!this.props.isFullMode && hostName !== HOST_INFOBIP) {
|
|
1793
|
-
return nextTemplates.filter(
|
|
1794
|
-
(t) => get(t, 'versions.base.content.RCS.rcsContent.cardContent[0].Status', 'unavailable') === RCS_STATUSES.approved
|
|
1795
|
-
);
|
|
1767
|
+
let { selectedRcsStatus } = this.state;
|
|
1768
|
+
selectedRcsStatus = !this.props.isFullMode ? RCS_STATUSES.approved : '';
|
|
1769
|
+
if (selectedRcsStatus) {
|
|
1770
|
+
return templates?.filter((template) => template?.versions?.base?.content?.RCS?.rcsContent?.cardContent?.[0]?.Status === selectedRcsStatus);
|
|
1796
1771
|
}
|
|
1797
|
-
return
|
|
1772
|
+
return templates;
|
|
1798
1773
|
}
|
|
1799
1774
|
|
|
1800
1775
|
filterZaloTemplates = (templates) => {
|
|
@@ -1883,6 +1858,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1883
1858
|
const currentChannel = channel.toUpperCase();
|
|
1884
1859
|
const {channel: stateChannel} = this.state;
|
|
1885
1860
|
const channelLowerCase = stateChannel.toLowerCase();
|
|
1861
|
+
const _selectedIds = get(this.props, 'Templates.selectedTemplateIds', []);
|
|
1862
|
+
const _selectedIdsArray = _selectedIds && typeof _selectedIds.toJS === 'function' ? _selectedIds.toJS() : (Array.isArray(_selectedIds) ? _selectedIds : []);
|
|
1863
|
+
const hasSelection = this.props.isFullMode && _selectedIdsArray.length > 0;
|
|
1886
1864
|
let filteredTemplates = templates;
|
|
1887
1865
|
let isTraiDltFeature = false;
|
|
1888
1866
|
switch (currentChannel) {
|
|
@@ -1922,10 +1900,26 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1922
1900
|
const iosBodyType = get(template, 'versions.base.content.IOS.bodyType');
|
|
1923
1901
|
const inappBodyType = androidBodyType || iosBodyType;
|
|
1924
1902
|
const isZaloPreviewLoading = previewTemplateId === template?._id;
|
|
1903
|
+
const selectedIdsForCard = get(this.props, 'Templates.selectedTemplateIds', []);
|
|
1904
|
+
const selectedIdsArrayForCard = selectedIdsForCard.toJS ? selectedIdsForCard.toJS() : selectedIdsForCard;
|
|
1905
|
+
// Archive eligibility per template: Zalo never; WhatsApp/RCS not when pending/awaiting
|
|
1906
|
+
const cardWhatsappStatus = get(template, `versions.base.content.${WHATSAPP_LOWERCASE}.status`, '');
|
|
1907
|
+
const cardRcsStatus = get(template, 'versions.base.content.RCS.rcsContent.cardContent[0].Status', '');
|
|
1908
|
+
const isCardArchiveEligible = currentChannel !== ZALO &&
|
|
1909
|
+
!(currentChannel === WHATSAPP && [WHATSAPP_STATUSES.awaitingApproval, WHATSAPP_STATUSES.pending, WHATSAPP_STATUSES.unsubmitted].includes(cardWhatsappStatus)) &&
|
|
1910
|
+
!(currentChannel === RCS && [RCS_STATUSES.awaitingApproval, RCS_STATUSES.pending].includes(cardRcsStatus));
|
|
1925
1911
|
const templateData = {
|
|
1926
1912
|
key: `${currentChannel}-card-${template?.name}`,
|
|
1927
1913
|
title: (
|
|
1928
|
-
<span title={template?.name}>
|
|
1914
|
+
<span title={template?.name} style={{ display: 'flex', alignItems: 'center' }}>
|
|
1915
|
+
{this.props.isFullMode && this.props.location.query.type !== 'embedded' && isCardArchiveEligible && (
|
|
1916
|
+
<CapCheckbox
|
|
1917
|
+
checked={selectedIdsArrayForCard.includes(template._id)}
|
|
1918
|
+
onChange={() => this.props.actions.toggleTemplateSelection(template._id)}
|
|
1919
|
+
onClick={(e) => e.stopPropagation()}
|
|
1920
|
+
style={{ marginRight: CAP_SPACE_08, flexShrink: 0 }}
|
|
1921
|
+
/>
|
|
1922
|
+
)}
|
|
1929
1923
|
{template?.name}
|
|
1930
1924
|
{currentChannel === INAPP && (
|
|
1931
1925
|
<CapRow>
|
|
@@ -1969,7 +1963,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1969
1963
|
style={{ marginRight: "16px" }}
|
|
1970
1964
|
type="eye"
|
|
1971
1965
|
onClick={() => {
|
|
1972
|
-
if (!this.props.isFullMode || this.props.isDltFromRcs
|
|
1966
|
+
if (!this.props.isFullMode || this.props.isDltFromRcs) {
|
|
1973
1967
|
if (!get(template, "versions.base.content.zalo.previewUrl", "")) {
|
|
1974
1968
|
this.setState({ zaloPreviewItemId: template?._id });
|
|
1975
1969
|
}
|
|
@@ -2046,7 +2040,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2046
2040
|
{![WECHAT, WHATSAPP, ZALO].includes(
|
|
2047
2041
|
this.state.channel.toUpperCase()
|
|
2048
2042
|
) &&
|
|
2049
|
-
!isTraiDltFeature && (
|
|
2043
|
+
!isTraiDltFeature && !template.isArchived && (
|
|
2050
2044
|
<CapMenu.Item
|
|
2051
2045
|
className={`duplicate-${channelLowerCase}`}
|
|
2052
2046
|
onClick={() => this.duplicateTemplate(template)}
|
|
@@ -2054,6 +2048,42 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2054
2048
|
<FormattedMessage {...messages.duplicateButton} />
|
|
2055
2049
|
</CapMenu.Item>
|
|
2056
2050
|
)}
|
|
2051
|
+
{/* Archive/Unarchive menu item (full mode only, not for Zalo, not for WhatsApp/RCS awaiting/pending) */}
|
|
2052
|
+
{(() => {
|
|
2053
|
+
const channelUp = this.state.channel.toUpperCase();
|
|
2054
|
+
const isArchiveEligible = channelUp !== ZALO &&
|
|
2055
|
+
!(channelUp === WHATSAPP && [WHATSAPP_STATUSES.awaitingApproval, WHATSAPP_STATUSES.pending, WHATSAPP_STATUSES.unsubmitted].includes(status)) &&
|
|
2056
|
+
!(channelUp === RCS && [RCS_STATUSES.awaitingApproval, RCS_STATUSES.pending].includes(rcsStatus));
|
|
2057
|
+
if (!isArchiveEligible) return null;
|
|
2058
|
+
return !template.isArchived ? (
|
|
2059
|
+
<CapMenu.Item
|
|
2060
|
+
className={`archive-${channelLowerCase}`}
|
|
2061
|
+
onClick={() => {
|
|
2062
|
+
this.showArchiveConfirm({
|
|
2063
|
+
title: this.props.intl.formatMessage(messages.archiveTemplates),
|
|
2064
|
+
onConfirm: () => this.props.actions.archiveTemplate(this.state.channel, template._id, template.name),
|
|
2065
|
+
count: 1,
|
|
2066
|
+
});
|
|
2067
|
+
}}
|
|
2068
|
+
>
|
|
2069
|
+
<FormattedMessage {...messages.archiveButton} />
|
|
2070
|
+
</CapMenu.Item>
|
|
2071
|
+
) : (
|
|
2072
|
+
<CapMenu.Item
|
|
2073
|
+
className={`unarchive-${channelLowerCase}`}
|
|
2074
|
+
onClick={() => {
|
|
2075
|
+
this.showArchiveConfirm({
|
|
2076
|
+
title: this.props.intl.formatMessage(messages.unarchiveTemplates),
|
|
2077
|
+
onConfirm: () => this.props.actions.unarchiveTemplate(this.state.channel, template._id, template.name),
|
|
2078
|
+
count: 1,
|
|
2079
|
+
isUnarchive: true,
|
|
2080
|
+
});
|
|
2081
|
+
}}
|
|
2082
|
+
>
|
|
2083
|
+
<FormattedMessage {...messages.unarchiveButton} />
|
|
2084
|
+
</CapMenu.Item>
|
|
2085
|
+
);
|
|
2086
|
+
})()}
|
|
2057
2087
|
{/* Delete/Unmap menu item */}
|
|
2058
2088
|
{(!(
|
|
2059
2089
|
this.state.channel.toUpperCase() === WHATSAPP &&
|
|
@@ -2334,7 +2364,15 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2334
2364
|
case WHATSAPP: {
|
|
2335
2365
|
const { whatsappImageSrc = '', templateMsg, docPreview, whatsappVideoPreviewImg = '', templateHeaderPreview, templateFooterPreview, carouselData = [] } = getWhatsappContent(template);
|
|
2336
2366
|
templateData.title = (
|
|
2337
|
-
<CapRow>
|
|
2367
|
+
<CapRow type="flex" align="middle">
|
|
2368
|
+
{this.props.isFullMode && this.props.location.query.type !== 'embedded' && isCardArchiveEligible && (
|
|
2369
|
+
<CapCheckbox
|
|
2370
|
+
checked={selectedIdsArrayForCard.includes(template._id)}
|
|
2371
|
+
onChange={() => this.props.actions.toggleTemplateSelection(template._id)}
|
|
2372
|
+
onClick={(e) => e.stopPropagation()}
|
|
2373
|
+
style={{ marginRight: CAP_SPACE_08, flexShrink: 0 }}
|
|
2374
|
+
/>
|
|
2375
|
+
)}
|
|
2338
2376
|
<CapLabel className="whatsapp-rcs-template-name">{template?.name}</CapLabel>
|
|
2339
2377
|
<WhatsappStatusContainer template={template} />
|
|
2340
2378
|
</CapRow>
|
|
@@ -2427,16 +2465,23 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2427
2465
|
const name = get(template, "name", "");
|
|
2428
2466
|
const statusDisplay=getRcsStatusType(status);
|
|
2429
2467
|
templateData.title = (
|
|
2430
|
-
<CapRow>
|
|
2468
|
+
<CapRow type="flex" align="middle">
|
|
2469
|
+
{this.props.isFullMode && this.props.location.query.type !== 'embedded' && isCardArchiveEligible && (
|
|
2470
|
+
<CapCheckbox
|
|
2471
|
+
checked={selectedIdsArrayForCard.includes(template._id)}
|
|
2472
|
+
onChange={() => this.props.actions.toggleTemplateSelection(template._id)}
|
|
2473
|
+
onClick={(e) => e.stopPropagation()}
|
|
2474
|
+
style={{ marginRight: CAP_SPACE_08, flexShrink: 0 }}
|
|
2475
|
+
/>
|
|
2476
|
+
)}
|
|
2431
2477
|
<CapLabel className="whatsapp-rcs-template-name">{name}</CapLabel>
|
|
2432
|
-
|
|
2478
|
+
<CapRow type="flex" align="middle" className="rcs-status-container zalo-status-color">
|
|
2433
2479
|
<CapStatus
|
|
2434
2480
|
type={statusDisplay}
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
}
|
|
2481
|
+
text={statusDisplay && this.props.intl.formatMessage(rcsMessages?.[`${statusDisplay}_STATUS`])}
|
|
2482
|
+
labelType="label3"
|
|
2483
|
+
/>
|
|
2484
|
+
</CapRow>
|
|
2440
2485
|
</CapRow>
|
|
2441
2486
|
);
|
|
2442
2487
|
|
|
@@ -2552,7 +2597,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2552
2597
|
|
|
2553
2598
|
//no templates available
|
|
2554
2599
|
const showIllustrationForChannel = (forChannel) => {
|
|
2555
|
-
return forChannel === channelLowerCase && isEmpty(templates) && isEmpty(this.state.searchText) && !isLoading;
|
|
2600
|
+
return forChannel === channelLowerCase && isEmpty(templates) && isEmpty(this.state.searchText) && !isLoading && !get(this.props, 'Templates.isArchivedMode', false);
|
|
2556
2601
|
}
|
|
2557
2602
|
//when filters applied not matching templates
|
|
2558
2603
|
const filteredEmptyAndFullModeAs = (fullModeValue) => {
|
|
@@ -2578,9 +2623,49 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2578
2623
|
|
|
2579
2624
|
const noLoaderAndSearchText = isEmpty(this.state.searchText) && !isLoading;
|
|
2580
2625
|
|
|
2581
|
-
|
|
2626
|
+
const isArchivedModeLocal = get(this.props, 'Templates.isArchivedMode', false);
|
|
2627
|
+
const selectedIdsLocal = get(this.props, 'Templates.selectedTemplateIds', []);
|
|
2628
|
+
const selectedIdsArrayLocal = selectedIdsLocal && typeof selectedIdsLocal.toJS === 'function' ? selectedIdsLocal.toJS() : (Array.isArray(selectedIdsLocal) ? selectedIdsLocal : []);
|
|
2629
|
+
const selectedCountLocal = selectedIdsArrayLocal.length;
|
|
2630
|
+
const hasSelectionLocal = this.props.isFullMode && selectedCountLocal > 0;
|
|
2631
|
+
|
|
2632
|
+
return (<div>
|
|
2582
2633
|
{[WECHAT, MOBILE_PUSH, WEBPUSH, INAPP, WHATSAPP, ZALO, RCS].includes(currentChannel) && this.showAccountName()}
|
|
2583
|
-
|
|
2634
|
+
<CapRow type="flex" align="middle" justify="space-between" className="filter-row">
|
|
2635
|
+
<div className="filter-row-content">{filterContent}</div>
|
|
2636
|
+
{hasSelectionLocal && (
|
|
2637
|
+
<CapRow type="flex" align="middle" className="bulk-selection-bar">
|
|
2638
|
+
<CapLabel type="label2">
|
|
2639
|
+
{this.props.intl.formatMessage(messages.templatesSelected, { count: selectedCountLocal })}
|
|
2640
|
+
</CapLabel>
|
|
2641
|
+
<CapButton
|
|
2642
|
+
type="primary"
|
|
2643
|
+
prefix={<CapIcon type="archive" size="l" />}
|
|
2644
|
+
onClick={() => {
|
|
2645
|
+
this.showArchiveConfirm({
|
|
2646
|
+
title: this.props.intl.formatMessage(isArchivedModeLocal ? messages.unarchiveTemplates : messages.archiveTemplates),
|
|
2647
|
+
onConfirm: () => {
|
|
2648
|
+
if (isArchivedModeLocal) {
|
|
2649
|
+
this.props.actions.bulkUnarchiveTemplates(this.state.channel, selectedIdsArrayLocal);
|
|
2650
|
+
} else {
|
|
2651
|
+
this.props.actions.bulkArchiveTemplates(this.state.channel, selectedIdsArrayLocal);
|
|
2652
|
+
}
|
|
2653
|
+
},
|
|
2654
|
+
count: selectedCountLocal,
|
|
2655
|
+
isUnarchive: isArchivedModeLocal,
|
|
2656
|
+
});
|
|
2657
|
+
}}
|
|
2658
|
+
>
|
|
2659
|
+
<span className="archive-btn-label">
|
|
2660
|
+
<FormattedMessage {...(isArchivedModeLocal ? messages.unarchiveButton : messages.archiveButton)} />
|
|
2661
|
+
</span>
|
|
2662
|
+
</CapButton>
|
|
2663
|
+
<CapButton type="secondary" onClick={() => this.props.actions.clearTemplateSelection()}>
|
|
2664
|
+
<FormattedMessage {...messages.archiveConfirmCancel} />
|
|
2665
|
+
</CapButton>
|
|
2666
|
+
</CapRow>
|
|
2667
|
+
)}
|
|
2668
|
+
</CapRow>
|
|
2584
2669
|
{[WHATSAPP, ZALO, INAPP,RCS].includes(currentChannel) && this.selectedFilters()}
|
|
2585
2670
|
{<div>
|
|
2586
2671
|
{!isEmpty(filteredTemplates) || !isEmpty(this.state.searchText) || !isEmpty(this.props.Templates.templateError) ? (
|
|
@@ -2593,7 +2678,7 @@ return (<div>
|
|
|
2593
2678
|
fbType={"list"}
|
|
2594
2679
|
/>
|
|
2595
2680
|
</div>)
|
|
2596
|
-
: [SMS_LOWERCASE, EMAIL_LOWERCASE].includes(this.state.channel.toLowerCase()) && !isLoading && this.getSmsEmailIllustration()
|
|
2681
|
+
: [SMS_LOWERCASE, EMAIL_LOWERCASE].includes(this.state.channel.toLowerCase()) && !isLoading && !get(this.props, 'Templates.isArchivedMode', false) && this.getSmsEmailIllustration()
|
|
2597
2682
|
}
|
|
2598
2683
|
|
|
2599
2684
|
{(this.state.selectedAccount === '' && isEmpty(this.props.Templates.selectedWeChatAccount)) && ([WECHAT_LOWERCASE, MOBILE_PUSH_LOWERCASE, INAPP_LOWERCASE].includes(this.state.channel.toLowerCase())) &&
|
|
@@ -2617,7 +2702,7 @@ return (<div>
|
|
|
2617
2702
|
</div>
|
|
2618
2703
|
)
|
|
2619
2704
|
}
|
|
2620
|
-
{(showWhatsappIllustration || showZaloIllustration) && (
|
|
2705
|
+
{(showWhatsappIllustration || showZaloIllustration) && !get(this.props, 'Templates.isArchivedMode', false) && (
|
|
2621
2706
|
noLoaderAndSearchText &&
|
|
2622
2707
|
<div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto' } : {}}>
|
|
2623
2708
|
{noWhatsappZaloTemplates && <ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} hostName={this.state?.hostName}/>}
|
|
@@ -2658,6 +2743,16 @@ return (<div>
|
|
|
2658
2743
|
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} hostName={this.state?.hostName}/>
|
|
2659
2744
|
</div>
|
|
2660
2745
|
}
|
|
2746
|
+
{get(this.props, 'Templates.isArchivedMode', false) && isEmpty(templates) && !isLoading && !getAllTemplatesInProgress && isEmpty(this.state.searchText) && (
|
|
2747
|
+
<div className={this.isFullMode() ? 'illustration-scroll-wrapper' : ''}>
|
|
2748
|
+
<ChannelTypeIllustration
|
|
2749
|
+
isFullMode={this.props.isFullMode}
|
|
2750
|
+
createTemplate={this.createTemplate}
|
|
2751
|
+
currentChannel={currentChannel}
|
|
2752
|
+
isArchivedMode
|
|
2753
|
+
/>
|
|
2754
|
+
</div>
|
|
2755
|
+
)}
|
|
2661
2756
|
{<CapCustomSkeleton loader={isInitialLoading && (isLoading || getAllTemplatesInProgress)} />}
|
|
2662
2757
|
{<CapPageSpinner spinning={!isInitialLoading && (isLoading || getAllTemplatesInProgress)} />}
|
|
2663
2758
|
</div>
|
|
@@ -2960,7 +3055,6 @@ return (<div>
|
|
|
2960
3055
|
let routeParams = {};
|
|
2961
3056
|
const {fbAdManager} = this.props;
|
|
2962
3057
|
const isLibraryMode = this.isEnabledInLibraryModule("callCreateFromProps");
|
|
2963
|
-
|
|
2964
3058
|
if (!isLibraryMode) {
|
|
2965
3059
|
timeTracker.startTimer(CHANNEL_CREATE_TRACK_MAPPING[channel]);
|
|
2966
3060
|
}
|
|
@@ -3302,17 +3396,14 @@ return (<div>
|
|
|
3302
3396
|
};
|
|
3303
3397
|
|
|
3304
3398
|
handleEditClick(e, template, modeType, path, options) {
|
|
3399
|
+
if (template && template.isArchived) {
|
|
3400
|
+
CapNotification.error({ message: this.props.intl.formatMessage(messages.cannotEditArchivedTemplate) });
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3305
3403
|
if (modeType && modeType !== undefined) {
|
|
3306
3404
|
this.setState({modeType});
|
|
3307
3405
|
}
|
|
3308
3406
|
const { _id: id } = template;
|
|
3309
|
-
const {
|
|
3310
|
-
localTemplatesConfig,
|
|
3311
|
-
fbAdManager,
|
|
3312
|
-
isDltFromRcs,
|
|
3313
|
-
isSmsFallbackFromRcs,
|
|
3314
|
-
onSelectTemplate,
|
|
3315
|
-
} = this.props;
|
|
3316
3407
|
const type = this.props.location.query.type;
|
|
3317
3408
|
const module = this.props.location.query.module;
|
|
3318
3409
|
const isLanguageSupport = (this.props.location.query.isLanguageSupport) ? this.props.location.query.isLanguageSupport : false;
|
|
@@ -3398,12 +3489,10 @@ return (<div>
|
|
|
3398
3489
|
}
|
|
3399
3490
|
if (this.isEnabledInLibraryModule("callSelectFromProps")) {
|
|
3400
3491
|
let data = id;
|
|
3401
|
-
if (
|
|
3402
|
-
data = template;
|
|
3403
|
-
} else if (fbAdManager || isDltFromRcs || isSmsFallbackFromRcs) {
|
|
3492
|
+
if (this.props.fbAdManager || this.props.isDltFromRcs) {
|
|
3404
3493
|
data = this.selectTemplate(id);
|
|
3405
3494
|
}
|
|
3406
|
-
onSelectTemplate(data, fbAdManager);
|
|
3495
|
+
this.props.onSelectTemplate(data, this.props.fbAdManager);
|
|
3407
3496
|
} else {
|
|
3408
3497
|
timeTracker.startTimer(CHANNEL_EDIT_TRACK_MAPPING[this.state.channel.toLowerCase()]);
|
|
3409
3498
|
if (this.state.channel.toLowerCase() === 'ebill') {
|
|
@@ -3492,6 +3581,33 @@ return (<div>
|
|
|
3492
3581
|
this.setState({showModal: false});
|
|
3493
3582
|
}
|
|
3494
3583
|
|
|
3584
|
+
// Shared helper for archive/unarchive confirm modals:
|
|
3585
|
+
// - no icon, lighter overlay, Confirm button on left (primary), Cancel on right
|
|
3586
|
+
showArchiveConfirm = ({ title, content, onConfirm, count = 1, isUnarchive = false }) => {
|
|
3587
|
+
const { intl } = this.props;
|
|
3588
|
+
const confirmText = intl.formatMessage(messages.archiveConfirmOk);
|
|
3589
|
+
const cancelText = intl.formatMessage(messages.archiveConfirmCancel);
|
|
3590
|
+
// Derive content from count if not explicitly provided
|
|
3591
|
+
const resolvedContent = content || (isUnarchive
|
|
3592
|
+
? intl.formatMessage(count > 1 ? messages.unarchiveTemplateContent : messages.unarchiveTemplateSingleContent)
|
|
3593
|
+
: intl.formatMessage(count > 1 ? messages.archiveTemplateContent : messages.archiveTemplateSingleContent));
|
|
3594
|
+
// AntD v3 footer order is [cancelButton][okButton]. Swap text+handler so
|
|
3595
|
+
// "Confirm" (primary) appears on the left and "Cancel" (default) on the right.
|
|
3596
|
+
CapModal.confirm({
|
|
3597
|
+
title,
|
|
3598
|
+
content: resolvedContent,
|
|
3599
|
+
icon: ' ',
|
|
3600
|
+
className: 'archive-confirm-modal',
|
|
3601
|
+
maskStyle: { backgroundColor: 'rgba(0, 0, 0, 0.25)' },
|
|
3602
|
+
cancelText: confirmText,
|
|
3603
|
+
okText: cancelText,
|
|
3604
|
+
cancelButtonProps: { type: 'primary' },
|
|
3605
|
+
okButtonProps: { type: 'default' },
|
|
3606
|
+
onCancel: (close) => { onConfirm(); close(); },
|
|
3607
|
+
// onOk (the right "Cancel" button) just closes the modal — default behaviour
|
|
3608
|
+
});
|
|
3609
|
+
}
|
|
3610
|
+
|
|
3495
3611
|
populateTemplatesList = (data, blankTemplateRequired, layoutSelection) => {
|
|
3496
3612
|
if (!data) {
|
|
3497
3613
|
return [];
|
|
@@ -3641,20 +3757,78 @@ return (<div>
|
|
|
3641
3757
|
deleteOption = this.props.intl.formatMessage(messages.unMapButton);
|
|
3642
3758
|
}
|
|
3643
3759
|
if (!layoutSelection) {
|
|
3760
|
+
// Determine archive eligibility for this template:
|
|
3761
|
+
// - Zalo: never eligible
|
|
3762
|
+
// - WhatsApp: not eligible when status is awaitingApproval / pending / unsubmitted
|
|
3763
|
+
// - RCS: not eligible when status is awaitingApproval / pending
|
|
3764
|
+
const templateWhatsappStatus = get(template, `versions.base.content.${WHATSAPP_LOWERCASE}.status`, '');
|
|
3765
|
+
const templateRcsStatus = get(template, 'versions.base.content.RCS.rcsContent.cardContent[0].Status', '');
|
|
3766
|
+
const channelUpCase = this.state.channel.toUpperCase();
|
|
3767
|
+
const isTemplateArchiveEligible = channelUpCase !== ZALO &&
|
|
3768
|
+
!(channelUpCase === WHATSAPP && [WHATSAPP_STATUSES.awaitingApproval, WHATSAPP_STATUSES.pending, WHATSAPP_STATUSES.unsubmitted].includes(templateWhatsappStatus)) &&
|
|
3769
|
+
!(channelUpCase === RCS && [RCS_STATUSES.awaitingApproval, RCS_STATUSES.pending].includes(templateRcsStatus));
|
|
3770
|
+
|
|
3771
|
+
// Checkbox on card header (full mode only, only for archive-eligible templates)
|
|
3772
|
+
if (this.props.isFullMode && this.props.location.query.type !== 'embedded' && isTemplateArchiveEligible) {
|
|
3773
|
+
const selectedIds = get(this.props, 'Templates.selectedTemplateIds', []);
|
|
3774
|
+
const selectedIdsArray = selectedIds.toJS ? selectedIds.toJS() : selectedIds;
|
|
3775
|
+
temp.cardTop = (
|
|
3776
|
+
<div className="template-card-top-bar">
|
|
3777
|
+
<CapCheckbox
|
|
3778
|
+
checked={selectedIdsArray.includes(template._id)}
|
|
3779
|
+
onChange={() => this.props.actions.toggleTemplateSelection(template._id)}
|
|
3780
|
+
onClick={(e) => e.stopPropagation()}
|
|
3781
|
+
/>
|
|
3782
|
+
</div>
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3644
3786
|
temp.footer = (
|
|
3645
3787
|
<div className="footer-container">
|
|
3646
3788
|
<div className="card-title">
|
|
3647
3789
|
<span className="template-name" style={{ fontWeight: `${this.state.channel.toLowerCase() === 'wechat' ? '400' : '600'}` }}>
|
|
3648
3790
|
{ template && template.versions && template.versions.history && template.versions.history.length > 1 && this.state.channel.toLowerCase() !== 'mobilepush' && <i style={{fontSize: '16px', margin: '0 8px 0 0', verticalAlign: 'middle'}} className="material-icons">filter_none</i>}
|
|
3649
3791
|
{template?.name}
|
|
3792
|
+
{template.isArchived && <CapColoredTag tagColor={CAP_G08} tagTextColor={CAP_G05} className="archived-tag">{this.props.intl.formatMessage(messages.archivedTag)}</CapColoredTag>}
|
|
3650
3793
|
</span>
|
|
3651
3794
|
{this.props.location.query.type !== 'embedded' && <CapPopover
|
|
3652
3795
|
trigger="click"
|
|
3653
3796
|
content={
|
|
3654
3797
|
<div className="popover-content">
|
|
3655
|
-
{this.state.channel !== 'wechat' && <div className="popover-action-container">
|
|
3798
|
+
{this.state.channel !== 'wechat' && !template.isArchived && <div className="popover-action-container">
|
|
3656
3799
|
<span onClick={() => this.duplicateTemplate(template)} className="popover-action" style={{cursor: 'pointer', padding: '8px 0px'}}>{this.props.intl.formatMessage(messages.duplicateButton)}</span>
|
|
3657
3800
|
</div>}
|
|
3801
|
+
{this.props.isFullMode && isTemplateArchiveEligible && !template.isArchived && <div className="popover-action-container">
|
|
3802
|
+
<span
|
|
3803
|
+
onClick={() => {
|
|
3804
|
+
this.showArchiveConfirm({
|
|
3805
|
+
title: this.props.intl.formatMessage(messages.archiveTemplates),
|
|
3806
|
+
onConfirm: () => this.props.actions.archiveTemplate(this.state.channel, template._id, template.name),
|
|
3807
|
+
count: 1,
|
|
3808
|
+
});
|
|
3809
|
+
}}
|
|
3810
|
+
className="popover-action popover-archive-action"
|
|
3811
|
+
>
|
|
3812
|
+
<CapIcon type="archive" size="l" />
|
|
3813
|
+
{this.props.intl.formatMessage(messages.archiveButton)}
|
|
3814
|
+
</span>
|
|
3815
|
+
</div>}
|
|
3816
|
+
{this.props.isFullMode && isTemplateArchiveEligible && template.isArchived && <div className="popover-action-container">
|
|
3817
|
+
<span
|
|
3818
|
+
onClick={() => {
|
|
3819
|
+
this.showArchiveConfirm({
|
|
3820
|
+
title: this.props.intl.formatMessage(messages.unarchiveTemplates),
|
|
3821
|
+
onConfirm: () => this.props.actions.unarchiveTemplate(this.state.channel, template._id, template.name),
|
|
3822
|
+
count: 1,
|
|
3823
|
+
isUnarchive: true,
|
|
3824
|
+
});
|
|
3825
|
+
}}
|
|
3826
|
+
className="popover-action popover-archive-action"
|
|
3827
|
+
>
|
|
3828
|
+
<CapIcon type="archive" size="l" />
|
|
3829
|
+
{this.props.intl.formatMessage(messages.unarchiveButton)}
|
|
3830
|
+
</span>
|
|
3831
|
+
</div>}
|
|
3658
3832
|
<div className="popover-action-container">
|
|
3659
3833
|
<span onClick={() => this.toggleDeleteTemplateModal(template)} className="popover-action" style={{cursor: 'pointer', padding: '8px 0px'}}>{deleteOption}</span>
|
|
3660
3834
|
</div>
|
|
@@ -4219,14 +4393,9 @@ return (<div>
|
|
|
4219
4393
|
const isWechatEmbedded = !this.props.isFullMode && channel.toUpperCase() === WECHAT;
|
|
4220
4394
|
const channelLowerCase = (channel || '').toLowerCase();
|
|
4221
4395
|
const isTraiDltFeature = this.checkDLTfeatureEnable();
|
|
4396
|
+
|
|
4222
4397
|
const createButton =
|
|
4223
|
-
(
|
|
4224
|
-
(
|
|
4225
|
-
channelLowerCase === WHATSAPP_LOWERCASE
|
|
4226
|
-
|| channelLowerCase === RCS_LOWERCASE
|
|
4227
|
-
)
|
|
4228
|
-
&& !this.props.isFullMode
|
|
4229
|
-
)
|
|
4398
|
+
( (channelLowerCase === WHATSAPP_LOWERCASE || channelLowerCase === RCS_LOWERCASE) && !this.props.isFullMode )
|
|
4230
4399
|
? (
|
|
4231
4400
|
<CapLink
|
|
4232
4401
|
onClick={this.openCreativesFullMode}
|
|
@@ -4252,23 +4421,22 @@ return (<div>
|
|
|
4252
4421
|
if (([WHATSAPP_LOWERCASE, ZALO_LOWERCASE, RCS_LOWERCASE].includes(this.state?.channel?.toLocaleLowerCase()) && isEmpty(this.state?.hostName))) {
|
|
4253
4422
|
isfilterContentVisisble = false;
|
|
4254
4423
|
}
|
|
4255
|
-
|
|
4256
|
-
const
|
|
4257
|
-
const
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
) : null}
|
|
4424
|
+
const _isArchivedMode = get(this.props, 'Templates.isArchivedMode', false);
|
|
4425
|
+
const _renderSelectedIds = get(this.props, 'Templates.selectedTemplateIds', []);
|
|
4426
|
+
const _renderSelectedIdsArray = _renderSelectedIds && typeof _renderSelectedIds.toJS === 'function' ? _renderSelectedIds.toJS() : (Array.isArray(_renderSelectedIds) ? _renderSelectedIds : []);
|
|
4427
|
+
const _renderHasSelection = this.props.isFullMode && _renderSelectedIdsArray.length > 0;
|
|
4428
|
+
|
|
4429
|
+
const filterContent = (( isfilterContentVisisble || [WECHAT, MOBILE_PUSH, INAPP].includes(this.state.channel.toUpperCase())) && <div className="action-container">
|
|
4430
|
+
{isfilterContentVisisble && <CapInput.Search
|
|
4431
|
+
className="search-text"
|
|
4432
|
+
style={{width: '210px'}}
|
|
4433
|
+
placeholder={_isArchivedMode ? this.props.intl.formatMessage(messages.searchArchivedTemplates) : this.props.intl.formatMessage(messages.searchText)}
|
|
4434
|
+
value={this.state.searchText}
|
|
4435
|
+
onChange={(e) => this.searchTemplate(e.target.value, this.state.channel)}
|
|
4436
|
+
disabled={this.checkSearchDisabled()}
|
|
4437
|
+
onClear={() => this.searchTemplate('', this.state.channel)}
|
|
4438
|
+
onScroll={(e) => e.stopPropagation()}
|
|
4439
|
+
/>}
|
|
4272
4440
|
{
|
|
4273
4441
|
channel.toUpperCase() === WECHAT && <CapRadio.CapRadioGroup className="wechat-filters" defaultValue={wechatFilter} onChange={this.setWechatFilter}>
|
|
4274
4442
|
<CapRadio.Button value={WECHAT_FILTERS.ALL}><CapLabel type="label2">
|
|
@@ -4414,27 +4582,46 @@ return (<div>
|
|
|
4414
4582
|
</div>
|
|
4415
4583
|
)
|
|
4416
4584
|
}
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
{
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4585
|
+
<div className="template-listing-header-actions">
|
|
4586
|
+
{!_isArchivedMode && !_renderHasSelection && (
|
|
4587
|
+
this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE && (isWhatsappCountExeeded) ? (
|
|
4588
|
+
<CapTooltip title={whatsappCountExceedText}>
|
|
4589
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
4590
|
+
{createButton}
|
|
4591
|
+
</div>
|
|
4592
|
+
</CapTooltip>
|
|
4593
|
+
)
|
|
4594
|
+
: isfilterContentVisisble && !isWechatEmbedded && !this.props.isDltFromRcs && createButton
|
|
4595
|
+
)}
|
|
4596
|
+
{/* More (⋯) menu: full mode only, not archived mode, not Zalo (no archive support), not when selection active */}
|
|
4597
|
+
{!_isArchivedMode && !_renderHasSelection && this.props.isFullMode && this.props.location.query.type !== 'embedded' && channelLowerCase !== ZALO_LOWERCASE && (
|
|
4598
|
+
<CapDropdown
|
|
4599
|
+
trigger={['click']}
|
|
4600
|
+
overlay={
|
|
4601
|
+
<CapMenu>
|
|
4602
|
+
<CapMenu.Item
|
|
4603
|
+
key="archived"
|
|
4604
|
+
onClick={() => {
|
|
4605
|
+
this.props.actions.setArchivedMode(true);
|
|
4606
|
+
this.setState({ searchText: '', page: 1 }, () => {
|
|
4607
|
+
const params = { name: '', sortBy: this.state.sortBy, archiveStatus: 'archived' };
|
|
4608
|
+
this.getAllTemplates({ params, resetPage: true }, true);
|
|
4609
|
+
});
|
|
4610
|
+
}}
|
|
4611
|
+
>
|
|
4612
|
+
<FormattedMessage {...messages.archivedTemplates} />
|
|
4613
|
+
</CapMenu.Item>
|
|
4614
|
+
</CapMenu>
|
|
4429
4615
|
}
|
|
4430
|
-
|
|
4431
|
-
|
|
4616
|
+
placement="bottomRight"
|
|
4617
|
+
>
|
|
4618
|
+
<CapButton type="flat" className="template-listing-more-btn">
|
|
4619
|
+
<CapIcon type="more" />
|
|
4620
|
+
</CapButton>
|
|
4621
|
+
</CapDropdown>
|
|
4622
|
+
)}
|
|
4432
4623
|
</div>
|
|
4433
|
-
)
|
|
4434
|
-
const localTemplatesFilterContent = get(this.props, 'localTemplatesConfig.localTemplatesFilterContent', null);
|
|
4435
|
-
const filterContent = (useLocalTemplates && localTemplatesFilterContent) != null
|
|
4436
|
-
? localTemplatesFilterContent
|
|
4437
|
-
: builtFilterContent;
|
|
4624
|
+
</div>);
|
|
4438
4625
|
let htmlPreviewContent = "";
|
|
4439
4626
|
if (this.state.channel.toLowerCase() === 'ebill') {
|
|
4440
4627
|
htmlPreviewContent = this.state.previewTemplate && this.state.previewTemplate.versions && this.state.previewTemplate.versions.base && this.state.previewTemplate.versions.base['ebill-editor'];
|
|
@@ -4444,10 +4631,7 @@ return (<div>
|
|
|
4444
4631
|
|
|
4445
4632
|
|
|
4446
4633
|
const creativesParams = this.getCreativesParams();
|
|
4447
|
-
const templates =
|
|
4448
|
-
? (this.props.localTemplatesConfig?.localTemplates || [])
|
|
4449
|
-
: (this.props.TemplatesList || []);
|
|
4450
|
-
const isLoadingWhenLocal = useLocalTemplates && !!this.props.localTemplatesConfig?.localTemplatesLoading;
|
|
4634
|
+
const templates = this.props.TemplatesList || [];
|
|
4451
4635
|
const {route} = this.props;
|
|
4452
4636
|
const loadingTipMap = {
|
|
4453
4637
|
sendingFile: 'uploadingFile',
|
|
@@ -4462,11 +4646,9 @@ return (<div>
|
|
|
4462
4646
|
(deleteRcsTemplateInProgress && 'deletingTemplate') ||
|
|
4463
4647
|
(this.props.EmailCreate.duplicateTemplateInProgress && 'duplicatingTemplate');
|
|
4464
4648
|
|
|
4465
|
-
const loadingTip =
|
|
4466
|
-
? this.props.localTemplatesConfig.localTemplatesLoadingTip
|
|
4467
|
-
: (messages[loadingTipIntl] ? this.props.intl.formatMessage(messages[loadingTipIntl]) : this.props.intl.formatMessage(messages.gettingAllTemplates));
|
|
4649
|
+
const loadingTip = messages[loadingTipIntl] ? this.props.intl.formatMessage(messages[loadingTipIntl]) : this.props.intl.formatMessage(messages.gettingAllTemplates);
|
|
4468
4650
|
const showNoTemplatesFoundZalo = this.state.channel.toUpperCase() === ZALO && isEmpty(this.state.searchedZaloTemplates) && this.state.searchingZaloTemplate;
|
|
4469
|
-
const showNoTemplatesFoundOther = ![ZALO].includes(this.state.channel.toUpperCase()) && isEmpty(
|
|
4651
|
+
const showNoTemplatesFoundOther = ![ZALO].includes(this.state.channel.toUpperCase()) && isEmpty(this.props.TemplatesList) && !this.props.Templates.getAllTemplatesInProgress && !isEmpty(this.state.searchText);
|
|
4470
4652
|
const showNoTemplatesFound = showNoTemplatesFoundZalo || showNoTemplatesFoundOther;
|
|
4471
4653
|
|
|
4472
4654
|
return (
|
|
@@ -4487,6 +4669,24 @@ return (<div>
|
|
|
4487
4669
|
}
|
|
4488
4670
|
/>
|
|
4489
4671
|
|
|
4672
|
+
{/* Archived mode header with back arrow (full mode only) */}
|
|
4673
|
+
{this.props.isFullMode && get(this.props, 'Templates.isArchivedMode', false) && (
|
|
4674
|
+
<CapRow type="flex" align="middle" className="archived-mode-header">
|
|
4675
|
+
<CapIcon
|
|
4676
|
+
type="back"
|
|
4677
|
+
className="archived-mode-back-icon"
|
|
4678
|
+
onClick={() => {
|
|
4679
|
+
this.props.actions.setArchivedMode(false);
|
|
4680
|
+
this.setState({ searchText: '', page: 1 }, () => {
|
|
4681
|
+
const params = { name: '', sortBy: this.state.sortBy, archiveStatus: 'active' };
|
|
4682
|
+
this.getAllTemplates({ params, resetPage: true }, true);
|
|
4683
|
+
});
|
|
4684
|
+
}}
|
|
4685
|
+
/>
|
|
4686
|
+
<CapHeading type="h3"><FormattedMessage {...messages.archivedTemplates} /></CapHeading>
|
|
4687
|
+
</CapRow>
|
|
4688
|
+
)}
|
|
4689
|
+
|
|
4490
4690
|
{channel.toLowerCase() === WHATSAPP_LOWERCASE &&
|
|
4491
4691
|
showWhatsappCountWarning ? (
|
|
4492
4692
|
<CapAlert message={whatsappCountExceedText} type="info" />
|
|
@@ -4498,7 +4698,7 @@ return (<div>
|
|
|
4498
4698
|
/>
|
|
4499
4699
|
) : null}
|
|
4500
4700
|
|
|
4501
|
-
{channel.toLowerCase() === RCS_LOWERCASE && !isFullMode
|
|
4701
|
+
{channel.toLowerCase() === RCS_LOWERCASE && !isFullMode ? (
|
|
4502
4702
|
<CapInfoNote
|
|
4503
4703
|
message={formatMessage(messages.rcsOnlyApprovedTemplates)}
|
|
4504
4704
|
/>
|
|
@@ -4511,22 +4711,22 @@ return (<div>
|
|
|
4511
4711
|
) : null}
|
|
4512
4712
|
<CapRow>
|
|
4513
4713
|
<Pagination
|
|
4514
|
-
templateInProgress={
|
|
4714
|
+
templateInProgress={
|
|
4715
|
+
this.props.Templates.getAllTemplatesInProgress
|
|
4716
|
+
}
|
|
4515
4717
|
onPageChange={
|
|
4516
|
-
templates.length
|
|
4517
|
-
? (useLocalTemplates ? (this.props.localTemplatesConfig?.localTemplatesOnPageChange || (() => {})) : this.onPaginationChange)
|
|
4518
|
-
: () => {}
|
|
4718
|
+
templates.length ? this.onPaginationChange : () => {}
|
|
4519
4719
|
}
|
|
4520
4720
|
>
|
|
4521
4721
|
{this.getTemplateDataForGrid({
|
|
4522
4722
|
previewTemplateId: this.state.zaloPreviewItemId,
|
|
4523
|
-
isLoading
|
|
4524
|
-
isInitialLoading
|
|
4723
|
+
isLoading,
|
|
4724
|
+
isInitialLoading,
|
|
4525
4725
|
loadingTip,
|
|
4526
4726
|
channel: this.state.channel,
|
|
4527
4727
|
templates: this.state.searchingZaloTemplate
|
|
4528
4728
|
? this.state.searchedZaloTemplates
|
|
4529
|
-
:
|
|
4729
|
+
: this.props.TemplatesList,
|
|
4530
4730
|
filterContent,
|
|
4531
4731
|
handlers: {
|
|
4532
4732
|
handlePreviewClick: this.handlePreviewClick,
|
|
@@ -4709,15 +4909,6 @@ Templates.propTypes = {
|
|
|
4709
4909
|
WebPush: PropTypes.object,
|
|
4710
4910
|
smsRegister: PropTypes.any,
|
|
4711
4911
|
isDltFromRcs: PropTypes.bool,
|
|
4712
|
-
isSmsFallbackFromRcs: PropTypes.bool,
|
|
4713
|
-
localTemplatesConfig: PropTypes.shape({
|
|
4714
|
-
useLocalTemplates: PropTypes.bool,
|
|
4715
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
4716
|
-
localTemplatesLoading: PropTypes.bool,
|
|
4717
|
-
localTemplatesLoadingTip: PropTypes.string,
|
|
4718
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
4719
|
-
localTemplatesOnPageChange: PropTypes.func,
|
|
4720
|
-
}),
|
|
4721
4912
|
};
|
|
4722
4913
|
|
|
4723
4914
|
const mapStateToProps = createStructuredSelector({
|