@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.330
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 -18
- package/package.json +1 -1
- package/services/api.js +0 -17
- package/services/tests/api.test.js +0 -85
- package/utils/commonUtils.js +0 -28
- package/utils/tests/commonUtil.test.js +0 -169
- 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 +53 -87
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -20
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +34 -145
- package/v2Components/CommonTestAndPreview/actions.js +0 -10
- package/v2Components/CommonTestAndPreview/constants.js +1 -53
- package/v2Components/CommonTestAndPreview/index.js +168 -998
- package/v2Components/CommonTestAndPreview/messages.js +3 -147
- package/v2Components/CommonTestAndPreview/reducer.js +0 -10
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +286 -328
- 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/SendTestMessage.test.js +24 -65
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -31
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -168
- package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -71
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -17
- package/v2Components/FormBuilder/index.js +1 -7
- 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/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +93 -292
- package/v2Containers/CreativesContainer/index.scss +1 -51
- 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 +10 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Rcs/constants.js +3 -40
- package/v2Containers/Rcs/index.js +895 -1145
- package/v2Containers/Rcs/index.scss +6 -85
- package/v2Containers/Rcs/messages.js +2 -12
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2236 -41719
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +38 -41
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +1 -435
- package/v2Containers/Rcs/utils.js +10 -405
- package/v2Containers/Sms/Create/index.js +38 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +128 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2604 -4590
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +2 -63
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +40 -90
- package/v2Containers/Templates/sagas.js +12 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
- package/v2Containers/Templates/tests/sagas.test.js +123 -193
- 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 +4872 -5790
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/AddTestCustomer.js +0 -42
- package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +0 -155
- package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +0 -93
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +0 -66
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -648
- package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +0 -174
- package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +0 -114
- 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/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/rcsLibraryHydrationUtils.js +0 -225
- 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
|
|
|
@@ -42,9 +47,6 @@ import {
|
|
|
42
47
|
import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
|
|
43
48
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
44
49
|
import { RCS_STATUSES } from '../Rcs/constants';
|
|
45
|
-
import { mapRcsCardContentForConsumerWithResolvedTags } from '../Rcs/utils';
|
|
46
|
-
import { pickRcsCardVarMappedEntries } from '../Rcs/rcsLibraryHydrationUtils';
|
|
47
|
-
import { RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../../v2Components/CommonTestAndPreview/constants';
|
|
48
50
|
import { CREATIVE } from '../Facebook/constants';
|
|
49
51
|
import { LOYALTY } from '../App/constants';
|
|
50
52
|
import {
|
|
@@ -59,11 +61,6 @@ import { capSagaForFetchSchemaForEntity, capSagaLiquidEntity } from '../Cap/saga
|
|
|
59
61
|
import { v2TemplateSagaWatchGetDefaultBeeTemplates } from '../Templates/sagas';
|
|
60
62
|
import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
|
|
61
63
|
import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
|
|
62
|
-
import SlideBoxWrapper from './CreativesSlideBoxWrapper';
|
|
63
|
-
import {
|
|
64
|
-
computeLiquidFooterUpdateFromFormBuilder,
|
|
65
|
-
getSlideBoxWrapperMarginFromLiquidErrors,
|
|
66
|
-
} from './embeddedSlideboxUtils';
|
|
67
64
|
|
|
68
65
|
import {
|
|
69
66
|
transformChannelPayload,
|
|
@@ -72,24 +69,51 @@ import {
|
|
|
72
69
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
73
70
|
import { BIG_HTML } from '../InApp/constants';
|
|
74
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
|
+
|
|
75
89
|
const classPrefix = 'add-creatives-section';
|
|
76
90
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
77
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
|
+
`;
|
|
78
112
|
export class Creatives extends React.Component {
|
|
79
113
|
constructor(props) {
|
|
80
114
|
super(props);
|
|
81
115
|
|
|
82
|
-
const
|
|
83
|
-
props,
|
|
84
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
85
|
-
get(props, 'useLocalTemplates', false),
|
|
86
|
-
);
|
|
87
|
-
const initialSlidBoxContent = this.getSlideBoxContent({
|
|
88
|
-
mode: props.creativesMode,
|
|
89
|
-
templateData: props.templateData,
|
|
90
|
-
isFullMode: props.isFullMode,
|
|
91
|
-
useLocalTemplates,
|
|
92
|
-
});
|
|
116
|
+
const initialSlidBoxContent = this.getSlideBoxContent({ mode: props.creativesMode, templateData: props.templateData, isFullMode: props.isFullMode });
|
|
93
117
|
|
|
94
118
|
this.state = {
|
|
95
119
|
isLoadingContent: true,
|
|
@@ -136,13 +160,7 @@ export class Creatives extends React.Component {
|
|
|
136
160
|
}
|
|
137
161
|
|
|
138
162
|
componentWillUnmount() {
|
|
139
|
-
|
|
140
|
-
const useLocalTemplates = get(
|
|
141
|
-
this.props,
|
|
142
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
143
|
-
get(this.props, 'useLocalTemplates', false),
|
|
144
|
-
);
|
|
145
|
-
if (isEmbedded && !useLocalTemplates) {
|
|
163
|
+
if (get(this.props, 'location.query.type', '') === "embedded") {
|
|
146
164
|
this.props.templateActions.resetTemplateStoreData();
|
|
147
165
|
}
|
|
148
166
|
this.props.globalActions.clearMetaEntities();
|
|
@@ -744,46 +762,14 @@ export class Creatives extends React.Component {
|
|
|
744
762
|
smsFallBackContent = {},
|
|
745
763
|
creativeName = "",
|
|
746
764
|
channel = constants.RCS,
|
|
747
|
-
rcsCardVarMapped,
|
|
748
765
|
} = templateData || {};
|
|
749
|
-
const
|
|
750
|
-
const firstCardIn = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
751
|
-
const {
|
|
752
|
-
cardDisplayTitle: _omitDispTitleIn,
|
|
753
|
-
cardDisplayDescription: _omitDispDescIn,
|
|
754
|
-
...cardContent
|
|
755
|
-
} = firstCardIn;
|
|
766
|
+
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
756
767
|
const Status = RCS_STATUSES.approved || '';
|
|
757
|
-
const mergedCardVarMapped = (() => {
|
|
758
|
-
const nestedCardVarMapped = cardContent?.cardVarMapped;
|
|
759
|
-
const rootMirrorCardVarMapped = rcsCardVarMapped;
|
|
760
|
-
const nestedRecord =
|
|
761
|
-
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
762
|
-
? nestedCardVarMapped
|
|
763
|
-
: {};
|
|
764
|
-
const rootRecord =
|
|
765
|
-
rootMirrorCardVarMapped != null && typeof rootMirrorCardVarMapped === 'object'
|
|
766
|
-
? rootMirrorCardVarMapped
|
|
767
|
-
: {};
|
|
768
|
-
const mergedFromRootAndNested = {
|
|
769
|
-
...pickRcsCardVarMappedEntries(rootRecord),
|
|
770
|
-
...pickRcsCardVarMappedEntries(nestedRecord),
|
|
771
|
-
};
|
|
772
|
-
return Object.keys(mergedFromRootAndNested).length > 0
|
|
773
|
-
? mergedFromRootAndNested
|
|
774
|
-
: null;
|
|
775
|
-
})();
|
|
776
|
-
// Campaigns (embedded): do not duplicate `cardVarMapped` as root `rcsCardVarMapped` on send —
|
|
777
|
-
// slot map stays on `versions…cardContent[0].cardVarMapped` only. Library full mode keeps root mirror.
|
|
778
|
-
// Use `=== true` so omitted/undefined `isFullMode` does not behave like library (avoids duplicate on approval payload).
|
|
779
|
-
const includeRootRcsCardVarMapped =
|
|
780
|
-
mergedCardVarMapped && isFullModeForRcsPayload === true;
|
|
781
768
|
|
|
782
769
|
creativesTemplateData = {
|
|
783
770
|
type: channel,
|
|
784
771
|
edit: true,
|
|
785
772
|
name: creativeName,
|
|
786
|
-
...(includeRootRcsCardVarMapped ? { rcsCardVarMapped: mergedCardVarMapped } : {}),
|
|
787
773
|
versions: {
|
|
788
774
|
base: {
|
|
789
775
|
content: {
|
|
@@ -793,7 +779,6 @@ export class Creatives extends React.Component {
|
|
|
793
779
|
cardContent: [
|
|
794
780
|
{
|
|
795
781
|
...cardContent,
|
|
796
|
-
...(mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
797
782
|
Status,
|
|
798
783
|
},
|
|
799
784
|
],
|
|
@@ -944,10 +929,7 @@ export class Creatives extends React.Component {
|
|
|
944
929
|
return newExpandableDetails;
|
|
945
930
|
}
|
|
946
931
|
|
|
947
|
-
getCreativesData = async (
|
|
948
|
-
const channel = String(
|
|
949
|
-
channelParam || template?.type || get(template, 'value.type') || '',
|
|
950
|
-
).toUpperCase();
|
|
932
|
+
getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
|
|
951
933
|
let templateData = { channel };
|
|
952
934
|
switch (channel) {
|
|
953
935
|
case constants.SMS:
|
|
@@ -1289,101 +1271,26 @@ export class Creatives extends React.Component {
|
|
|
1289
1271
|
break;
|
|
1290
1272
|
case constants.RCS: {
|
|
1291
1273
|
if (template.value) {
|
|
1292
|
-
const {
|
|
1293
|
-
|
|
1294
|
-
const
|
|
1295
|
-
const fromRecords = {
|
|
1296
|
-
...(templateRecords?.smsFallBackContent || {}),
|
|
1297
|
-
...(get(templateRecords, 'versions.base.content.RCS.smsFallBackContent') || {}),
|
|
1298
|
-
};
|
|
1299
|
-
const hasMeaningfulRcsSmsFallback = (smsFallbackPayload) => {
|
|
1300
|
-
if (
|
|
1301
|
-
!smsFallbackPayload
|
|
1302
|
-
|| typeof smsFallbackPayload !== 'object'
|
|
1303
|
-
|| Object.keys(smsFallbackPayload).length === 0
|
|
1304
|
-
) {
|
|
1305
|
-
return false;
|
|
1306
|
-
}
|
|
1307
|
-
const fallbackBodyText = String(
|
|
1308
|
-
smsFallbackPayload.smsContent
|
|
1309
|
-
?? smsFallbackPayload.smsTemplateContent
|
|
1310
|
-
?? smsFallbackPayload.message
|
|
1311
|
-
?? smsFallbackPayload.content
|
|
1312
|
-
?? '',
|
|
1313
|
-
).trim();
|
|
1314
|
-
const fallbackTemplateName = String(
|
|
1315
|
-
smsFallbackPayload.smsTemplateName ?? smsFallbackPayload.templateName ?? '',
|
|
1316
|
-
).trim();
|
|
1317
|
-
const rcsSmsFallbackVarMapped =
|
|
1318
|
-
smsFallbackPayload?.[RCS_SMS_FALLBACK_VAR_MAPPED_PROP];
|
|
1319
|
-
const hasVarMappedEntries =
|
|
1320
|
-
rcsSmsFallbackVarMapped != null
|
|
1321
|
-
&& typeof rcsSmsFallbackVarMapped === 'object'
|
|
1322
|
-
&& Object.keys(rcsSmsFallbackVarMapped).length > 0;
|
|
1323
|
-
return (
|
|
1324
|
-
fallbackBodyText !== ''
|
|
1325
|
-
|| fallbackTemplateName !== ''
|
|
1326
|
-
|| hasVarMappedEntries
|
|
1327
|
-
);
|
|
1328
|
-
};
|
|
1329
|
-
// If submit has only empty strings, do not let it wipe fallback mirrored on templateRecords (library round-trip).
|
|
1330
|
-
const smsFallBackContent = hasMeaningfulRcsSmsFallback(fromSubmit)
|
|
1331
|
-
? { ...fromRecords, ...fromSubmit }
|
|
1332
|
-
: { ...fromSubmit, ...fromRecords };
|
|
1274
|
+
const { name = "", versions = {} } = {
|
|
1275
|
+
} = template.value || {};
|
|
1276
|
+
const smsFallBackContent = get(versions, 'base.content.RCS.smsFallBackContent', {});
|
|
1333
1277
|
const {
|
|
1334
|
-
cardContent
|
|
1278
|
+
cardContent = [],
|
|
1335
1279
|
contentType = "",
|
|
1336
1280
|
cardType = "",
|
|
1337
1281
|
cardSettings = {},
|
|
1338
1282
|
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1339
|
-
const rootRcsCardVarMappedFromSubmit = get(template, 'value.rcsCardVarMapped');
|
|
1340
|
-
const firstCardFromSubmit = Array.isArray(cardContentFromSubmit)
|
|
1341
|
-
? cardContentFromSubmit[0]
|
|
1342
|
-
: null;
|
|
1343
|
-
const cardContent = mapRcsCardContentForConsumerWithResolvedTags(
|
|
1344
|
-
cardContentFromSubmit,
|
|
1345
|
-
rootRcsCardVarMappedFromSubmit,
|
|
1346
|
-
isFullModeForRcsConsumerPayload,
|
|
1347
|
-
);
|
|
1348
1283
|
const rcsContent = {
|
|
1349
1284
|
contentType,
|
|
1350
1285
|
cardType,
|
|
1351
1286
|
cardSettings,
|
|
1352
1287
|
cardContent,
|
|
1353
1288
|
};
|
|
1354
|
-
const cardVarMappedFromFirstRcsCard =
|
|
1355
|
-
firstCardFromSubmit?.cardVarMapped != null
|
|
1356
|
-
&& typeof firstCardFromSubmit.cardVarMapped === 'object'
|
|
1357
|
-
? pickRcsCardVarMappedEntries(firstCardFromSubmit.cardVarMapped)
|
|
1358
|
-
: null;
|
|
1359
|
-
const includeRootRcsCardVarMappedOnConsumerPayload =
|
|
1360
|
-
cardVarMappedFromFirstRcsCard
|
|
1361
|
-
&& Object.keys(cardVarMappedFromFirstRcsCard).length > 0
|
|
1362
|
-
&& isFullModeForRcsConsumerPayload === true;
|
|
1363
1289
|
templateData = {
|
|
1364
1290
|
channel,
|
|
1365
1291
|
creativeName: name,
|
|
1366
1292
|
rcsContent,
|
|
1367
|
-
...(includeRootRcsCardVarMappedOnConsumerPayload
|
|
1368
|
-
? { rcsCardVarMapped: cardVarMappedFromFirstRcsCard }
|
|
1369
|
-
: {}),
|
|
1370
1293
|
};
|
|
1371
|
-
// Library / campaign consumers round-trip templateData via getTemplateData; include SMS fallback
|
|
1372
|
-
// so reopening the editor restores fallback text and tag mappings.
|
|
1373
|
-
// cap-campaigns-v2 API expects `smsFallBackContent.message` (see normalizeRcsMessageContentForApi).
|
|
1374
|
-
if (hasMeaningfulRcsSmsFallback(smsFallBackContent)) {
|
|
1375
|
-
const smsText =
|
|
1376
|
-
smsFallBackContent.message
|
|
1377
|
-
?? smsFallBackContent.smsContent
|
|
1378
|
-
?? smsFallBackContent.smsTemplateContent
|
|
1379
|
-
?? '';
|
|
1380
|
-
templateData.smsFallBackContent = {
|
|
1381
|
-
...smsFallBackContent,
|
|
1382
|
-
...(String(smsText).trim() !== ''
|
|
1383
|
-
? { message: String(smsText).trim() }
|
|
1384
|
-
: {}),
|
|
1385
|
-
};
|
|
1386
|
-
}
|
|
1387
1294
|
}
|
|
1388
1295
|
}
|
|
1389
1296
|
break;
|
|
@@ -1503,10 +1410,7 @@ export class Creatives extends React.Component {
|
|
|
1503
1410
|
return templateData;
|
|
1504
1411
|
};
|
|
1505
1412
|
|
|
1506
|
-
getSlideBoxContent({ mode, templateData, isFullMode
|
|
1507
|
-
if (useLocalTemplates && mode === 'create' && isEmpty(templateData)) {
|
|
1508
|
-
return 'templates';
|
|
1509
|
-
}
|
|
1413
|
+
getSlideBoxContent({ mode, templateData, isFullMode }) {
|
|
1510
1414
|
let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
|
|
1511
1415
|
if (mode === 'create' && isFullMode) {
|
|
1512
1416
|
creativesMode = 'createTemplate';
|
|
@@ -1594,110 +1498,24 @@ export class Creatives extends React.Component {
|
|
|
1594
1498
|
getFormData = (template) => {
|
|
1595
1499
|
// Always reset isGetFormData so the child does not re-send form data on every re-render
|
|
1596
1500
|
// (e.g. when user fixes validation error by typing, we must not auto-close the slidebox)
|
|
1597
|
-
this.setState(
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|| ''
|
|
1609
|
-
).toUpperCase();
|
|
1610
|
-
// Library mode: persist last submitted creatives shape so reopening still hydrates the editor
|
|
1611
|
-
// (parent may not merge getCreativesData back into templateData).
|
|
1612
|
-
if (this.props.isFullMode === false && template.value) {
|
|
1613
|
-
if (channel === constants.RCS) {
|
|
1614
|
-
const smsFallBackFromPayload = get(
|
|
1615
|
-
template.value,
|
|
1616
|
-
'versions.base.content.RCS.smsFallBackContent',
|
|
1617
|
-
);
|
|
1618
|
-
const rcsCardVarMappedFromPayload = get(
|
|
1619
|
-
template.value,
|
|
1620
|
-
'versions.base.content.RCS.rcsContent.cardContent[0].cardVarMapped',
|
|
1621
|
-
);
|
|
1622
|
-
next.templateData = {
|
|
1623
|
-
...baseTd,
|
|
1624
|
-
type: constants.RCS,
|
|
1625
|
-
name: template?.value?.name,
|
|
1626
|
-
versions: template?.value?.versions,
|
|
1627
|
-
...(smsFallBackFromPayload != null
|
|
1628
|
-
&& typeof smsFallBackFromPayload === 'object'
|
|
1629
|
-
&& Object.keys(smsFallBackFromPayload).length > 0
|
|
1630
|
-
? { smsFallBackContent: smsFallBackFromPayload }
|
|
1631
|
-
: {}),
|
|
1632
|
-
...(rcsCardVarMappedFromPayload != null
|
|
1633
|
-
&& typeof rcsCardVarMappedFromPayload === 'object'
|
|
1634
|
-
? { rcsCardVarMapped: rcsCardVarMappedFromPayload }
|
|
1635
|
-
: {}),
|
|
1636
|
-
};
|
|
1637
|
-
if (template._id) {
|
|
1638
|
-
next.templateData._id = template._id;
|
|
1639
|
-
}
|
|
1640
|
-
} else if (channel === constants.SMS) {
|
|
1641
|
-
const submittedSmsTemplateValue = template?.value;
|
|
1642
|
-
const smsVersions =
|
|
1643
|
-
submittedSmsTemplateValue?.history != null
|
|
1644
|
-
? submittedSmsTemplateValue
|
|
1645
|
-
: {
|
|
1646
|
-
base: submittedSmsTemplateValue?.base,
|
|
1647
|
-
history: submittedSmsTemplateValue?.base
|
|
1648
|
-
? [submittedSmsTemplateValue.base]
|
|
1649
|
-
: [],
|
|
1650
|
-
};
|
|
1651
|
-
next.templateData = {
|
|
1652
|
-
...baseTd,
|
|
1653
|
-
type: constants.SMS,
|
|
1654
|
-
name: baseTd?.name || 'Campaign message SMS content',
|
|
1655
|
-
versions: smsVersions,
|
|
1656
|
-
};
|
|
1657
|
-
if (template?._id) {
|
|
1658
|
-
next.templateData._id = template._id;
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
return next;
|
|
1663
|
-
},
|
|
1664
|
-
() => {
|
|
1665
|
-
if (!template.validity) {
|
|
1666
|
-
return;
|
|
1667
|
-
}
|
|
1668
|
-
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1669
|
-
const channelForConsumer = String(
|
|
1670
|
-
templateData.type
|
|
1671
|
-
|| template.type
|
|
1672
|
-
|| get(template, 'value.type')
|
|
1673
|
-
|| '',
|
|
1674
|
-
).toUpperCase();
|
|
1675
|
-
const creativesData = this.getCreativesData(
|
|
1676
|
-
channelForConsumer,
|
|
1677
|
-
template,
|
|
1678
|
-
this.state.templateData || template,
|
|
1679
|
-
);// convers data to consumer understandable format
|
|
1680
|
-
creativesData.then((data) => {
|
|
1681
|
-
this.logGTMEvent(channelForConsumer, data);
|
|
1682
|
-
this.processCentralCommsMetaId(channelForConsumer, data, {
|
|
1683
|
-
closeSlideBoxAfterSubmit: template.closeSlideBoxAfterSubmit,
|
|
1501
|
+
this.setState({ isGetFormData: false });
|
|
1502
|
+
if (template.validity) {
|
|
1503
|
+
this.setState(
|
|
1504
|
+
{},
|
|
1505
|
+
() => {
|
|
1506
|
+
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1507
|
+
const channel = templateData.type;
|
|
1508
|
+
const creativesData = this.getCreativesData(channel, template, templateData);// convers data to consumer understandable format
|
|
1509
|
+
creativesData.then((data) => {
|
|
1510
|
+
this.logGTMEvent(channel, data);
|
|
1511
|
+
this.processCentralCommsMetaId(channel, data);
|
|
1684
1512
|
});
|
|
1685
|
-
}
|
|
1686
|
-
|
|
1687
|
-
|
|
1513
|
+
},
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1688
1516
|
}
|
|
1689
1517
|
|
|
1690
|
-
processCentralCommsMetaId = (channel, creativesData
|
|
1691
|
-
const { closeSlideBoxAfterSubmit = false } = options;
|
|
1692
|
-
const maybeCloseLibrarySlideBox = () => {
|
|
1693
|
-
if (
|
|
1694
|
-
closeSlideBoxAfterSubmit
|
|
1695
|
-
&& this.props.isFullMode === false
|
|
1696
|
-
&& typeof this.handleCloseSlideBox === 'function'
|
|
1697
|
-
) {
|
|
1698
|
-
this.handleCloseSlideBox();
|
|
1699
|
-
}
|
|
1700
|
-
};
|
|
1518
|
+
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1701
1519
|
// Create the payload for the centralcommnsmetaId API call
|
|
1702
1520
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1703
1521
|
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
@@ -1723,7 +1541,6 @@ export class Creatives extends React.Component {
|
|
|
1723
1541
|
if (result?.status?.code === 200) {
|
|
1724
1542
|
setMetaData(result);
|
|
1725
1543
|
this.props.getCreativesData(creativesData);
|
|
1726
|
-
maybeCloseLibrarySlideBox();
|
|
1727
1544
|
} else {
|
|
1728
1545
|
CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
|
|
1729
1546
|
}
|
|
@@ -1734,7 +1551,6 @@ export class Creatives extends React.Component {
|
|
|
1734
1551
|
} else {
|
|
1735
1552
|
// If not a loyalty module or different action, should work as usual
|
|
1736
1553
|
this.props.getCreativesData(creativesData);
|
|
1737
|
-
maybeCloseLibrarySlideBox();
|
|
1738
1554
|
}
|
|
1739
1555
|
};
|
|
1740
1556
|
|
|
@@ -1767,9 +1583,7 @@ export class Creatives extends React.Component {
|
|
|
1767
1583
|
}
|
|
1768
1584
|
this.setState((prevState) => ({
|
|
1769
1585
|
...prevState,
|
|
1770
|
-
|
|
1771
|
-
// Undefined isFullMode defaults to full-mode close behavior (clear templateData).
|
|
1772
|
-
...(this.props.isFullMode !== false ? { templateData: undefined } : {}),
|
|
1586
|
+
templateData: undefined,
|
|
1773
1587
|
showSlideBox: false,
|
|
1774
1588
|
liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
|
|
1775
1589
|
isLiquidValidationError: false,
|
|
@@ -1980,12 +1794,21 @@ export class Creatives extends React.Component {
|
|
|
1980
1794
|
}
|
|
1981
1795
|
|
|
1982
1796
|
showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1985
|
-
|
|
1797
|
+
const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
|
|
1798
|
+
const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
|
|
1799
|
+
const hasLiquid = !isDeepEmpty(liquidMsgs);
|
|
1800
|
+
const hasStandard = !isDeepEmpty(standardMsgs);
|
|
1801
|
+
const isLiquidValidationError = hasLiquid || hasStandard;
|
|
1802
|
+
// Don't overwrite existing liquid error with empty only for Mobile Push OLD (FormBuilder/clear calls empty there); SMS/others clear on input change
|
|
1803
|
+
const isMobilePush = this.state.currentChannel?.toUpperCase() === constants.MOBILE_PUSH;
|
|
1804
|
+
if (!hasLiquid && !hasStandard && this.state.isLiquidValidationError && isMobilePush) {
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
this.setState({
|
|
1808
|
+
isLiquidValidationError,
|
|
1809
|
+
liquidErrorMessage: errorMessagesFromFormBuilder,
|
|
1810
|
+
activeFormBuilderTab: currentFormBuilderTab === 1 ? constants.ANDROID : (currentFormBuilderTab === 2 ? constants.IOS : null), // Update activeFormBuilderTab, default to 1 if undefined
|
|
1986
1811
|
});
|
|
1987
|
-
if (next == null) return;
|
|
1988
|
-
this.setState(next);
|
|
1989
1812
|
}
|
|
1990
1813
|
|
|
1991
1814
|
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
@@ -2108,11 +1931,6 @@ export class Creatives extends React.Component {
|
|
|
2108
1931
|
inAppEditorType,
|
|
2109
1932
|
htmlEditorValidationState,
|
|
2110
1933
|
} = this.state;
|
|
2111
|
-
const useLocalTemplates = get(
|
|
2112
|
-
this.props,
|
|
2113
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
2114
|
-
get(this.props, 'useLocalTemplates', false),
|
|
2115
|
-
);
|
|
2116
1934
|
const {
|
|
2117
1935
|
isFullMode,
|
|
2118
1936
|
creativesMode,
|
|
@@ -2164,7 +1982,14 @@ export class Creatives extends React.Component {
|
|
|
2164
1982
|
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
2165
1983
|
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
2166
1984
|
|
|
2167
|
-
|
|
1985
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
1986
|
+
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
1987
|
+
? CAP_SPACE_64
|
|
1988
|
+
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
1989
|
+
? CAP_SPACE_56
|
|
1990
|
+
: get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
1991
|
+
? CAP_SPACE_32
|
|
1992
|
+
: 0;
|
|
2168
1993
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
2169
1994
|
|
|
2170
1995
|
// Compute anonymous user type and channel restrictions
|
|
@@ -2193,10 +2018,7 @@ export class Creatives extends React.Component {
|
|
|
2193
2018
|
<SlideBoxWrapper
|
|
2194
2019
|
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
2195
2020
|
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
2196
|
-
className={classnames(
|
|
2197
|
-
`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`,
|
|
2198
|
-
useLocalTemplates && slidBoxContent === 'templates' && 'creatives-slidebox--local-sms-templates',
|
|
2199
|
-
)}
|
|
2021
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
2200
2022
|
>
|
|
2201
2023
|
<CapSlideBox
|
|
2202
2024
|
header={
|
|
@@ -2221,13 +2043,12 @@ export class Creatives extends React.Component {
|
|
|
2221
2043
|
smsRegister={smsRegister}
|
|
2222
2044
|
handleClose={this.handleCloseSlideBox}
|
|
2223
2045
|
moduleType={this.props.messageDetails?.type}
|
|
2224
|
-
useLocalTemplates={useLocalTemplates}
|
|
2225
2046
|
/>
|
|
2226
2047
|
)}
|
|
2227
2048
|
content={(
|
|
2228
2049
|
<SlideBoxContent
|
|
2229
2050
|
key="creatives-container-slidebox-content"
|
|
2230
|
-
onSelectTemplate={this.
|
|
2051
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
2231
2052
|
onCreateComplete={getCreativesData}
|
|
2232
2053
|
onPreviewTemplate={this.onPreviewTemplate}
|
|
2233
2054
|
slidBoxContent={slidBoxContent}
|
|
@@ -2303,8 +2124,7 @@ export class Creatives extends React.Component {
|
|
|
2303
2124
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2304
2125
|
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
2305
2126
|
onPersonalizationTokensChange={this.handlePersonalizationTokensChange}
|
|
2306
|
-
|
|
2307
|
-
/>
|
|
2127
|
+
/>
|
|
2308
2128
|
)}
|
|
2309
2129
|
footer={this.shouldShowFooter() ? (
|
|
2310
2130
|
<SlideBoxFooter
|
|
@@ -2394,25 +2214,6 @@ Creatives.propTypes = {
|
|
|
2394
2214
|
formatMessage: PropTypes.func,
|
|
2395
2215
|
}),
|
|
2396
2216
|
stopValidation: PropTypes.func,
|
|
2397
|
-
// Local template list (e.g. for SMS fallback): when set, TemplatesV2 uses these instead of Redux.
|
|
2398
|
-
// All optional. Pass either localTemplatesConfig (object) or individual props below.
|
|
2399
|
-
localTemplatesConfig: PropTypes.shape({
|
|
2400
|
-
useLocalTemplates: PropTypes.bool,
|
|
2401
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2402
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2403
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2404
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2405
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2406
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2407
|
-
}),
|
|
2408
|
-
useLocalTemplates: PropTypes.bool,
|
|
2409
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2410
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2411
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2412
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2413
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2414
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2415
|
-
onSelectTemplate: PropTypes.func,
|
|
2416
2217
|
};
|
|
2417
2218
|
const mapStatesToProps = () => createStructuredSelector({
|
|
2418
2219
|
isLoading: isLoadingSelector(),
|
|
@@ -2,43 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
$classPrefix: add-creatives-section;
|
|
4
4
|
|
|
5
|
-
/* Local SMS template picker: fill slidebox height; global .v2-pagination-container uses 100vh-20rem and leaves a dead zone inside slideboxes */
|
|
6
|
-
.#{$classPrefix}.creatives-slidebox--local-sms-templates {
|
|
7
|
-
.cap-slide-box-v2-container {
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: column;
|
|
10
|
-
min-height: 0;
|
|
11
|
-
max-height: 100vh;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.slidebox-content-container {
|
|
15
|
-
flex: 1;
|
|
16
|
-
min-height: 0;
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
overflow: hidden;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.slidebox-content-container > div {
|
|
23
|
-
flex: 1;
|
|
24
|
-
min-height: 0;
|
|
25
|
-
display: flex;
|
|
26
|
-
flex-direction: column;
|
|
27
|
-
overflow: hidden;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* TemplatesV2 root: fill slidebox so the template grid can flex instead of using 100vh-based pagination height */
|
|
31
|
-
.slidebox-content-container .creatives-templates-container--local-sms.library-mode {
|
|
32
|
-
flex: 1;
|
|
33
|
-
min-height: 0;
|
|
34
|
-
display: flex;
|
|
35
|
-
flex-direction: column;
|
|
36
|
-
overflow: hidden;
|
|
37
|
-
height: auto;
|
|
38
|
-
max-height: 100%;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
5
|
.#{$classPrefix} {
|
|
43
6
|
&.creatives-library-mode{
|
|
44
7
|
.sms-create-container, .sms-email-container{
|
|
@@ -117,18 +80,5 @@ $classPrefix: add-creatives-section;
|
|
|
117
80
|
}
|
|
118
81
|
|
|
119
82
|
.template-footer-width {
|
|
120
|
-
width: 100
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.slidebox-footer-actions {
|
|
124
|
-
display: flex;
|
|
125
|
-
flex-wrap: nowrap;
|
|
126
|
-
align-items: center;
|
|
127
|
-
gap: 0.75rem;
|
|
128
|
-
min-width: 0;
|
|
129
|
-
|
|
130
|
-
.ant-btn,
|
|
131
|
-
button {
|
|
132
|
-
flex-shrink: 0;
|
|
133
|
-
}
|
|
83
|
+
width: 100%;;
|
|
134
84
|
}
|