@capillarytech/creatives-library 9.0.15-alpha.3 → 9.0.16-beta.0
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/AppRoot.js +80 -0
- package/app.js +5 -3
- package/constants/unified.js +0 -29
- package/entry.js +67 -1
- package/global-styles.js +1 -1
- package/mfe-exposed-components.js +2 -4
- package/package.json +2 -2
- package/services/api.js +1 -1
- package/services/tests/api.test.js +20 -35
- package/styles/containers/layout/_layoutPage.scss +8 -6
- package/utils/commonUtils.js +1 -19
- package/utils/getDataLayer.js +15 -0
- package/utils/gtmTrackers/gtmEvents/creativeDetails.js +2 -1
- package/utils/mfeDetect.js +1 -0
- package/v2Components/CapActionButton/constants.js +1 -8
- package/v2Components/CapActionButton/index.js +144 -202
- package/v2Components/CapActionButton/index.scss +14 -232
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +18 -42
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +48 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -214
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +9 -83
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -60
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +22 -202
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +80 -381
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +8 -155
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +222 -761
- package/v2Components/CommonTestAndPreview/messages.js +3 -45
- package/v2Components/CommonTestAndPreview/sagas.js +6 -25
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -1
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +267 -284
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -133
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +24 -31
- package/v2Components/NavigationBar/index.js +9 -7
- package/v2Components/NavigationBar/mfeModuleHeader.config.js +16 -0
- package/v2Components/Pagination/_pagination.scss +2 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +25 -45
- package/v2Components/TemplatePreview/index.js +32 -147
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/Cap/constants.js +1 -0
- package/v2Containers/Cap/index.js +47 -21
- package/v2Containers/Cap/sagas.js +19 -0
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +1 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +0 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
- package/v2Containers/CreativesContainer/SlideBoxContent.js +7 -37
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +5 -14
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +5 -36
- package/v2Containers/CreativesContainer/constants.js +0 -11
- package/v2Containers/CreativesContainer/index.js +104 -323
- package/v2Containers/CreativesContainer/index.scss +1 -83
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +90 -333
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +11 -131
- package/v2Containers/Rcs/index.js +829 -2682
- package/v2Containers/Rcs/index.scss +8 -443
- package/v2Containers/Rcs/messages.js +6 -45
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +39409 -74176
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +74 -10
- package/v2Containers/Rcs/tests/index.test.js +40 -151
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -643
- package/v2Containers/Rcs/utils.js +12 -466
- package/v2Containers/Sms/Create/index.js +48 -115
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +169 -678
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2854 -5455
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +11 -196
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +60 -131
- package/v2Containers/Templates/sagas.js +13 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1015 -1060
- package/v2Containers/Templates/tests/sagas.test.js +16 -199
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +10 -75
- package/v2Containers/TemplatesV2/index.js +43 -86
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +25 -4
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/rcsPayloadUtils.test.js +0 -226
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/CommonTestAndPreview/utils.js +0 -84
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -91
- package/v2Components/SmsFallback/constants.js +0 -94
- package/v2Components/SmsFallback/index.js +0 -958
- package/v2Components/SmsFallback/index.scss +0 -266
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -120
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -208
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -309
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -17
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -227
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -126
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
|
@@ -44,6 +44,10 @@ class TemplateNameInputField extends React.Component {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
import PropTypes from 'prop-types';
|
|
47
|
+
import {
|
|
48
|
+
CAP_SPACE_16, CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64,
|
|
49
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
50
|
+
|
|
47
51
|
import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
|
|
48
52
|
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
49
53
|
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
@@ -53,11 +57,12 @@ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
|
53
57
|
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
54
58
|
import classnames from 'classnames';
|
|
55
59
|
import {
|
|
56
|
-
isEmpty, get, forEach, cloneDeep, debounce,
|
|
60
|
+
isEmpty, get, forEach, cloneDeep, debounce,
|
|
57
61
|
} from 'lodash';
|
|
58
62
|
import { connect } from 'react-redux';
|
|
59
63
|
import { createStructuredSelector } from 'reselect';
|
|
60
64
|
import { bindActionCreators, compose } from 'redux';
|
|
65
|
+
import styled from 'styled-components';
|
|
61
66
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
62
67
|
import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
|
|
63
68
|
|
|
@@ -71,7 +76,6 @@ import SlideBoxContent from './SlideBoxContent';
|
|
|
71
76
|
import * as constants from './constants';
|
|
72
77
|
import * as commonUtil from '../../utils/common';
|
|
73
78
|
import { gtmPush } from '../../utils/gtmTrackers';
|
|
74
|
-
import { normalizeRcsMessageContentForApi } from '../../utils/rcsPayloadUtils';
|
|
75
79
|
import './index.scss';
|
|
76
80
|
import * as templateActions from '../Templates/actions';
|
|
77
81
|
import * as globalActions from '../Cap/actions';
|
|
@@ -86,10 +90,7 @@ import {
|
|
|
86
90
|
} from '../Line/Container/constants';
|
|
87
91
|
import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
|
|
88
92
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
89
|
-
import { RCS_STATUSES
|
|
90
|
-
import { mapRcsCardContentForConsumerWithResolvedTags } from '../Rcs/utils';
|
|
91
|
-
import { pickRcsCardVarMappedEntries } from '../Rcs/rcsLibraryHydrationUtils';
|
|
92
|
-
import { RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../../v2Components/CommonTestAndPreview/constants';
|
|
93
|
+
import { RCS_STATUSES } from '../Rcs/constants';
|
|
93
94
|
import { CREATIVE } from '../Facebook/constants';
|
|
94
95
|
import { LOYALTY } from '../App/constants';
|
|
95
96
|
import {
|
|
@@ -130,11 +131,6 @@ import { capSagaForFetchSchemaForEntity, capSagaLiquidEntity } from '../Cap/saga
|
|
|
130
131
|
import { v2TemplateSagaWatchGetDefaultBeeTemplates } from '../Templates/sagas';
|
|
131
132
|
import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
|
|
132
133
|
import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
|
|
133
|
-
import SlideBoxWrapper from './CreativesSlideBoxWrapper';
|
|
134
|
-
import {
|
|
135
|
-
computeLiquidFooterUpdateFromFormBuilder,
|
|
136
|
-
getSlideBoxWrapperMarginFromLiquidErrors,
|
|
137
|
-
} from './embeddedSlideboxUtils';
|
|
138
134
|
|
|
139
135
|
import {
|
|
140
136
|
transformChannelPayload,
|
|
@@ -143,24 +139,51 @@ import {
|
|
|
143
139
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
144
140
|
import { BIG_HTML } from '../InApp/constants';
|
|
145
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Returns true if value is "deep empty": no errors present.
|
|
144
|
+
* - null/undefined: empty
|
|
145
|
+
* - string: empty if length === 0
|
|
146
|
+
* - array: empty if length === 0
|
|
147
|
+
* - plain object (e.g. { android: [], ios: [], generic: [] }): empty only if every value is deep-empty
|
|
148
|
+
*/
|
|
149
|
+
function isDeepEmpty(value) {
|
|
150
|
+
if (value == null) return true;
|
|
151
|
+
if (typeof value === 'string') return value.length === 0;
|
|
152
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
153
|
+
if (typeof value === 'object') {
|
|
154
|
+
return Object.values(value).every(isDeepEmpty);
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
146
159
|
const classPrefix = 'add-creatives-section';
|
|
147
160
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
148
161
|
|
|
162
|
+
const SlideBoxWrapper = styled.div`
|
|
163
|
+
.cap-slide-box-v2-container{
|
|
164
|
+
.slidebox-header, .slidebox-content-container{
|
|
165
|
+
margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
|
|
166
|
+
padding: 0 rem;
|
|
167
|
+
&.has-footer{
|
|
168
|
+
overflow-x: hidden;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
.slidebox-footer{
|
|
172
|
+
/* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
|
|
173
|
+
/* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
|
|
174
|
+
margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
|
|
175
|
+
padding: 0 rem;
|
|
176
|
+
&.has-footer{
|
|
177
|
+
overflow-x: hidden;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
`;
|
|
149
182
|
export class Creatives extends React.Component {
|
|
150
183
|
constructor(props) {
|
|
151
184
|
super(props);
|
|
152
185
|
|
|
153
|
-
const
|
|
154
|
-
props,
|
|
155
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
156
|
-
get(props, 'useLocalTemplates', false),
|
|
157
|
-
);
|
|
158
|
-
const initialSlidBoxContent = this.getSlideBoxContent({
|
|
159
|
-
mode: props.creativesMode,
|
|
160
|
-
templateData: props.templateData,
|
|
161
|
-
isFullMode: props.isFullMode,
|
|
162
|
-
useLocalTemplates,
|
|
163
|
-
});
|
|
186
|
+
const initialSlidBoxContent = this.getSlideBoxContent({ mode: props.creativesMode, templateData: props.templateData, isFullMode: props.isFullMode });
|
|
164
187
|
|
|
165
188
|
this.state = {
|
|
166
189
|
isLoadingContent: true,
|
|
@@ -207,13 +230,7 @@ export class Creatives extends React.Component {
|
|
|
207
230
|
}
|
|
208
231
|
|
|
209
232
|
componentWillUnmount() {
|
|
210
|
-
|
|
211
|
-
const useLocalTemplates = get(
|
|
212
|
-
this.props,
|
|
213
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
214
|
-
get(this.props, 'useLocalTemplates', false),
|
|
215
|
-
);
|
|
216
|
-
if (isEmbedded && !useLocalTemplates) {
|
|
233
|
+
if (get(this.props, 'location.query.type', '') === "embedded") {
|
|
217
234
|
this.props.templateActions.resetTemplateStoreData();
|
|
218
235
|
}
|
|
219
236
|
this.props.globalActions.clearMetaEntities();
|
|
@@ -823,69 +840,15 @@ export class Creatives extends React.Component {
|
|
|
823
840
|
smsFallBackContent = {},
|
|
824
841
|
creativeName = "",
|
|
825
842
|
channel = constants.RCS,
|
|
826
|
-
rcsCardVarMapped,
|
|
827
843
|
accountId = "",
|
|
828
844
|
} = templateData || {};
|
|
829
|
-
const
|
|
830
|
-
const isCarouselRcs = (rcsContent?.cardType || '').toString().toUpperCase() === RCS_CONTENT_TYPE.carousel;
|
|
831
|
-
const firstCardIn = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
832
|
-
const {
|
|
833
|
-
cardDisplayTitle: _omitDispTitleIn,
|
|
834
|
-
cardDisplayDescription: _omitDispDescIn,
|
|
835
|
-
...cardContent
|
|
836
|
-
} = firstCardIn;
|
|
845
|
+
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
837
846
|
const Status = RCS_STATUSES.approved || '';
|
|
838
|
-
const mergedCardVarMapped = (() => {
|
|
839
|
-
const nestedCardVarMapped = cardContent?.cardVarMapped;
|
|
840
|
-
const rootMirrorCardVarMapped = rcsCardVarMapped;
|
|
841
|
-
const nestedRecord =
|
|
842
|
-
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
843
|
-
? nestedCardVarMapped
|
|
844
|
-
: {};
|
|
845
|
-
const rootRecord =
|
|
846
|
-
rootMirrorCardVarMapped != null && typeof rootMirrorCardVarMapped === 'object'
|
|
847
|
-
? rootMirrorCardVarMapped
|
|
848
|
-
: {};
|
|
849
|
-
const mergedFromRootAndNested = {
|
|
850
|
-
...pickRcsCardVarMappedEntries(rootRecord),
|
|
851
|
-
...pickRcsCardVarMappedEntries(nestedRecord),
|
|
852
|
-
};
|
|
853
|
-
return Object.keys(mergedFromRootAndNested).length > 0
|
|
854
|
-
? mergedFromRootAndNested
|
|
855
|
-
: null;
|
|
856
|
-
})();
|
|
857
|
-
// Campaigns (embedded): do not duplicate `cardVarMapped` as root `rcsCardVarMapped` on send —
|
|
858
|
-
// slot map stays on `versions…cardContent[0].cardVarMapped` only. Library full mode keeps root mirror.
|
|
859
|
-
// Use `=== true` so omitted/undefined `isFullMode` does not behave like library (avoids duplicate on approval payload).
|
|
860
|
-
const includeRootRcsCardVarMapped =
|
|
861
|
-
mergedCardVarMapped && isFullModeForRcsPayload === true;
|
|
862
|
-
|
|
863
|
-
const builtCardContent = isCarouselRcs
|
|
864
|
-
? (rcsContent.cardContent || []).map((card, idx) => {
|
|
865
|
-
const {
|
|
866
|
-
cardDisplayTitle: _dt,
|
|
867
|
-
cardDisplayDescription: _dd,
|
|
868
|
-
...restCard
|
|
869
|
-
} = card || {};
|
|
870
|
-
return {
|
|
871
|
-
...restCard,
|
|
872
|
-
...(idx === 0 && mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
873
|
-
Status,
|
|
874
|
-
};
|
|
875
|
-
})
|
|
876
|
-
: [
|
|
877
|
-
{
|
|
878
|
-
...cardContent,
|
|
879
|
-
...(mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
880
|
-
Status,
|
|
881
|
-
},
|
|
882
|
-
];
|
|
883
847
|
|
|
884
848
|
creativesTemplateData = {
|
|
885
849
|
type: channel,
|
|
886
850
|
edit: true,
|
|
887
851
|
name: creativeName,
|
|
888
|
-
...(includeRootRcsCardVarMapped ? { rcsCardVarMapped: mergedCardVarMapped } : {}),
|
|
889
852
|
versions: {
|
|
890
853
|
base: {
|
|
891
854
|
content: {
|
|
@@ -893,7 +856,12 @@ export class Creatives extends React.Component {
|
|
|
893
856
|
rcsContent: {
|
|
894
857
|
...rcsContent,
|
|
895
858
|
...(accountId && !isFullMode && { accountId }),
|
|
896
|
-
cardContent:
|
|
859
|
+
cardContent: [
|
|
860
|
+
{
|
|
861
|
+
...cardContent,
|
|
862
|
+
Status,
|
|
863
|
+
},
|
|
864
|
+
],
|
|
897
865
|
},
|
|
898
866
|
smsFallBackContent,
|
|
899
867
|
},
|
|
@@ -1041,10 +1009,7 @@ export class Creatives extends React.Component {
|
|
|
1041
1009
|
return newExpandableDetails;
|
|
1042
1010
|
}
|
|
1043
1011
|
|
|
1044
|
-
getCreativesData = async (
|
|
1045
|
-
const channel = String(
|
|
1046
|
-
channelParam || template?.type || get(template, 'value.type') || '',
|
|
1047
|
-
).toUpperCase();
|
|
1012
|
+
getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
|
|
1048
1013
|
let templateData = { channel };
|
|
1049
1014
|
switch (channel) {
|
|
1050
1015
|
case constants.SMS:
|
|
@@ -1391,104 +1356,28 @@ export class Creatives extends React.Component {
|
|
|
1391
1356
|
break;
|
|
1392
1357
|
case constants.RCS:
|
|
1393
1358
|
if (template.value) {
|
|
1394
|
-
const {
|
|
1395
|
-
|
|
1396
|
-
const
|
|
1397
|
-
const fromRecords = {
|
|
1398
|
-
...(templateRecords?.smsFallBackContent || {}),
|
|
1399
|
-
...(get(templateRecords, 'versions.base.content.RCS.smsFallBackContent') || {}),
|
|
1400
|
-
};
|
|
1401
|
-
const hasMeaningfulRcsSmsFallback = (smsFallbackPayload) => {
|
|
1402
|
-
if (
|
|
1403
|
-
!smsFallbackPayload
|
|
1404
|
-
|| typeof smsFallbackPayload !== 'object'
|
|
1405
|
-
|| Object.keys(smsFallbackPayload).length === 0
|
|
1406
|
-
) {
|
|
1407
|
-
return false;
|
|
1408
|
-
}
|
|
1409
|
-
const fallbackBodyText = String(
|
|
1410
|
-
smsFallbackPayload.smsContent
|
|
1411
|
-
?? smsFallbackPayload.smsTemplateContent
|
|
1412
|
-
?? smsFallbackPayload.message
|
|
1413
|
-
?? smsFallbackPayload.content
|
|
1414
|
-
?? '',
|
|
1415
|
-
).trim();
|
|
1416
|
-
const fallbackTemplateName = String(
|
|
1417
|
-
smsFallbackPayload.smsTemplateName ?? smsFallbackPayload.templateName ?? '',
|
|
1418
|
-
).trim();
|
|
1419
|
-
const rcsSmsFallbackVarMapped =
|
|
1420
|
-
smsFallbackPayload?.[RCS_SMS_FALLBACK_VAR_MAPPED_PROP];
|
|
1421
|
-
const hasVarMappedEntries =
|
|
1422
|
-
rcsSmsFallbackVarMapped != null
|
|
1423
|
-
&& typeof rcsSmsFallbackVarMapped === 'object'
|
|
1424
|
-
&& Object.keys(rcsSmsFallbackVarMapped).length > 0;
|
|
1425
|
-
return (
|
|
1426
|
-
fallbackBodyText !== ''
|
|
1427
|
-
|| fallbackTemplateName !== ''
|
|
1428
|
-
|| hasVarMappedEntries
|
|
1429
|
-
);
|
|
1430
|
-
};
|
|
1431
|
-
// If submit has only empty strings, do not let it wipe fallback mirrored on templateRecords (library round-trip).
|
|
1432
|
-
const smsFallBackContent = hasMeaningfulRcsSmsFallback(fromSubmit)
|
|
1433
|
-
? { ...fromRecords, ...fromSubmit }
|
|
1434
|
-
: { ...fromSubmit, ...fromRecords };
|
|
1359
|
+
const { name = "", versions = {} } = {
|
|
1360
|
+
} = template.value || {};
|
|
1361
|
+
const smsFallBackContent = get(versions, 'base.content.RCS.smsFallBackContent', {});
|
|
1435
1362
|
const {
|
|
1436
|
-
cardContent
|
|
1363
|
+
cardContent = [],
|
|
1437
1364
|
contentType = "",
|
|
1438
1365
|
cardType = "",
|
|
1439
1366
|
cardSettings = {},
|
|
1440
1367
|
accountId = "",
|
|
1441
1368
|
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1442
|
-
const rootRcsCardVarMappedFromSubmit = get(template, 'value.rcsCardVarMapped');
|
|
1443
|
-
const firstCardFromSubmit = Array.isArray(cardContentFromSubmit)
|
|
1444
|
-
? cardContentFromSubmit[0]
|
|
1445
|
-
: null;
|
|
1446
|
-
const cardContent = mapRcsCardContentForConsumerWithResolvedTags(
|
|
1447
|
-
cardContentFromSubmit,
|
|
1448
|
-
rootRcsCardVarMappedFromSubmit,
|
|
1449
|
-
isFullModeForRcsConsumerPayload,
|
|
1450
|
-
);
|
|
1451
1369
|
const rcsContent = {
|
|
1452
1370
|
contentType,
|
|
1453
1371
|
cardType,
|
|
1454
1372
|
cardSettings,
|
|
1455
1373
|
cardContent,
|
|
1456
1374
|
};
|
|
1457
|
-
const cardVarMappedFromFirstRcsCard =
|
|
1458
|
-
firstCardFromSubmit?.cardVarMapped != null
|
|
1459
|
-
&& typeof firstCardFromSubmit.cardVarMapped === 'object'
|
|
1460
|
-
? pickRcsCardVarMappedEntries(firstCardFromSubmit.cardVarMapped)
|
|
1461
|
-
: null;
|
|
1462
|
-
const includeRootRcsCardVarMappedOnConsumerPayload =
|
|
1463
|
-
cardVarMappedFromFirstRcsCard
|
|
1464
|
-
&& Object.keys(cardVarMappedFromFirstRcsCard).length > 0
|
|
1465
|
-
&& isFullModeForRcsConsumerPayload === true;
|
|
1466
1375
|
templateData = {
|
|
1467
1376
|
channel,
|
|
1468
1377
|
creativeName: name,
|
|
1469
1378
|
rcsContent,
|
|
1470
1379
|
accountId,
|
|
1471
|
-
...(includeRootRcsCardVarMappedOnConsumerPayload
|
|
1472
|
-
? { rcsCardVarMapped: cardVarMappedFromFirstRcsCard }
|
|
1473
|
-
: {}),
|
|
1474
1380
|
};
|
|
1475
|
-
// Library / campaign consumers round-trip templateData via getTemplateData; include SMS fallback
|
|
1476
|
-
// so reopening the editor restores fallback text and tag mappings.
|
|
1477
|
-
// cap-campaigns-v2 API expects `smsFallBackContent.message` (see normalizeRcsMessageContentForApi).
|
|
1478
|
-
if (hasMeaningfulRcsSmsFallback(smsFallBackContent)) {
|
|
1479
|
-
const smsText =
|
|
1480
|
-
smsFallBackContent.message
|
|
1481
|
-
?? smsFallBackContent.smsContent
|
|
1482
|
-
?? smsFallBackContent.smsTemplateContent
|
|
1483
|
-
?? '';
|
|
1484
|
-
templateData.smsFallBackContent = {
|
|
1485
|
-
...smsFallBackContent,
|
|
1486
|
-
...(String(smsText).trim() !== ''
|
|
1487
|
-
? { message: String(smsText).trim() }
|
|
1488
|
-
: {}),
|
|
1489
|
-
};
|
|
1490
|
-
}
|
|
1491
|
-
normalizeRcsMessageContentForApi(templateData);
|
|
1492
1381
|
}
|
|
1493
1382
|
break;
|
|
1494
1383
|
case constants.ZALO:
|
|
@@ -1606,10 +1495,7 @@ export class Creatives extends React.Component {
|
|
|
1606
1495
|
return templateData;
|
|
1607
1496
|
};
|
|
1608
1497
|
|
|
1609
|
-
getSlideBoxContent({ mode, templateData, isFullMode
|
|
1610
|
-
if (useLocalTemplates && mode === 'create' && isEmpty(templateData)) {
|
|
1611
|
-
return 'templates';
|
|
1612
|
-
}
|
|
1498
|
+
getSlideBoxContent({ mode, templateData, isFullMode }) {
|
|
1613
1499
|
let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
|
|
1614
1500
|
if (mode === 'create' && isFullMode) {
|
|
1615
1501
|
creativesMode = 'createTemplate';
|
|
@@ -1697,110 +1583,24 @@ export class Creatives extends React.Component {
|
|
|
1697
1583
|
getFormData = (template) => {
|
|
1698
1584
|
// Always reset isGetFormData so the child does not re-send form data on every re-render
|
|
1699
1585
|
// (e.g. when user fixes validation error by typing, we must not auto-close the slidebox)
|
|
1700
|
-
this.setState(
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|| ''
|
|
1712
|
-
).toUpperCase();
|
|
1713
|
-
// Library mode: persist last submitted creatives shape so reopening still hydrates the editor
|
|
1714
|
-
// (parent may not merge getCreativesData back into templateData).
|
|
1715
|
-
if (this.props.isFullMode === false && template.value) {
|
|
1716
|
-
if (channel === constants.RCS) {
|
|
1717
|
-
const smsFallBackFromPayload = get(
|
|
1718
|
-
template.value,
|
|
1719
|
-
'versions.base.content.RCS.smsFallBackContent',
|
|
1720
|
-
);
|
|
1721
|
-
const rcsCardVarMappedFromPayload = get(
|
|
1722
|
-
template.value,
|
|
1723
|
-
'versions.base.content.RCS.rcsContent.cardContent[0].cardVarMapped',
|
|
1724
|
-
);
|
|
1725
|
-
next.templateData = {
|
|
1726
|
-
...baseTd,
|
|
1727
|
-
type: constants.RCS,
|
|
1728
|
-
name: template?.value?.name,
|
|
1729
|
-
versions: template?.value?.versions,
|
|
1730
|
-
...(smsFallBackFromPayload != null
|
|
1731
|
-
&& typeof smsFallBackFromPayload === 'object'
|
|
1732
|
-
&& Object.keys(smsFallBackFromPayload).length > 0
|
|
1733
|
-
? { smsFallBackContent: smsFallBackFromPayload }
|
|
1734
|
-
: {}),
|
|
1735
|
-
...(rcsCardVarMappedFromPayload != null
|
|
1736
|
-
&& typeof rcsCardVarMappedFromPayload === 'object'
|
|
1737
|
-
? { rcsCardVarMapped: rcsCardVarMappedFromPayload }
|
|
1738
|
-
: {}),
|
|
1739
|
-
};
|
|
1740
|
-
if (template._id) {
|
|
1741
|
-
next.templateData._id = template._id;
|
|
1742
|
-
}
|
|
1743
|
-
} else if (channel === constants.SMS) {
|
|
1744
|
-
const submittedSmsTemplateValue = template?.value;
|
|
1745
|
-
const smsVersions =
|
|
1746
|
-
submittedSmsTemplateValue?.history != null
|
|
1747
|
-
? submittedSmsTemplateValue
|
|
1748
|
-
: {
|
|
1749
|
-
base: submittedSmsTemplateValue?.base,
|
|
1750
|
-
history: submittedSmsTemplateValue?.base
|
|
1751
|
-
? [submittedSmsTemplateValue.base]
|
|
1752
|
-
: [],
|
|
1753
|
-
};
|
|
1754
|
-
next.templateData = {
|
|
1755
|
-
...baseTd,
|
|
1756
|
-
type: constants.SMS,
|
|
1757
|
-
name: baseTd?.name || constants.DEFAULT_SMS_TEMPLATE_NAME,
|
|
1758
|
-
versions: smsVersions,
|
|
1759
|
-
};
|
|
1760
|
-
if (template?._id) {
|
|
1761
|
-
next.templateData._id = template._id;
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
return next;
|
|
1766
|
-
},
|
|
1767
|
-
() => {
|
|
1768
|
-
if (!template.validity) {
|
|
1769
|
-
return;
|
|
1770
|
-
}
|
|
1771
|
-
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1772
|
-
const channelForConsumer = String(
|
|
1773
|
-
templateData.type
|
|
1774
|
-
|| template.type
|
|
1775
|
-
|| get(template, 'value.type')
|
|
1776
|
-
|| '',
|
|
1777
|
-
).toUpperCase();
|
|
1778
|
-
const creativesData = this.getCreativesData(
|
|
1779
|
-
channelForConsumer,
|
|
1780
|
-
template,
|
|
1781
|
-
this.state.templateData || template,
|
|
1782
|
-
);// convers data to consumer understandable format
|
|
1783
|
-
creativesData.then((data) => {
|
|
1784
|
-
this.logGTMEvent(channelForConsumer, data);
|
|
1785
|
-
this.processCentralCommsMetaId(channelForConsumer, data, {
|
|
1786
|
-
closeSlideBoxAfterSubmit: template.closeSlideBoxAfterSubmit,
|
|
1586
|
+
this.setState({ isGetFormData: false });
|
|
1587
|
+
if (template.validity) {
|
|
1588
|
+
this.setState(
|
|
1589
|
+
{},
|
|
1590
|
+
() => {
|
|
1591
|
+
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1592
|
+
const channel = templateData.type;
|
|
1593
|
+
const creativesData = this.getCreativesData(channel, template, templateData);// convers data to consumer understandable format
|
|
1594
|
+
creativesData.then((data) => {
|
|
1595
|
+
this.logGTMEvent(channel, data);
|
|
1596
|
+
this.processCentralCommsMetaId(channel, data);
|
|
1787
1597
|
});
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1598
|
+
},
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1791
1601
|
}
|
|
1792
1602
|
|
|
1793
|
-
processCentralCommsMetaId = (channel, creativesData
|
|
1794
|
-
const { closeSlideBoxAfterSubmit = false } = options;
|
|
1795
|
-
const maybeCloseLibrarySlideBox = () => {
|
|
1796
|
-
if (
|
|
1797
|
-
closeSlideBoxAfterSubmit
|
|
1798
|
-
&& this.props.isFullMode === false
|
|
1799
|
-
&& typeof this.handleCloseSlideBox === 'function'
|
|
1800
|
-
) {
|
|
1801
|
-
this.handleCloseSlideBox();
|
|
1802
|
-
}
|
|
1803
|
-
};
|
|
1603
|
+
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1804
1604
|
// Create the payload for the centralcommnsmetaId API call
|
|
1805
1605
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1806
1606
|
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
@@ -1826,7 +1626,6 @@ export class Creatives extends React.Component {
|
|
|
1826
1626
|
if (result?.status?.code === 200) {
|
|
1827
1627
|
setMetaData(result);
|
|
1828
1628
|
this.props.getCreativesData(creativesData);
|
|
1829
|
-
maybeCloseLibrarySlideBox();
|
|
1830
1629
|
} else {
|
|
1831
1630
|
CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
|
|
1832
1631
|
}
|
|
@@ -1837,7 +1636,6 @@ export class Creatives extends React.Component {
|
|
|
1837
1636
|
} else {
|
|
1838
1637
|
// If not a loyalty module or different action, should work as usual
|
|
1839
1638
|
this.props.getCreativesData(creativesData);
|
|
1840
|
-
maybeCloseLibrarySlideBox();
|
|
1841
1639
|
}
|
|
1842
1640
|
};
|
|
1843
1641
|
|
|
@@ -1870,9 +1668,7 @@ export class Creatives extends React.Component {
|
|
|
1870
1668
|
}
|
|
1871
1669
|
this.setState((prevState) => ({
|
|
1872
1670
|
...prevState,
|
|
1873
|
-
|
|
1874
|
-
// Undefined isFullMode defaults to full-mode close behavior (clear templateData).
|
|
1875
|
-
...(this.props.isFullMode !== false ? { templateData: undefined } : {}),
|
|
1671
|
+
templateData: undefined,
|
|
1876
1672
|
showSlideBox: false,
|
|
1877
1673
|
liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
|
|
1878
1674
|
isLiquidValidationError: false,
|
|
@@ -2075,17 +1871,21 @@ export class Creatives extends React.Component {
|
|
|
2075
1871
|
}
|
|
2076
1872
|
|
|
2077
1873
|
showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
|
|
2078
|
-
const
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
this.setState(
|
|
1874
|
+
const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
|
|
1875
|
+
const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
|
|
1876
|
+
const hasLiquid = !isDeepEmpty(liquidMsgs);
|
|
1877
|
+
const hasStandard = !isDeepEmpty(standardMsgs);
|
|
1878
|
+
const isLiquidValidationError = hasLiquid || hasStandard;
|
|
1879
|
+
// Don't overwrite existing liquid error with empty only for Mobile Push OLD (FormBuilder/clear calls empty there); SMS/others clear on input change
|
|
1880
|
+
const isMobilePush = this.state.currentChannel?.toUpperCase() === constants.MOBILE_PUSH;
|
|
1881
|
+
if (!hasLiquid && !hasStandard && this.state.isLiquidValidationError && isMobilePush) {
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
this.setState({
|
|
1885
|
+
isLiquidValidationError,
|
|
1886
|
+
liquidErrorMessage: errorMessagesFromFormBuilder,
|
|
1887
|
+
activeFormBuilderTab: currentFormBuilderTab === 1 ? constants.ANDROID : (currentFormBuilderTab === 2 ? constants.IOS : null), // Update activeFormBuilderTab, default to 1 if undefined
|
|
1888
|
+
});
|
|
2089
1889
|
}
|
|
2090
1890
|
|
|
2091
1891
|
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
@@ -2208,11 +2008,6 @@ export class Creatives extends React.Component {
|
|
|
2208
2008
|
inAppEditorType,
|
|
2209
2009
|
htmlEditorValidationState,
|
|
2210
2010
|
} = this.state;
|
|
2211
|
-
const useLocalTemplates = get(
|
|
2212
|
-
this.props,
|
|
2213
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
2214
|
-
get(this.props, 'useLocalTemplates', false),
|
|
2215
|
-
);
|
|
2216
2011
|
const {
|
|
2217
2012
|
isFullMode,
|
|
2218
2013
|
creativesMode,
|
|
@@ -2231,6 +2026,7 @@ export class Creatives extends React.Component {
|
|
|
2231
2026
|
smsRegister,
|
|
2232
2027
|
enableNewChannels,
|
|
2233
2028
|
eventContextTags,
|
|
2029
|
+
waitEventContextTags = {},
|
|
2234
2030
|
isLoyaltyModule,
|
|
2235
2031
|
loyaltyMetaData = {},
|
|
2236
2032
|
} = this.props;
|
|
@@ -2264,7 +2060,14 @@ export class Creatives extends React.Component {
|
|
|
2264
2060
|
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
2265
2061
|
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
2266
2062
|
|
|
2267
|
-
|
|
2063
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
2064
|
+
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
2065
|
+
? CAP_SPACE_64
|
|
2066
|
+
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
2067
|
+
? CAP_SPACE_56
|
|
2068
|
+
: get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
2069
|
+
? CAP_SPACE_32
|
|
2070
|
+
: 0;
|
|
2268
2071
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
2269
2072
|
|
|
2270
2073
|
// Compute anonymous user type and channel restrictions
|
|
@@ -2293,10 +2096,7 @@ export class Creatives extends React.Component {
|
|
|
2293
2096
|
<SlideBoxWrapper
|
|
2294
2097
|
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
2295
2098
|
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
2296
|
-
className={classnames(
|
|
2297
|
-
`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`,
|
|
2298
|
-
useLocalTemplates && slidBoxContent === 'templates' && 'creatives-slidebox--local-sms-templates',
|
|
2299
|
-
)}
|
|
2099
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
2300
2100
|
>
|
|
2301
2101
|
<CapSlideBox
|
|
2302
2102
|
header={
|
|
@@ -2321,13 +2121,12 @@ export class Creatives extends React.Component {
|
|
|
2321
2121
|
smsRegister={smsRegister}
|
|
2322
2122
|
handleClose={this.handleCloseSlideBox}
|
|
2323
2123
|
moduleType={this.props.messageDetails?.type}
|
|
2324
|
-
useLocalTemplates={useLocalTemplates}
|
|
2325
2124
|
/>
|
|
2326
2125
|
)}
|
|
2327
2126
|
content={(
|
|
2328
2127
|
<SlideBoxContent
|
|
2329
2128
|
key="creatives-container-slidebox-content"
|
|
2330
|
-
onSelectTemplate={this.
|
|
2129
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
2331
2130
|
onCreateComplete={getCreativesData}
|
|
2332
2131
|
onPreviewTemplate={this.onPreviewTemplate}
|
|
2333
2132
|
slidBoxContent={slidBoxContent}
|
|
@@ -2395,6 +2194,7 @@ export class Creatives extends React.Component {
|
|
|
2395
2194
|
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.
|
|
2396
2195
|
hostName={this.props?.hostName || ''}
|
|
2397
2196
|
eventContextTags={eventContextTags}
|
|
2197
|
+
waitEventContextTags={waitEventContextTags}
|
|
2398
2198
|
isLoyaltyModule={isLoyaltyModule}
|
|
2399
2199
|
loyaltyMetaData={loyaltyMetaData}
|
|
2400
2200
|
showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
|
|
@@ -2403,8 +2203,7 @@ export class Creatives extends React.Component {
|
|
|
2403
2203
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2404
2204
|
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
2405
2205
|
onPersonalizationTokensChange={this.handlePersonalizationTokensChange}
|
|
2406
|
-
|
|
2407
|
-
/>
|
|
2206
|
+
/>
|
|
2408
2207
|
)}
|
|
2409
2208
|
footer={this.shouldShowFooter() ? (
|
|
2410
2209
|
<SlideBoxFooter
|
|
@@ -2489,31 +2288,13 @@ Creatives.propTypes = {
|
|
|
2489
2288
|
orgUnitId: PropTypes.number,
|
|
2490
2289
|
hostName: PropTypes.string,
|
|
2491
2290
|
eventContextTags: PropTypes.array,
|
|
2291
|
+
waitEventContextTags: PropTypes.object,
|
|
2492
2292
|
loyaltyTagFetchingDependencies: PropTypes.object,
|
|
2493
2293
|
customerType: PropTypes.string,
|
|
2494
2294
|
intl: PropTypes.shape({
|
|
2495
2295
|
formatMessage: PropTypes.func,
|
|
2496
2296
|
}),
|
|
2497
2297
|
stopValidation: PropTypes.func,
|
|
2498
|
-
// Local template list (e.g. for SMS fallback): when set, TemplatesV2 uses these instead of Redux.
|
|
2499
|
-
// All optional. Pass either localTemplatesConfig (object) or individual props below.
|
|
2500
|
-
localTemplatesConfig: PropTypes.shape({
|
|
2501
|
-
useLocalTemplates: PropTypes.bool,
|
|
2502
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2503
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2504
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2505
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2506
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2507
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2508
|
-
}),
|
|
2509
|
-
useLocalTemplates: PropTypes.bool,
|
|
2510
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2511
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2512
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2513
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2514
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2515
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2516
|
-
onSelectTemplate: PropTypes.func,
|
|
2517
2298
|
};
|
|
2518
2299
|
const mapStatesToProps = () => createStructuredSelector({
|
|
2519
2300
|
isLoading: isLoadingSelector(),
|