@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.331
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 +2 -2
- 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 +100 -298
- 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 +901 -1144
- 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,56 +762,25 @@ export class Creatives extends React.Component {
|
|
|
744
762
|
smsFallBackContent = {},
|
|
745
763
|
creativeName = "",
|
|
746
764
|
channel = constants.RCS,
|
|
747
|
-
|
|
765
|
+
accountId = "",
|
|
748
766
|
} = templateData || {};
|
|
749
|
-
const
|
|
750
|
-
const firstCardIn = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
751
|
-
const {
|
|
752
|
-
cardDisplayTitle: _omitDispTitleIn,
|
|
753
|
-
cardDisplayDescription: _omitDispDescIn,
|
|
754
|
-
...cardContent
|
|
755
|
-
} = firstCardIn;
|
|
767
|
+
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
756
768
|
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
769
|
|
|
782
770
|
creativesTemplateData = {
|
|
783
771
|
type: channel,
|
|
784
772
|
edit: true,
|
|
785
773
|
name: creativeName,
|
|
786
|
-
...(includeRootRcsCardVarMapped ? { rcsCardVarMapped: mergedCardVarMapped } : {}),
|
|
787
774
|
versions: {
|
|
788
775
|
base: {
|
|
789
776
|
content: {
|
|
790
777
|
RCS: {
|
|
791
778
|
rcsContent: {
|
|
792
779
|
...rcsContent,
|
|
780
|
+
...(accountId && !isFullMode && { accountId }),
|
|
793
781
|
cardContent: [
|
|
794
782
|
{
|
|
795
783
|
...cardContent,
|
|
796
|
-
...(mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
797
784
|
Status,
|
|
798
785
|
},
|
|
799
786
|
],
|
|
@@ -944,10 +931,7 @@ export class Creatives extends React.Component {
|
|
|
944
931
|
return newExpandableDetails;
|
|
945
932
|
}
|
|
946
933
|
|
|
947
|
-
getCreativesData = async (
|
|
948
|
-
const channel = String(
|
|
949
|
-
channelParam || template?.type || get(template, 'value.type') || '',
|
|
950
|
-
).toUpperCase();
|
|
934
|
+
getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
|
|
951
935
|
let templateData = { channel };
|
|
952
936
|
switch (channel) {
|
|
953
937
|
case constants.SMS:
|
|
@@ -1241,7 +1225,7 @@ export class Creatives extends React.Component {
|
|
|
1241
1225
|
};
|
|
1242
1226
|
}
|
|
1243
1227
|
break;
|
|
1244
|
-
case constants.FACEBOOK:
|
|
1228
|
+
case constants.FACEBOOK:
|
|
1245
1229
|
if (template.value) {
|
|
1246
1230
|
const FacebookAd = template?.value?.versions?.base?.content?.FacebookAd;
|
|
1247
1231
|
const { type } = FacebookAd[0];
|
|
@@ -1285,109 +1269,34 @@ export class Creatives extends React.Component {
|
|
|
1285
1269
|
selectedMarketingObjective: template.value.selectedMarketingObjective,
|
|
1286
1270
|
};
|
|
1287
1271
|
}
|
|
1288
|
-
}
|
|
1289
1272
|
break;
|
|
1290
|
-
case constants.RCS:
|
|
1273
|
+
case constants.RCS:
|
|
1291
1274
|
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 };
|
|
1275
|
+
const { name = "", versions = {} } = {
|
|
1276
|
+
} = template.value || {};
|
|
1277
|
+
const smsFallBackContent = get(versions, 'base.content.RCS.smsFallBackContent', {});
|
|
1333
1278
|
const {
|
|
1334
|
-
cardContent
|
|
1279
|
+
cardContent = [],
|
|
1335
1280
|
contentType = "",
|
|
1336
1281
|
cardType = "",
|
|
1337
1282
|
cardSettings = {},
|
|
1283
|
+
accountId = "",
|
|
1338
1284
|
} = 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
1285
|
const rcsContent = {
|
|
1349
1286
|
contentType,
|
|
1350
1287
|
cardType,
|
|
1351
1288
|
cardSettings,
|
|
1352
1289
|
cardContent,
|
|
1353
1290
|
};
|
|
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
1291
|
templateData = {
|
|
1364
1292
|
channel,
|
|
1365
1293
|
creativeName: name,
|
|
1366
1294
|
rcsContent,
|
|
1367
|
-
|
|
1368
|
-
? { rcsCardVarMapped: cardVarMappedFromFirstRcsCard }
|
|
1369
|
-
: {}),
|
|
1295
|
+
accountId,
|
|
1370
1296
|
};
|
|
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
1297
|
}
|
|
1388
|
-
}
|
|
1389
1298
|
break;
|
|
1390
|
-
case constants.ZALO:
|
|
1299
|
+
case constants.ZALO:
|
|
1391
1300
|
if (template.value) {
|
|
1392
1301
|
templateData = {
|
|
1393
1302
|
...template.value,
|
|
@@ -1396,7 +1305,6 @@ export class Creatives extends React.Component {
|
|
|
1396
1305
|
delete templateData.type;
|
|
1397
1306
|
}
|
|
1398
1307
|
}
|
|
1399
|
-
}
|
|
1400
1308
|
break;
|
|
1401
1309
|
case constants.WEBPUSH: {
|
|
1402
1310
|
if (template.value) {
|
|
@@ -1503,10 +1411,7 @@ export class Creatives extends React.Component {
|
|
|
1503
1411
|
return templateData;
|
|
1504
1412
|
};
|
|
1505
1413
|
|
|
1506
|
-
getSlideBoxContent({ mode, templateData, isFullMode
|
|
1507
|
-
if (useLocalTemplates && mode === 'create' && isEmpty(templateData)) {
|
|
1508
|
-
return 'templates';
|
|
1509
|
-
}
|
|
1414
|
+
getSlideBoxContent({ mode, templateData, isFullMode }) {
|
|
1510
1415
|
let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
|
|
1511
1416
|
if (mode === 'create' && isFullMode) {
|
|
1512
1417
|
creativesMode = 'createTemplate';
|
|
@@ -1594,110 +1499,24 @@ export class Creatives extends React.Component {
|
|
|
1594
1499
|
getFormData = (template) => {
|
|
1595
1500
|
// Always reset isGetFormData so the child does not re-send form data on every re-render
|
|
1596
1501
|
// (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,
|
|
1502
|
+
this.setState({ isGetFormData: false });
|
|
1503
|
+
if (template.validity) {
|
|
1504
|
+
this.setState(
|
|
1505
|
+
{},
|
|
1506
|
+
() => {
|
|
1507
|
+
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1508
|
+
const channel = templateData.type;
|
|
1509
|
+
const creativesData = this.getCreativesData(channel, template, templateData);// convers data to consumer understandable format
|
|
1510
|
+
creativesData.then((data) => {
|
|
1511
|
+
this.logGTMEvent(channel, data);
|
|
1512
|
+
this.processCentralCommsMetaId(channel, data);
|
|
1684
1513
|
});
|
|
1685
|
-
}
|
|
1686
|
-
|
|
1687
|
-
|
|
1514
|
+
},
|
|
1515
|
+
);
|
|
1516
|
+
}
|
|
1688
1517
|
}
|
|
1689
1518
|
|
|
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
|
-
};
|
|
1519
|
+
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1701
1520
|
// Create the payload for the centralcommnsmetaId API call
|
|
1702
1521
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1703
1522
|
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
@@ -1723,7 +1542,6 @@ export class Creatives extends React.Component {
|
|
|
1723
1542
|
if (result?.status?.code === 200) {
|
|
1724
1543
|
setMetaData(result);
|
|
1725
1544
|
this.props.getCreativesData(creativesData);
|
|
1726
|
-
maybeCloseLibrarySlideBox();
|
|
1727
1545
|
} else {
|
|
1728
1546
|
CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
|
|
1729
1547
|
}
|
|
@@ -1734,7 +1552,6 @@ export class Creatives extends React.Component {
|
|
|
1734
1552
|
} else {
|
|
1735
1553
|
// If not a loyalty module or different action, should work as usual
|
|
1736
1554
|
this.props.getCreativesData(creativesData);
|
|
1737
|
-
maybeCloseLibrarySlideBox();
|
|
1738
1555
|
}
|
|
1739
1556
|
};
|
|
1740
1557
|
|
|
@@ -1767,9 +1584,7 @@ export class Creatives extends React.Component {
|
|
|
1767
1584
|
}
|
|
1768
1585
|
this.setState((prevState) => ({
|
|
1769
1586
|
...prevState,
|
|
1770
|
-
|
|
1771
|
-
// Undefined isFullMode defaults to full-mode close behavior (clear templateData).
|
|
1772
|
-
...(this.props.isFullMode !== false ? { templateData: undefined } : {}),
|
|
1587
|
+
templateData: undefined,
|
|
1773
1588
|
showSlideBox: false,
|
|
1774
1589
|
liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
|
|
1775
1590
|
isLiquidValidationError: false,
|
|
@@ -1980,12 +1795,21 @@ export class Creatives extends React.Component {
|
|
|
1980
1795
|
}
|
|
1981
1796
|
|
|
1982
1797
|
showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
|
|
1983
|
-
const
|
|
1984
|
-
|
|
1985
|
-
|
|
1798
|
+
const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
|
|
1799
|
+
const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
|
|
1800
|
+
const hasLiquid = !isDeepEmpty(liquidMsgs);
|
|
1801
|
+
const hasStandard = !isDeepEmpty(standardMsgs);
|
|
1802
|
+
const isLiquidValidationError = hasLiquid || hasStandard;
|
|
1803
|
+
// Don't overwrite existing liquid error with empty only for Mobile Push OLD (FormBuilder/clear calls empty there); SMS/others clear on input change
|
|
1804
|
+
const isMobilePush = this.state.currentChannel?.toUpperCase() === constants.MOBILE_PUSH;
|
|
1805
|
+
if (!hasLiquid && !hasStandard && this.state.isLiquidValidationError && isMobilePush) {
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
this.setState({
|
|
1809
|
+
isLiquidValidationError,
|
|
1810
|
+
liquidErrorMessage: errorMessagesFromFormBuilder,
|
|
1811
|
+
activeFormBuilderTab: currentFormBuilderTab === 1 ? constants.ANDROID : (currentFormBuilderTab === 2 ? constants.IOS : null), // Update activeFormBuilderTab, default to 1 if undefined
|
|
1986
1812
|
});
|
|
1987
|
-
if (next == null) return;
|
|
1988
|
-
this.setState(next);
|
|
1989
1813
|
}
|
|
1990
1814
|
|
|
1991
1815
|
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
@@ -2108,11 +1932,6 @@ export class Creatives extends React.Component {
|
|
|
2108
1932
|
inAppEditorType,
|
|
2109
1933
|
htmlEditorValidationState,
|
|
2110
1934
|
} = this.state;
|
|
2111
|
-
const useLocalTemplates = get(
|
|
2112
|
-
this.props,
|
|
2113
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
2114
|
-
get(this.props, 'useLocalTemplates', false),
|
|
2115
|
-
);
|
|
2116
1935
|
const {
|
|
2117
1936
|
isFullMode,
|
|
2118
1937
|
creativesMode,
|
|
@@ -2164,7 +1983,14 @@ export class Creatives extends React.Component {
|
|
|
2164
1983
|
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
2165
1984
|
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
2166
1985
|
|
|
2167
|
-
|
|
1986
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
1987
|
+
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
1988
|
+
? CAP_SPACE_64
|
|
1989
|
+
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
1990
|
+
? CAP_SPACE_56
|
|
1991
|
+
: get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
1992
|
+
? CAP_SPACE_32
|
|
1993
|
+
: 0;
|
|
2168
1994
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
2169
1995
|
|
|
2170
1996
|
// Compute anonymous user type and channel restrictions
|
|
@@ -2193,10 +2019,7 @@ export class Creatives extends React.Component {
|
|
|
2193
2019
|
<SlideBoxWrapper
|
|
2194
2020
|
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
2195
2021
|
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
|
-
)}
|
|
2022
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
2200
2023
|
>
|
|
2201
2024
|
<CapSlideBox
|
|
2202
2025
|
header={
|
|
@@ -2221,13 +2044,12 @@ export class Creatives extends React.Component {
|
|
|
2221
2044
|
smsRegister={smsRegister}
|
|
2222
2045
|
handleClose={this.handleCloseSlideBox}
|
|
2223
2046
|
moduleType={this.props.messageDetails?.type}
|
|
2224
|
-
useLocalTemplates={useLocalTemplates}
|
|
2225
2047
|
/>
|
|
2226
2048
|
)}
|
|
2227
2049
|
content={(
|
|
2228
2050
|
<SlideBoxContent
|
|
2229
2051
|
key="creatives-container-slidebox-content"
|
|
2230
|
-
onSelectTemplate={this.
|
|
2052
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
2231
2053
|
onCreateComplete={getCreativesData}
|
|
2232
2054
|
onPreviewTemplate={this.onPreviewTemplate}
|
|
2233
2055
|
slidBoxContent={slidBoxContent}
|
|
@@ -2303,8 +2125,7 @@ export class Creatives extends React.Component {
|
|
|
2303
2125
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2304
2126
|
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
2305
2127
|
onPersonalizationTokensChange={this.handlePersonalizationTokensChange}
|
|
2306
|
-
|
|
2307
|
-
/>
|
|
2128
|
+
/>
|
|
2308
2129
|
)}
|
|
2309
2130
|
footer={this.shouldShowFooter() ? (
|
|
2310
2131
|
<SlideBoxFooter
|
|
@@ -2394,25 +2215,6 @@ Creatives.propTypes = {
|
|
|
2394
2215
|
formatMessage: PropTypes.func,
|
|
2395
2216
|
}),
|
|
2396
2217
|
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
2218
|
};
|
|
2417
2219
|
const mapStatesToProps = () => createStructuredSelector({
|
|
2418
2220
|
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
|
}
|