@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
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import {
|
|
4
|
+
CAP_SPACE_16, CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64,
|
|
5
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
6
|
+
|
|
3
7
|
import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
|
|
4
8
|
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
5
9
|
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
@@ -9,11 +13,12 @@ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
|
9
13
|
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
10
14
|
import classnames from 'classnames';
|
|
11
15
|
import {
|
|
12
|
-
isEmpty, get, forEach, cloneDeep, debounce,
|
|
16
|
+
isEmpty, get, forEach, cloneDeep, debounce,
|
|
13
17
|
} from 'lodash';
|
|
14
18
|
import { connect } from 'react-redux';
|
|
15
19
|
import { createStructuredSelector } from 'reselect';
|
|
16
20
|
import { bindActionCreators, compose } from 'redux';
|
|
21
|
+
import styled from 'styled-components';
|
|
17
22
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
18
23
|
import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
|
|
19
24
|
|
|
@@ -27,7 +32,6 @@ import SlideBoxContent from './SlideBoxContent';
|
|
|
27
32
|
import * as constants from './constants';
|
|
28
33
|
import * as commonUtil from '../../utils/common';
|
|
29
34
|
import { gtmPush } from '../../utils/gtmTrackers';
|
|
30
|
-
import { normalizeRcsMessageContentForApi } from '../../utils/rcsPayloadUtils';
|
|
31
35
|
import './index.scss';
|
|
32
36
|
import * as templateActions from '../Templates/actions';
|
|
33
37
|
import * as globalActions from '../Cap/actions';
|
|
@@ -43,9 +47,6 @@ import {
|
|
|
43
47
|
import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
|
|
44
48
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
45
49
|
import { RCS_STATUSES } from '../Rcs/constants';
|
|
46
|
-
import { mapRcsCardContentForConsumerWithResolvedTags } from '../Rcs/utils';
|
|
47
|
-
import { pickRcsCardVarMappedEntries } from '../Rcs/rcsLibraryHydrationUtils';
|
|
48
|
-
import { RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../../v2Components/CommonTestAndPreview/constants';
|
|
49
50
|
import { CREATIVE } from '../Facebook/constants';
|
|
50
51
|
import { LOYALTY } from '../App/constants';
|
|
51
52
|
import {
|
|
@@ -60,11 +61,6 @@ import { capSagaForFetchSchemaForEntity, capSagaLiquidEntity } from '../Cap/saga
|
|
|
60
61
|
import { v2TemplateSagaWatchGetDefaultBeeTemplates } from '../Templates/sagas';
|
|
61
62
|
import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
|
|
62
63
|
import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
|
|
63
|
-
import SlideBoxWrapper from './CreativesSlideBoxWrapper';
|
|
64
|
-
import {
|
|
65
|
-
computeLiquidFooterUpdateFromFormBuilder,
|
|
66
|
-
getSlideBoxWrapperMarginFromLiquidErrors,
|
|
67
|
-
} from './embeddedSlideboxUtils';
|
|
68
64
|
|
|
69
65
|
import {
|
|
70
66
|
transformChannelPayload,
|
|
@@ -73,24 +69,51 @@ import {
|
|
|
73
69
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
74
70
|
import { BIG_HTML } from '../InApp/constants';
|
|
75
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if value is "deep empty": no errors present.
|
|
74
|
+
* - null/undefined: empty
|
|
75
|
+
* - string: empty if length === 0
|
|
76
|
+
* - array: empty if length === 0
|
|
77
|
+
* - plain object (e.g. { android: [], ios: [], generic: [] }): empty only if every value is deep-empty
|
|
78
|
+
*/
|
|
79
|
+
function isDeepEmpty(value) {
|
|
80
|
+
if (value == null) return true;
|
|
81
|
+
if (typeof value === 'string') return value.length === 0;
|
|
82
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
83
|
+
if (typeof value === 'object') {
|
|
84
|
+
return Object.values(value).every(isDeepEmpty);
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
76
89
|
const classPrefix = 'add-creatives-section';
|
|
77
90
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
78
91
|
|
|
92
|
+
const SlideBoxWrapper = styled.div`
|
|
93
|
+
.cap-slide-box-v2-container{
|
|
94
|
+
.slidebox-header, .slidebox-content-container{
|
|
95
|
+
margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
|
|
96
|
+
padding: 0 rem;
|
|
97
|
+
&.has-footer{
|
|
98
|
+
overflow-x: hidden;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
.slidebox-footer{
|
|
102
|
+
/* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
|
|
103
|
+
/* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
|
|
104
|
+
margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
|
|
105
|
+
padding: 0 rem;
|
|
106
|
+
&.has-footer{
|
|
107
|
+
overflow-x: hidden;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
79
112
|
export class Creatives extends React.Component {
|
|
80
113
|
constructor(props) {
|
|
81
114
|
super(props);
|
|
82
115
|
|
|
83
|
-
const
|
|
84
|
-
props,
|
|
85
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
86
|
-
get(props, 'useLocalTemplates', false),
|
|
87
|
-
);
|
|
88
|
-
const initialSlidBoxContent = this.getSlideBoxContent({
|
|
89
|
-
mode: props.creativesMode,
|
|
90
|
-
templateData: props.templateData,
|
|
91
|
-
isFullMode: props.isFullMode,
|
|
92
|
-
useLocalTemplates,
|
|
93
|
-
});
|
|
116
|
+
const initialSlidBoxContent = this.getSlideBoxContent({ mode: props.creativesMode, templateData: props.templateData, isFullMode: props.isFullMode });
|
|
94
117
|
|
|
95
118
|
this.state = {
|
|
96
119
|
isLoadingContent: true,
|
|
@@ -137,13 +160,7 @@ export class Creatives extends React.Component {
|
|
|
137
160
|
}
|
|
138
161
|
|
|
139
162
|
componentWillUnmount() {
|
|
140
|
-
|
|
141
|
-
const useLocalTemplates = get(
|
|
142
|
-
this.props,
|
|
143
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
144
|
-
get(this.props, 'useLocalTemplates', false),
|
|
145
|
-
);
|
|
146
|
-
if (isEmbedded && !useLocalTemplates) {
|
|
163
|
+
if (get(this.props, 'location.query.type', '') === "embedded") {
|
|
147
164
|
this.props.templateActions.resetTemplateStoreData();
|
|
148
165
|
}
|
|
149
166
|
this.props.globalActions.clearMetaEntities();
|
|
@@ -243,6 +260,10 @@ export class Creatives extends React.Component {
|
|
|
243
260
|
};
|
|
244
261
|
|
|
245
262
|
onEditTemplate = () => {
|
|
263
|
+
if (this.props.templateData && this.props.templateData.isArchived) {
|
|
264
|
+
CapNotification.error({ message: this.props.intl.formatMessage(messages.cannotEditArchivedTemplate) });
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
246
267
|
this.setState({ slidBoxContent: 'editTemplate', showSlideBox: true, templateNameExists: true });
|
|
247
268
|
};
|
|
248
269
|
|
|
@@ -745,56 +766,25 @@ export class Creatives extends React.Component {
|
|
|
745
766
|
smsFallBackContent = {},
|
|
746
767
|
creativeName = "",
|
|
747
768
|
channel = constants.RCS,
|
|
748
|
-
|
|
769
|
+
accountId = "",
|
|
749
770
|
} = templateData || {};
|
|
750
|
-
const
|
|
751
|
-
const firstCardIn = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
752
|
-
const {
|
|
753
|
-
cardDisplayTitle: _omitDispTitleIn,
|
|
754
|
-
cardDisplayDescription: _omitDispDescIn,
|
|
755
|
-
...cardContent
|
|
756
|
-
} = firstCardIn;
|
|
771
|
+
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
757
772
|
const Status = RCS_STATUSES.approved || '';
|
|
758
|
-
const mergedCardVarMapped = (() => {
|
|
759
|
-
const nestedCardVarMapped = cardContent?.cardVarMapped;
|
|
760
|
-
const rootMirrorCardVarMapped = rcsCardVarMapped;
|
|
761
|
-
const nestedRecord =
|
|
762
|
-
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
763
|
-
? nestedCardVarMapped
|
|
764
|
-
: {};
|
|
765
|
-
const rootRecord =
|
|
766
|
-
rootMirrorCardVarMapped != null && typeof rootMirrorCardVarMapped === 'object'
|
|
767
|
-
? rootMirrorCardVarMapped
|
|
768
|
-
: {};
|
|
769
|
-
const mergedFromRootAndNested = {
|
|
770
|
-
...pickRcsCardVarMappedEntries(rootRecord),
|
|
771
|
-
...pickRcsCardVarMappedEntries(nestedRecord),
|
|
772
|
-
};
|
|
773
|
-
return Object.keys(mergedFromRootAndNested).length > 0
|
|
774
|
-
? mergedFromRootAndNested
|
|
775
|
-
: null;
|
|
776
|
-
})();
|
|
777
|
-
// Campaigns (embedded): do not duplicate `cardVarMapped` as root `rcsCardVarMapped` on send —
|
|
778
|
-
// slot map stays on `versions…cardContent[0].cardVarMapped` only. Library full mode keeps root mirror.
|
|
779
|
-
// Use `=== true` so omitted/undefined `isFullMode` does not behave like library (avoids duplicate on approval payload).
|
|
780
|
-
const includeRootRcsCardVarMapped =
|
|
781
|
-
mergedCardVarMapped && isFullModeForRcsPayload === true;
|
|
782
773
|
|
|
783
774
|
creativesTemplateData = {
|
|
784
775
|
type: channel,
|
|
785
776
|
edit: true,
|
|
786
777
|
name: creativeName,
|
|
787
|
-
...(includeRootRcsCardVarMapped ? { rcsCardVarMapped: mergedCardVarMapped } : {}),
|
|
788
778
|
versions: {
|
|
789
779
|
base: {
|
|
790
780
|
content: {
|
|
791
781
|
RCS: {
|
|
792
782
|
rcsContent: {
|
|
793
783
|
...rcsContent,
|
|
784
|
+
...(accountId && !isFullMode && { accountId }),
|
|
794
785
|
cardContent: [
|
|
795
786
|
{
|
|
796
787
|
...cardContent,
|
|
797
|
-
...(mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
798
788
|
Status,
|
|
799
789
|
},
|
|
800
790
|
],
|
|
@@ -945,10 +935,7 @@ export class Creatives extends React.Component {
|
|
|
945
935
|
return newExpandableDetails;
|
|
946
936
|
}
|
|
947
937
|
|
|
948
|
-
getCreativesData = async (
|
|
949
|
-
const channel = String(
|
|
950
|
-
channelParam || template?.type || get(template, 'value.type') || '',
|
|
951
|
-
).toUpperCase();
|
|
938
|
+
getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
|
|
952
939
|
let templateData = { channel };
|
|
953
940
|
switch (channel) {
|
|
954
941
|
case constants.SMS:
|
|
@@ -1242,7 +1229,7 @@ export class Creatives extends React.Component {
|
|
|
1242
1229
|
};
|
|
1243
1230
|
}
|
|
1244
1231
|
break;
|
|
1245
|
-
case constants.FACEBOOK:
|
|
1232
|
+
case constants.FACEBOOK:
|
|
1246
1233
|
if (template.value) {
|
|
1247
1234
|
const FacebookAd = template?.value?.versions?.base?.content?.FacebookAd;
|
|
1248
1235
|
const { type } = FacebookAd[0];
|
|
@@ -1286,110 +1273,34 @@ export class Creatives extends React.Component {
|
|
|
1286
1273
|
selectedMarketingObjective: template.value.selectedMarketingObjective,
|
|
1287
1274
|
};
|
|
1288
1275
|
}
|
|
1289
|
-
}
|
|
1290
1276
|
break;
|
|
1291
|
-
case constants.RCS:
|
|
1277
|
+
case constants.RCS:
|
|
1292
1278
|
if (template.value) {
|
|
1293
|
-
const {
|
|
1294
|
-
|
|
1295
|
-
const
|
|
1296
|
-
const fromRecords = {
|
|
1297
|
-
...(templateRecords?.smsFallBackContent || {}),
|
|
1298
|
-
...(get(templateRecords, 'versions.base.content.RCS.smsFallBackContent') || {}),
|
|
1299
|
-
};
|
|
1300
|
-
const hasMeaningfulRcsSmsFallback = (smsFallbackPayload) => {
|
|
1301
|
-
if (
|
|
1302
|
-
!smsFallbackPayload
|
|
1303
|
-
|| typeof smsFallbackPayload !== 'object'
|
|
1304
|
-
|| Object.keys(smsFallbackPayload).length === 0
|
|
1305
|
-
) {
|
|
1306
|
-
return false;
|
|
1307
|
-
}
|
|
1308
|
-
const fallbackBodyText = String(
|
|
1309
|
-
smsFallbackPayload.smsContent
|
|
1310
|
-
?? smsFallbackPayload.smsTemplateContent
|
|
1311
|
-
?? smsFallbackPayload.message
|
|
1312
|
-
?? smsFallbackPayload.content
|
|
1313
|
-
?? '',
|
|
1314
|
-
).trim();
|
|
1315
|
-
const fallbackTemplateName = String(
|
|
1316
|
-
smsFallbackPayload.smsTemplateName ?? smsFallbackPayload.templateName ?? '',
|
|
1317
|
-
).trim();
|
|
1318
|
-
const rcsSmsFallbackVarMapped =
|
|
1319
|
-
smsFallbackPayload?.[RCS_SMS_FALLBACK_VAR_MAPPED_PROP];
|
|
1320
|
-
const hasVarMappedEntries =
|
|
1321
|
-
rcsSmsFallbackVarMapped != null
|
|
1322
|
-
&& typeof rcsSmsFallbackVarMapped === 'object'
|
|
1323
|
-
&& Object.keys(rcsSmsFallbackVarMapped).length > 0;
|
|
1324
|
-
return (
|
|
1325
|
-
fallbackBodyText !== ''
|
|
1326
|
-
|| fallbackTemplateName !== ''
|
|
1327
|
-
|| hasVarMappedEntries
|
|
1328
|
-
);
|
|
1329
|
-
};
|
|
1330
|
-
// If submit has only empty strings, do not let it wipe fallback mirrored on templateRecords (library round-trip).
|
|
1331
|
-
const smsFallBackContent = hasMeaningfulRcsSmsFallback(fromSubmit)
|
|
1332
|
-
? { ...fromRecords, ...fromSubmit }
|
|
1333
|
-
: { ...fromSubmit, ...fromRecords };
|
|
1279
|
+
const { name = "", versions = {} } = {
|
|
1280
|
+
} = template.value || {};
|
|
1281
|
+
const smsFallBackContent = get(versions, 'base.content.RCS.smsFallBackContent', {});
|
|
1334
1282
|
const {
|
|
1335
|
-
cardContent
|
|
1283
|
+
cardContent = [],
|
|
1336
1284
|
contentType = "",
|
|
1337
1285
|
cardType = "",
|
|
1338
1286
|
cardSettings = {},
|
|
1287
|
+
accountId = "",
|
|
1339
1288
|
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1340
|
-
const rootRcsCardVarMappedFromSubmit = get(template, 'value.rcsCardVarMapped');
|
|
1341
|
-
const firstCardFromSubmit = Array.isArray(cardContentFromSubmit)
|
|
1342
|
-
? cardContentFromSubmit[0]
|
|
1343
|
-
: null;
|
|
1344
|
-
const cardContent = mapRcsCardContentForConsumerWithResolvedTags(
|
|
1345
|
-
cardContentFromSubmit,
|
|
1346
|
-
rootRcsCardVarMappedFromSubmit,
|
|
1347
|
-
isFullModeForRcsConsumerPayload,
|
|
1348
|
-
);
|
|
1349
1289
|
const rcsContent = {
|
|
1350
1290
|
contentType,
|
|
1351
1291
|
cardType,
|
|
1352
1292
|
cardSettings,
|
|
1353
1293
|
cardContent,
|
|
1354
1294
|
};
|
|
1355
|
-
const cardVarMappedFromFirstRcsCard =
|
|
1356
|
-
firstCardFromSubmit?.cardVarMapped != null
|
|
1357
|
-
&& typeof firstCardFromSubmit.cardVarMapped === 'object'
|
|
1358
|
-
? pickRcsCardVarMappedEntries(firstCardFromSubmit.cardVarMapped)
|
|
1359
|
-
: null;
|
|
1360
|
-
const includeRootRcsCardVarMappedOnConsumerPayload =
|
|
1361
|
-
cardVarMappedFromFirstRcsCard
|
|
1362
|
-
&& Object.keys(cardVarMappedFromFirstRcsCard).length > 0
|
|
1363
|
-
&& isFullModeForRcsConsumerPayload === true;
|
|
1364
1295
|
templateData = {
|
|
1365
1296
|
channel,
|
|
1366
1297
|
creativeName: name,
|
|
1367
1298
|
rcsContent,
|
|
1368
|
-
|
|
1369
|
-
? { rcsCardVarMapped: cardVarMappedFromFirstRcsCard }
|
|
1370
|
-
: {}),
|
|
1299
|
+
accountId,
|
|
1371
1300
|
};
|
|
1372
|
-
// Library / campaign consumers round-trip templateData via getTemplateData; include SMS fallback
|
|
1373
|
-
// so reopening the editor restores fallback text and tag mappings.
|
|
1374
|
-
// cap-campaigns-v2 API expects `smsFallBackContent.message` (see normalizeRcsMessageContentForApi).
|
|
1375
|
-
if (hasMeaningfulRcsSmsFallback(smsFallBackContent)) {
|
|
1376
|
-
const smsText =
|
|
1377
|
-
smsFallBackContent.message
|
|
1378
|
-
?? smsFallBackContent.smsContent
|
|
1379
|
-
?? smsFallBackContent.smsTemplateContent
|
|
1380
|
-
?? '';
|
|
1381
|
-
templateData.smsFallBackContent = {
|
|
1382
|
-
...smsFallBackContent,
|
|
1383
|
-
...(String(smsText).trim() !== ''
|
|
1384
|
-
? { message: String(smsText).trim() }
|
|
1385
|
-
: {}),
|
|
1386
|
-
};
|
|
1387
|
-
}
|
|
1388
|
-
normalizeRcsMessageContentForApi(templateData);
|
|
1389
1301
|
}
|
|
1390
|
-
}
|
|
1391
1302
|
break;
|
|
1392
|
-
case constants.ZALO:
|
|
1303
|
+
case constants.ZALO:
|
|
1393
1304
|
if (template.value) {
|
|
1394
1305
|
templateData = {
|
|
1395
1306
|
...template.value,
|
|
@@ -1398,7 +1309,6 @@ export class Creatives extends React.Component {
|
|
|
1398
1309
|
delete templateData.type;
|
|
1399
1310
|
}
|
|
1400
1311
|
}
|
|
1401
|
-
}
|
|
1402
1312
|
break;
|
|
1403
1313
|
case constants.WEBPUSH: {
|
|
1404
1314
|
if (template.value) {
|
|
@@ -1505,10 +1415,7 @@ export class Creatives extends React.Component {
|
|
|
1505
1415
|
return templateData;
|
|
1506
1416
|
};
|
|
1507
1417
|
|
|
1508
|
-
getSlideBoxContent({ mode, templateData, isFullMode
|
|
1509
|
-
if (useLocalTemplates && mode === 'create' && isEmpty(templateData)) {
|
|
1510
|
-
return 'templates';
|
|
1511
|
-
}
|
|
1418
|
+
getSlideBoxContent({ mode, templateData, isFullMode }) {
|
|
1512
1419
|
let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
|
|
1513
1420
|
if (mode === 'create' && isFullMode) {
|
|
1514
1421
|
creativesMode = 'createTemplate';
|
|
@@ -1596,110 +1503,24 @@ export class Creatives extends React.Component {
|
|
|
1596
1503
|
getFormData = (template) => {
|
|
1597
1504
|
// Always reset isGetFormData so the child does not re-send form data on every re-render
|
|
1598
1505
|
// (e.g. when user fixes validation error by typing, we must not auto-close the slidebox)
|
|
1599
|
-
this.setState(
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|| ''
|
|
1611
|
-
).toUpperCase();
|
|
1612
|
-
// Library mode: persist last submitted creatives shape so reopening still hydrates the editor
|
|
1613
|
-
// (parent may not merge getCreativesData back into templateData).
|
|
1614
|
-
if (this.props.isFullMode === false && template.value) {
|
|
1615
|
-
if (channel === constants.RCS) {
|
|
1616
|
-
const smsFallBackFromPayload = get(
|
|
1617
|
-
template.value,
|
|
1618
|
-
'versions.base.content.RCS.smsFallBackContent',
|
|
1619
|
-
);
|
|
1620
|
-
const rcsCardVarMappedFromPayload = get(
|
|
1621
|
-
template.value,
|
|
1622
|
-
'versions.base.content.RCS.rcsContent.cardContent[0].cardVarMapped',
|
|
1623
|
-
);
|
|
1624
|
-
next.templateData = {
|
|
1625
|
-
...baseTd,
|
|
1626
|
-
type: constants.RCS,
|
|
1627
|
-
name: template?.value?.name,
|
|
1628
|
-
versions: template?.value?.versions,
|
|
1629
|
-
...(smsFallBackFromPayload != null
|
|
1630
|
-
&& typeof smsFallBackFromPayload === 'object'
|
|
1631
|
-
&& Object.keys(smsFallBackFromPayload).length > 0
|
|
1632
|
-
? { smsFallBackContent: smsFallBackFromPayload }
|
|
1633
|
-
: {}),
|
|
1634
|
-
...(rcsCardVarMappedFromPayload != null
|
|
1635
|
-
&& typeof rcsCardVarMappedFromPayload === 'object'
|
|
1636
|
-
? { rcsCardVarMapped: rcsCardVarMappedFromPayload }
|
|
1637
|
-
: {}),
|
|
1638
|
-
};
|
|
1639
|
-
if (template._id) {
|
|
1640
|
-
next.templateData._id = template._id;
|
|
1641
|
-
}
|
|
1642
|
-
} else if (channel === constants.SMS) {
|
|
1643
|
-
const submittedSmsTemplateValue = template?.value;
|
|
1644
|
-
const smsVersions =
|
|
1645
|
-
submittedSmsTemplateValue?.history != null
|
|
1646
|
-
? submittedSmsTemplateValue
|
|
1647
|
-
: {
|
|
1648
|
-
base: submittedSmsTemplateValue?.base,
|
|
1649
|
-
history: submittedSmsTemplateValue?.base
|
|
1650
|
-
? [submittedSmsTemplateValue.base]
|
|
1651
|
-
: [],
|
|
1652
|
-
};
|
|
1653
|
-
next.templateData = {
|
|
1654
|
-
...baseTd,
|
|
1655
|
-
type: constants.SMS,
|
|
1656
|
-
name: baseTd?.name || 'Campaign message SMS content',
|
|
1657
|
-
versions: smsVersions,
|
|
1658
|
-
};
|
|
1659
|
-
if (template?._id) {
|
|
1660
|
-
next.templateData._id = template._id;
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
return next;
|
|
1665
|
-
},
|
|
1666
|
-
() => {
|
|
1667
|
-
if (!template.validity) {
|
|
1668
|
-
return;
|
|
1669
|
-
}
|
|
1670
|
-
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1671
|
-
const channelForConsumer = String(
|
|
1672
|
-
templateData.type
|
|
1673
|
-
|| template.type
|
|
1674
|
-
|| get(template, 'value.type')
|
|
1675
|
-
|| '',
|
|
1676
|
-
).toUpperCase();
|
|
1677
|
-
const creativesData = this.getCreativesData(
|
|
1678
|
-
channelForConsumer,
|
|
1679
|
-
template,
|
|
1680
|
-
this.state.templateData || template,
|
|
1681
|
-
);// convers data to consumer understandable format
|
|
1682
|
-
creativesData.then((data) => {
|
|
1683
|
-
this.logGTMEvent(channelForConsumer, data);
|
|
1684
|
-
this.processCentralCommsMetaId(channelForConsumer, data, {
|
|
1685
|
-
closeSlideBoxAfterSubmit: template.closeSlideBoxAfterSubmit,
|
|
1506
|
+
this.setState({ isGetFormData: false });
|
|
1507
|
+
if (template.validity) {
|
|
1508
|
+
this.setState(
|
|
1509
|
+
{},
|
|
1510
|
+
() => {
|
|
1511
|
+
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1512
|
+
const channel = templateData.type;
|
|
1513
|
+
const creativesData = this.getCreativesData(channel, template, templateData);// convers data to consumer understandable format
|
|
1514
|
+
creativesData.then((data) => {
|
|
1515
|
+
this.logGTMEvent(channel, data);
|
|
1516
|
+
this.processCentralCommsMetaId(channel, data);
|
|
1686
1517
|
});
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1518
|
+
},
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1690
1521
|
}
|
|
1691
1522
|
|
|
1692
|
-
processCentralCommsMetaId = (channel, creativesData
|
|
1693
|
-
const { closeSlideBoxAfterSubmit = false } = options;
|
|
1694
|
-
const maybeCloseLibrarySlideBox = () => {
|
|
1695
|
-
if (
|
|
1696
|
-
closeSlideBoxAfterSubmit
|
|
1697
|
-
&& this.props.isFullMode === false
|
|
1698
|
-
&& typeof this.handleCloseSlideBox === 'function'
|
|
1699
|
-
) {
|
|
1700
|
-
this.handleCloseSlideBox();
|
|
1701
|
-
}
|
|
1702
|
-
};
|
|
1523
|
+
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1703
1524
|
// Create the payload for the centralcommnsmetaId API call
|
|
1704
1525
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1705
1526
|
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
@@ -1725,7 +1546,6 @@ export class Creatives extends React.Component {
|
|
|
1725
1546
|
if (result?.status?.code === 200) {
|
|
1726
1547
|
setMetaData(result);
|
|
1727
1548
|
this.props.getCreativesData(creativesData);
|
|
1728
|
-
maybeCloseLibrarySlideBox();
|
|
1729
1549
|
} else {
|
|
1730
1550
|
CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
|
|
1731
1551
|
}
|
|
@@ -1736,7 +1556,6 @@ export class Creatives extends React.Component {
|
|
|
1736
1556
|
} else {
|
|
1737
1557
|
// If not a loyalty module or different action, should work as usual
|
|
1738
1558
|
this.props.getCreativesData(creativesData);
|
|
1739
|
-
maybeCloseLibrarySlideBox();
|
|
1740
1559
|
}
|
|
1741
1560
|
};
|
|
1742
1561
|
|
|
@@ -1769,9 +1588,7 @@ export class Creatives extends React.Component {
|
|
|
1769
1588
|
}
|
|
1770
1589
|
this.setState((prevState) => ({
|
|
1771
1590
|
...prevState,
|
|
1772
|
-
|
|
1773
|
-
// Undefined isFullMode defaults to full-mode close behavior (clear templateData).
|
|
1774
|
-
...(this.props.isFullMode !== false ? { templateData: undefined } : {}),
|
|
1591
|
+
templateData: undefined,
|
|
1775
1592
|
showSlideBox: false,
|
|
1776
1593
|
liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
|
|
1777
1594
|
isLiquidValidationError: false,
|
|
@@ -1982,12 +1799,21 @@ export class Creatives extends React.Component {
|
|
|
1982
1799
|
}
|
|
1983
1800
|
|
|
1984
1801
|
showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
|
|
1985
|
-
const
|
|
1986
|
-
|
|
1987
|
-
|
|
1802
|
+
const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
|
|
1803
|
+
const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
|
|
1804
|
+
const hasLiquid = !isDeepEmpty(liquidMsgs);
|
|
1805
|
+
const hasStandard = !isDeepEmpty(standardMsgs);
|
|
1806
|
+
const isLiquidValidationError = hasLiquid || hasStandard;
|
|
1807
|
+
// Don't overwrite existing liquid error with empty only for Mobile Push OLD (FormBuilder/clear calls empty there); SMS/others clear on input change
|
|
1808
|
+
const isMobilePush = this.state.currentChannel?.toUpperCase() === constants.MOBILE_PUSH;
|
|
1809
|
+
if (!hasLiquid && !hasStandard && this.state.isLiquidValidationError && isMobilePush) {
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
this.setState({
|
|
1813
|
+
isLiquidValidationError,
|
|
1814
|
+
liquidErrorMessage: errorMessagesFromFormBuilder,
|
|
1815
|
+
activeFormBuilderTab: currentFormBuilderTab === 1 ? constants.ANDROID : (currentFormBuilderTab === 2 ? constants.IOS : null), // Update activeFormBuilderTab, default to 1 if undefined
|
|
1988
1816
|
});
|
|
1989
|
-
if (next == null) return;
|
|
1990
|
-
this.setState(next);
|
|
1991
1817
|
}
|
|
1992
1818
|
|
|
1993
1819
|
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
@@ -2110,11 +1936,6 @@ export class Creatives extends React.Component {
|
|
|
2110
1936
|
inAppEditorType,
|
|
2111
1937
|
htmlEditorValidationState,
|
|
2112
1938
|
} = this.state;
|
|
2113
|
-
const useLocalTemplates = get(
|
|
2114
|
-
this.props,
|
|
2115
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
2116
|
-
get(this.props, 'useLocalTemplates', false),
|
|
2117
|
-
);
|
|
2118
1939
|
const {
|
|
2119
1940
|
isFullMode,
|
|
2120
1941
|
creativesMode,
|
|
@@ -2133,6 +1954,7 @@ export class Creatives extends React.Component {
|
|
|
2133
1954
|
smsRegister,
|
|
2134
1955
|
enableNewChannels,
|
|
2135
1956
|
eventContextTags,
|
|
1957
|
+
waitEventContextTags = {},
|
|
2136
1958
|
isLoyaltyModule,
|
|
2137
1959
|
loyaltyMetaData = {},
|
|
2138
1960
|
} = this.props;
|
|
@@ -2166,7 +1988,14 @@ export class Creatives extends React.Component {
|
|
|
2166
1988
|
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
2167
1989
|
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
2168
1990
|
|
|
2169
|
-
|
|
1991
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
1992
|
+
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
1993
|
+
? CAP_SPACE_64
|
|
1994
|
+
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
1995
|
+
? CAP_SPACE_56
|
|
1996
|
+
: get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
1997
|
+
? CAP_SPACE_32
|
|
1998
|
+
: 0;
|
|
2170
1999
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
2171
2000
|
|
|
2172
2001
|
// Compute anonymous user type and channel restrictions
|
|
@@ -2195,10 +2024,7 @@ export class Creatives extends React.Component {
|
|
|
2195
2024
|
<SlideBoxWrapper
|
|
2196
2025
|
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
2197
2026
|
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
2198
|
-
className={classnames(
|
|
2199
|
-
`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`,
|
|
2200
|
-
useLocalTemplates && slidBoxContent === 'templates' && 'creatives-slidebox--local-sms-templates',
|
|
2201
|
-
)}
|
|
2027
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
2202
2028
|
>
|
|
2203
2029
|
<CapSlideBox
|
|
2204
2030
|
header={
|
|
@@ -2223,13 +2049,12 @@ export class Creatives extends React.Component {
|
|
|
2223
2049
|
smsRegister={smsRegister}
|
|
2224
2050
|
handleClose={this.handleCloseSlideBox}
|
|
2225
2051
|
moduleType={this.props.messageDetails?.type}
|
|
2226
|
-
useLocalTemplates={useLocalTemplates}
|
|
2227
2052
|
/>
|
|
2228
2053
|
)}
|
|
2229
2054
|
content={(
|
|
2230
2055
|
<SlideBoxContent
|
|
2231
2056
|
key="creatives-container-slidebox-content"
|
|
2232
|
-
onSelectTemplate={this.
|
|
2057
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
2233
2058
|
onCreateComplete={getCreativesData}
|
|
2234
2059
|
onPreviewTemplate={this.onPreviewTemplate}
|
|
2235
2060
|
slidBoxContent={slidBoxContent}
|
|
@@ -2297,6 +2122,7 @@ export class Creatives extends React.Component {
|
|
|
2297
2122
|
creativesMode={creativesMode} // An existing prop that we're using here. Required to ensure correct account details in Edit or Preview in case of Embedded mode.
|
|
2298
2123
|
hostName={this.props?.hostName || ''}
|
|
2299
2124
|
eventContextTags={eventContextTags}
|
|
2125
|
+
waitEventContextTags={waitEventContextTags}
|
|
2300
2126
|
isLoyaltyModule={isLoyaltyModule}
|
|
2301
2127
|
loyaltyMetaData={loyaltyMetaData}
|
|
2302
2128
|
showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
|
|
@@ -2305,8 +2131,7 @@ export class Creatives extends React.Component {
|
|
|
2305
2131
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2306
2132
|
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
2307
2133
|
onPersonalizationTokensChange={this.handlePersonalizationTokensChange}
|
|
2308
|
-
|
|
2309
|
-
/>
|
|
2134
|
+
/>
|
|
2310
2135
|
)}
|
|
2311
2136
|
footer={this.shouldShowFooter() ? (
|
|
2312
2137
|
<SlideBoxFooter
|
|
@@ -2315,6 +2140,7 @@ export class Creatives extends React.Component {
|
|
|
2315
2140
|
onSave={this.saveMessage}
|
|
2316
2141
|
onDiscard={this.discardMessage}
|
|
2317
2142
|
onEditTemplate={this.onEditTemplate}
|
|
2143
|
+
isTemplateArchived={!!(this.props.templateData && this.props.templateData.isArchived)}
|
|
2318
2144
|
slidBoxContent={slidBoxContent}
|
|
2319
2145
|
onCreateNextStep={this.onCreateNextStep}
|
|
2320
2146
|
currentChannel={currentChannel.toUpperCase()}
|
|
@@ -2390,31 +2216,13 @@ Creatives.propTypes = {
|
|
|
2390
2216
|
orgUnitId: PropTypes.number,
|
|
2391
2217
|
hostName: PropTypes.string,
|
|
2392
2218
|
eventContextTags: PropTypes.array,
|
|
2219
|
+
waitEventContextTags: PropTypes.object,
|
|
2393
2220
|
loyaltyTagFetchingDependencies: PropTypes.object,
|
|
2394
2221
|
customerType: PropTypes.string,
|
|
2395
2222
|
intl: PropTypes.shape({
|
|
2396
2223
|
formatMessage: PropTypes.func,
|
|
2397
2224
|
}),
|
|
2398
2225
|
stopValidation: PropTypes.func,
|
|
2399
|
-
// Local template list (e.g. for SMS fallback): when set, TemplatesV2 uses these instead of Redux.
|
|
2400
|
-
// All optional. Pass either localTemplatesConfig (object) or individual props below.
|
|
2401
|
-
localTemplatesConfig: PropTypes.shape({
|
|
2402
|
-
useLocalTemplates: PropTypes.bool,
|
|
2403
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2404
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2405
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2406
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2407
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2408
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2409
|
-
}),
|
|
2410
|
-
useLocalTemplates: PropTypes.bool,
|
|
2411
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2412
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2413
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2414
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2415
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2416
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2417
|
-
onSelectTemplate: PropTypes.func,
|
|
2418
2226
|
};
|
|
2419
2227
|
const mapStatesToProps = () => createStructuredSelector({
|
|
2420
2228
|
isLoading: isLoadingSelector(),
|