@capillarytech/creatives-library 8.0.329 → 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 -14
- package/package.json +1 -1
- package/services/api.js +0 -17
- package/services/tests/api.test.js +0 -85
- package/utils/commonUtils.js +0 -10
- 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 -1006
- 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 -8
- 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 -286
- 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 +1 -34
- package/v2Containers/Rcs/index.js +884 -999
- package/v2Containers/Rcs/index.scss +6 -85
- package/v2Containers/Rcs/messages.js +1 -10
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2453 -41456
- 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 -379
- package/v2Containers/Rcs/utils.js +10 -358
- 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 -609
- package/v2Containers/SmsTrai/Edit/messages.js +4 -9
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2600 -4586
- 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 -172
- package/utils/tests/templateVarUtils.test.js +0 -160
- 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 -107
- 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 -261
- 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 -205
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -251
- 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,8 +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 { RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../../v2Components/CommonTestAndPreview/constants';
|
|
47
50
|
import { CREATIVE } from '../Facebook/constants';
|
|
48
51
|
import { LOYALTY } from '../App/constants';
|
|
49
52
|
import {
|
|
@@ -58,11 +61,6 @@ import { capSagaForFetchSchemaForEntity, capSagaLiquidEntity } from '../Cap/saga
|
|
|
58
61
|
import { v2TemplateSagaWatchGetDefaultBeeTemplates } from '../Templates/sagas';
|
|
59
62
|
import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
|
|
60
63
|
import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
|
|
61
|
-
import SlideBoxWrapper from './CreativesSlideBoxWrapper';
|
|
62
|
-
import {
|
|
63
|
-
computeLiquidFooterUpdateFromFormBuilder,
|
|
64
|
-
getSlideBoxWrapperMarginFromLiquidErrors,
|
|
65
|
-
} from './embeddedSlideboxUtils';
|
|
66
64
|
|
|
67
65
|
import {
|
|
68
66
|
transformChannelPayload,
|
|
@@ -71,24 +69,51 @@ import {
|
|
|
71
69
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
72
70
|
import { BIG_HTML } from '../InApp/constants';
|
|
73
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
|
+
|
|
74
89
|
const classPrefix = 'add-creatives-section';
|
|
75
90
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
76
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
|
+
`;
|
|
77
112
|
export class Creatives extends React.Component {
|
|
78
113
|
constructor(props) {
|
|
79
114
|
super(props);
|
|
80
115
|
|
|
81
|
-
const
|
|
82
|
-
props,
|
|
83
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
84
|
-
get(props, 'useLocalTemplates', false),
|
|
85
|
-
);
|
|
86
|
-
const initialSlidBoxContent = this.getSlideBoxContent({
|
|
87
|
-
mode: props.creativesMode,
|
|
88
|
-
templateData: props.templateData,
|
|
89
|
-
isFullMode: props.isFullMode,
|
|
90
|
-
useLocalTemplates,
|
|
91
|
-
});
|
|
116
|
+
const initialSlidBoxContent = this.getSlideBoxContent({ mode: props.creativesMode, templateData: props.templateData, isFullMode: props.isFullMode });
|
|
92
117
|
|
|
93
118
|
this.state = {
|
|
94
119
|
isLoadingContent: true,
|
|
@@ -135,13 +160,7 @@ export class Creatives extends React.Component {
|
|
|
135
160
|
}
|
|
136
161
|
|
|
137
162
|
componentWillUnmount() {
|
|
138
|
-
|
|
139
|
-
const useLocalTemplates = get(
|
|
140
|
-
this.props,
|
|
141
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
142
|
-
get(this.props, 'useLocalTemplates', false),
|
|
143
|
-
);
|
|
144
|
-
if (isEmbedded && !useLocalTemplates) {
|
|
163
|
+
if (get(this.props, 'location.query.type', '') === "embedded") {
|
|
145
164
|
this.props.templateActions.resetTemplateStoreData();
|
|
146
165
|
}
|
|
147
166
|
this.props.globalActions.clearMetaEntities();
|
|
@@ -743,41 +762,14 @@ export class Creatives extends React.Component {
|
|
|
743
762
|
smsFallBackContent = {},
|
|
744
763
|
creativeName = "",
|
|
745
764
|
channel = constants.RCS,
|
|
746
|
-
rcsCardVarMapped,
|
|
747
765
|
} = templateData || {};
|
|
748
|
-
const
|
|
749
|
-
const firstCardIn = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
750
|
-
const {
|
|
751
|
-
cardDisplayTitle: _omitDispTitleIn,
|
|
752
|
-
cardDisplayDescription: _omitDispDescIn,
|
|
753
|
-
...cardContent
|
|
754
|
-
} = firstCardIn;
|
|
766
|
+
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
755
767
|
const Status = RCS_STATUSES.approved || '';
|
|
756
|
-
const mergedCardVarMapped = (() => {
|
|
757
|
-
const nestedCardVarMapped = cardContent?.cardVarMapped;
|
|
758
|
-
const rootMirrorCardVarMapped = rcsCardVarMapped;
|
|
759
|
-
const nestedRecord =
|
|
760
|
-
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
761
|
-
? nestedCardVarMapped
|
|
762
|
-
: {};
|
|
763
|
-
const rootRecord =
|
|
764
|
-
rootMirrorCardVarMapped != null && typeof rootMirrorCardVarMapped === 'object'
|
|
765
|
-
? rootMirrorCardVarMapped
|
|
766
|
-
: {};
|
|
767
|
-
const mergedFromRootAndNested = { ...rootRecord, ...nestedRecord };
|
|
768
|
-
return Object.keys(mergedFromRootAndNested).length > 0 ? mergedFromRootAndNested : null;
|
|
769
|
-
})();
|
|
770
|
-
// Campaigns (embedded): do not duplicate `cardVarMapped` as root `rcsCardVarMapped` on send —
|
|
771
|
-
// slot map stays on `versions…cardContent[0].cardVarMapped` only. Library full mode keeps root mirror.
|
|
772
|
-
// Use `=== true` so omitted/undefined `isFullMode` does not behave like library (avoids duplicate on approval payload).
|
|
773
|
-
const includeRootRcsCardVarMapped =
|
|
774
|
-
mergedCardVarMapped && isFullModeForRcsPayload === true;
|
|
775
768
|
|
|
776
769
|
creativesTemplateData = {
|
|
777
770
|
type: channel,
|
|
778
771
|
edit: true,
|
|
779
772
|
name: creativeName,
|
|
780
|
-
...(includeRootRcsCardVarMapped ? { rcsCardVarMapped: mergedCardVarMapped } : {}),
|
|
781
773
|
versions: {
|
|
782
774
|
base: {
|
|
783
775
|
content: {
|
|
@@ -787,7 +779,6 @@ export class Creatives extends React.Component {
|
|
|
787
779
|
cardContent: [
|
|
788
780
|
{
|
|
789
781
|
...cardContent,
|
|
790
|
-
...(mergedCardVarMapped ? { cardVarMapped: mergedCardVarMapped } : {}),
|
|
791
782
|
Status,
|
|
792
783
|
},
|
|
793
784
|
],
|
|
@@ -938,10 +929,7 @@ export class Creatives extends React.Component {
|
|
|
938
929
|
return newExpandableDetails;
|
|
939
930
|
}
|
|
940
931
|
|
|
941
|
-
getCreativesData = async (
|
|
942
|
-
const channel = String(
|
|
943
|
-
channelParam || template?.type || get(template, 'value.type') || '',
|
|
944
|
-
).toUpperCase();
|
|
932
|
+
getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
|
|
945
933
|
let templateData = { channel };
|
|
946
934
|
switch (channel) {
|
|
947
935
|
case constants.SMS:
|
|
@@ -1283,101 +1271,26 @@ export class Creatives extends React.Component {
|
|
|
1283
1271
|
break;
|
|
1284
1272
|
case constants.RCS: {
|
|
1285
1273
|
if (template.value) {
|
|
1286
|
-
const {
|
|
1287
|
-
|
|
1288
|
-
const
|
|
1289
|
-
const fromRecords = {
|
|
1290
|
-
...(templateRecords?.smsFallBackContent || {}),
|
|
1291
|
-
...(get(templateRecords, 'versions.base.content.RCS.smsFallBackContent') || {}),
|
|
1292
|
-
};
|
|
1293
|
-
const hasMeaningfulRcsSmsFallback = (smsFallbackPayload) => {
|
|
1294
|
-
if (
|
|
1295
|
-
!smsFallbackPayload
|
|
1296
|
-
|| typeof smsFallbackPayload !== 'object'
|
|
1297
|
-
|| Object.keys(smsFallbackPayload).length === 0
|
|
1298
|
-
) {
|
|
1299
|
-
return false;
|
|
1300
|
-
}
|
|
1301
|
-
const fallbackBodyText = String(
|
|
1302
|
-
smsFallbackPayload.smsContent
|
|
1303
|
-
?? smsFallbackPayload.smsTemplateContent
|
|
1304
|
-
?? smsFallbackPayload.message
|
|
1305
|
-
?? smsFallbackPayload.content
|
|
1306
|
-
?? '',
|
|
1307
|
-
).trim();
|
|
1308
|
-
const fallbackTemplateName = String(
|
|
1309
|
-
smsFallbackPayload.smsTemplateName ?? smsFallbackPayload.templateName ?? '',
|
|
1310
|
-
).trim();
|
|
1311
|
-
const rcsSmsFallbackVarMapped =
|
|
1312
|
-
smsFallbackPayload?.[RCS_SMS_FALLBACK_VAR_MAPPED_PROP];
|
|
1313
|
-
const hasVarMappedEntries =
|
|
1314
|
-
rcsSmsFallbackVarMapped != null
|
|
1315
|
-
&& typeof rcsSmsFallbackVarMapped === 'object'
|
|
1316
|
-
&& Object.keys(rcsSmsFallbackVarMapped).length > 0;
|
|
1317
|
-
return (
|
|
1318
|
-
fallbackBodyText !== ''
|
|
1319
|
-
|| fallbackTemplateName !== ''
|
|
1320
|
-
|| hasVarMappedEntries
|
|
1321
|
-
);
|
|
1322
|
-
};
|
|
1323
|
-
// If submit has only empty strings, do not let it wipe fallback mirrored on templateRecords (library round-trip).
|
|
1324
|
-
const smsFallBackContent = hasMeaningfulRcsSmsFallback(fromSubmit)
|
|
1325
|
-
? { ...fromRecords, ...fromSubmit }
|
|
1326
|
-
: { ...fromSubmit, ...fromRecords };
|
|
1274
|
+
const { name = "", versions = {} } = {
|
|
1275
|
+
} = template.value || {};
|
|
1276
|
+
const smsFallBackContent = get(versions, 'base.content.RCS.smsFallBackContent', {});
|
|
1327
1277
|
const {
|
|
1328
|
-
cardContent
|
|
1278
|
+
cardContent = [],
|
|
1329
1279
|
contentType = "",
|
|
1330
1280
|
cardType = "",
|
|
1331
1281
|
cardSettings = {},
|
|
1332
1282
|
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1333
|
-
const rootRcsCardVarMappedFromSubmit = get(template, 'value.rcsCardVarMapped');
|
|
1334
|
-
const firstCardFromSubmit = Array.isArray(cardContentFromSubmit)
|
|
1335
|
-
? cardContentFromSubmit[0]
|
|
1336
|
-
: null;
|
|
1337
|
-
const cardContent = mapRcsCardContentForConsumerWithResolvedTags(
|
|
1338
|
-
cardContentFromSubmit,
|
|
1339
|
-
rootRcsCardVarMappedFromSubmit,
|
|
1340
|
-
isFullModeForRcsConsumerPayload,
|
|
1341
|
-
);
|
|
1342
1283
|
const rcsContent = {
|
|
1343
1284
|
contentType,
|
|
1344
1285
|
cardType,
|
|
1345
1286
|
cardSettings,
|
|
1346
1287
|
cardContent,
|
|
1347
1288
|
};
|
|
1348
|
-
const cardVarMappedFromFirstRcsCard =
|
|
1349
|
-
firstCardFromSubmit?.cardVarMapped != null
|
|
1350
|
-
&& typeof firstCardFromSubmit.cardVarMapped === 'object'
|
|
1351
|
-
? firstCardFromSubmit.cardVarMapped
|
|
1352
|
-
: null;
|
|
1353
|
-
const includeRootRcsCardVarMappedOnConsumerPayload =
|
|
1354
|
-
cardVarMappedFromFirstRcsCard
|
|
1355
|
-
&& Object.keys(cardVarMappedFromFirstRcsCard).length > 0
|
|
1356
|
-
&& isFullModeForRcsConsumerPayload === true;
|
|
1357
1289
|
templateData = {
|
|
1358
1290
|
channel,
|
|
1359
1291
|
creativeName: name,
|
|
1360
1292
|
rcsContent,
|
|
1361
|
-
...(includeRootRcsCardVarMappedOnConsumerPayload
|
|
1362
|
-
? { rcsCardVarMapped: cardVarMappedFromFirstRcsCard }
|
|
1363
|
-
: {}),
|
|
1364
1293
|
};
|
|
1365
|
-
// Library / campaign consumers round-trip templateData via getTemplateData; include SMS fallback
|
|
1366
|
-
// so reopening the editor restores fallback text and tag mappings.
|
|
1367
|
-
// cap-campaigns-v2 API expects `smsFallBackContent.message` (see normalizeRcsMessageContentForApi).
|
|
1368
|
-
if (hasMeaningfulRcsSmsFallback(smsFallBackContent)) {
|
|
1369
|
-
const smsText =
|
|
1370
|
-
smsFallBackContent.message
|
|
1371
|
-
?? smsFallBackContent.smsContent
|
|
1372
|
-
?? smsFallBackContent.smsTemplateContent
|
|
1373
|
-
?? '';
|
|
1374
|
-
templateData.smsFallBackContent = {
|
|
1375
|
-
...smsFallBackContent,
|
|
1376
|
-
...(String(smsText).trim() !== ''
|
|
1377
|
-
? { message: String(smsText).trim() }
|
|
1378
|
-
: {}),
|
|
1379
|
-
};
|
|
1380
|
-
}
|
|
1381
1294
|
}
|
|
1382
1295
|
}
|
|
1383
1296
|
break;
|
|
@@ -1497,10 +1410,7 @@ export class Creatives extends React.Component {
|
|
|
1497
1410
|
return templateData;
|
|
1498
1411
|
};
|
|
1499
1412
|
|
|
1500
|
-
getSlideBoxContent({ mode, templateData, isFullMode
|
|
1501
|
-
if (useLocalTemplates && mode === 'create' && isEmpty(templateData)) {
|
|
1502
|
-
return 'templates';
|
|
1503
|
-
}
|
|
1413
|
+
getSlideBoxContent({ mode, templateData, isFullMode }) {
|
|
1504
1414
|
let creativesMode = isFullMode ? 'createTemplate' : 'templates';// for library mode templates page is initial mode and for full mode createTemplates
|
|
1505
1415
|
if (mode === 'create' && isFullMode) {
|
|
1506
1416
|
creativesMode = 'createTemplate';
|
|
@@ -1588,110 +1498,24 @@ export class Creatives extends React.Component {
|
|
|
1588
1498
|
getFormData = (template) => {
|
|
1589
1499
|
// Always reset isGetFormData so the child does not re-send form data on every re-render
|
|
1590
1500
|
// (e.g. when user fixes validation error by typing, we must not auto-close the slidebox)
|
|
1591
|
-
this.setState(
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|| ''
|
|
1603
|
-
).toUpperCase();
|
|
1604
|
-
// Library mode: persist last submitted creatives shape so reopening still hydrates the editor
|
|
1605
|
-
// (parent may not merge getCreativesData back into templateData).
|
|
1606
|
-
if (this.props.isFullMode === false && template.value) {
|
|
1607
|
-
if (channel === constants.RCS) {
|
|
1608
|
-
const smsFallBackFromPayload = get(
|
|
1609
|
-
template.value,
|
|
1610
|
-
'versions.base.content.RCS.smsFallBackContent',
|
|
1611
|
-
);
|
|
1612
|
-
const rcsCardVarMappedFromPayload = get(
|
|
1613
|
-
template.value,
|
|
1614
|
-
'versions.base.content.RCS.rcsContent.cardContent[0].cardVarMapped',
|
|
1615
|
-
);
|
|
1616
|
-
next.templateData = {
|
|
1617
|
-
...baseTd,
|
|
1618
|
-
type: constants.RCS,
|
|
1619
|
-
name: template?.value?.name,
|
|
1620
|
-
versions: template?.value?.versions,
|
|
1621
|
-
...(smsFallBackFromPayload != null
|
|
1622
|
-
&& typeof smsFallBackFromPayload === 'object'
|
|
1623
|
-
&& Object.keys(smsFallBackFromPayload).length > 0
|
|
1624
|
-
? { smsFallBackContent: smsFallBackFromPayload }
|
|
1625
|
-
: {}),
|
|
1626
|
-
...(rcsCardVarMappedFromPayload != null
|
|
1627
|
-
&& typeof rcsCardVarMappedFromPayload === 'object'
|
|
1628
|
-
? { rcsCardVarMapped: rcsCardVarMappedFromPayload }
|
|
1629
|
-
: {}),
|
|
1630
|
-
};
|
|
1631
|
-
if (template._id) {
|
|
1632
|
-
next.templateData._id = template._id;
|
|
1633
|
-
}
|
|
1634
|
-
} else if (channel === constants.SMS) {
|
|
1635
|
-
const submittedSmsTemplateValue = template?.value;
|
|
1636
|
-
const smsVersions =
|
|
1637
|
-
submittedSmsTemplateValue?.history != null
|
|
1638
|
-
? submittedSmsTemplateValue
|
|
1639
|
-
: {
|
|
1640
|
-
base: submittedSmsTemplateValue?.base,
|
|
1641
|
-
history: submittedSmsTemplateValue?.base
|
|
1642
|
-
? [submittedSmsTemplateValue.base]
|
|
1643
|
-
: [],
|
|
1644
|
-
};
|
|
1645
|
-
next.templateData = {
|
|
1646
|
-
...baseTd,
|
|
1647
|
-
type: constants.SMS,
|
|
1648
|
-
name: baseTd?.name || 'Campaign message SMS content',
|
|
1649
|
-
versions: smsVersions,
|
|
1650
|
-
};
|
|
1651
|
-
if (template?._id) {
|
|
1652
|
-
next.templateData._id = template._id;
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
return next;
|
|
1657
|
-
},
|
|
1658
|
-
() => {
|
|
1659
|
-
if (!template.validity) {
|
|
1660
|
-
return;
|
|
1661
|
-
}
|
|
1662
|
-
const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
|
|
1663
|
-
const channelForConsumer = String(
|
|
1664
|
-
templateData.type
|
|
1665
|
-
|| template.type
|
|
1666
|
-
|| get(template, 'value.type')
|
|
1667
|
-
|| '',
|
|
1668
|
-
).toUpperCase();
|
|
1669
|
-
const creativesData = this.getCreativesData(
|
|
1670
|
-
channelForConsumer,
|
|
1671
|
-
template,
|
|
1672
|
-
this.state.templateData || template,
|
|
1673
|
-
);// convers data to consumer understandable format
|
|
1674
|
-
creativesData.then((data) => {
|
|
1675
|
-
this.logGTMEvent(channelForConsumer, data);
|
|
1676
|
-
this.processCentralCommsMetaId(channelForConsumer, data, {
|
|
1677
|
-
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);
|
|
1678
1512
|
});
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
|
|
1513
|
+
},
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1682
1516
|
}
|
|
1683
1517
|
|
|
1684
|
-
processCentralCommsMetaId = (channel, creativesData
|
|
1685
|
-
const { closeSlideBoxAfterSubmit = false } = options;
|
|
1686
|
-
const maybeCloseLibrarySlideBox = () => {
|
|
1687
|
-
if (
|
|
1688
|
-
closeSlideBoxAfterSubmit
|
|
1689
|
-
&& this.props.isFullMode === false
|
|
1690
|
-
&& typeof this.handleCloseSlideBox === 'function'
|
|
1691
|
-
) {
|
|
1692
|
-
this.handleCloseSlideBox();
|
|
1693
|
-
}
|
|
1694
|
-
};
|
|
1518
|
+
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1695
1519
|
// Create the payload for the centralcommnsmetaId API call
|
|
1696
1520
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1697
1521
|
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
@@ -1717,7 +1541,6 @@ export class Creatives extends React.Component {
|
|
|
1717
1541
|
if (result?.status?.code === 200) {
|
|
1718
1542
|
setMetaData(result);
|
|
1719
1543
|
this.props.getCreativesData(creativesData);
|
|
1720
|
-
maybeCloseLibrarySlideBox();
|
|
1721
1544
|
} else {
|
|
1722
1545
|
CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
|
|
1723
1546
|
}
|
|
@@ -1728,7 +1551,6 @@ export class Creatives extends React.Component {
|
|
|
1728
1551
|
} else {
|
|
1729
1552
|
// If not a loyalty module or different action, should work as usual
|
|
1730
1553
|
this.props.getCreativesData(creativesData);
|
|
1731
|
-
maybeCloseLibrarySlideBox();
|
|
1732
1554
|
}
|
|
1733
1555
|
};
|
|
1734
1556
|
|
|
@@ -1761,9 +1583,7 @@ export class Creatives extends React.Component {
|
|
|
1761
1583
|
}
|
|
1762
1584
|
this.setState((prevState) => ({
|
|
1763
1585
|
...prevState,
|
|
1764
|
-
|
|
1765
|
-
// Undefined isFullMode defaults to full-mode close behavior (clear templateData).
|
|
1766
|
-
...(this.props.isFullMode !== false ? { templateData: undefined } : {}),
|
|
1586
|
+
templateData: undefined,
|
|
1767
1587
|
showSlideBox: false,
|
|
1768
1588
|
liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
|
|
1769
1589
|
isLiquidValidationError: false,
|
|
@@ -1974,12 +1794,21 @@ export class Creatives extends React.Component {
|
|
|
1974
1794
|
}
|
|
1975
1795
|
|
|
1976
1796
|
showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
|
|
1977
|
-
const
|
|
1978
|
-
|
|
1979
|
-
|
|
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
|
|
1980
1811
|
});
|
|
1981
|
-
if (next == null) return;
|
|
1982
|
-
this.setState(next);
|
|
1983
1812
|
}
|
|
1984
1813
|
|
|
1985
1814
|
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
@@ -2102,11 +1931,6 @@ export class Creatives extends React.Component {
|
|
|
2102
1931
|
inAppEditorType,
|
|
2103
1932
|
htmlEditorValidationState,
|
|
2104
1933
|
} = this.state;
|
|
2105
|
-
const useLocalTemplates = get(
|
|
2106
|
-
this.props,
|
|
2107
|
-
'localTemplatesConfig.useLocalTemplates',
|
|
2108
|
-
get(this.props, 'useLocalTemplates', false),
|
|
2109
|
-
);
|
|
2110
1934
|
const {
|
|
2111
1935
|
isFullMode,
|
|
2112
1936
|
creativesMode,
|
|
@@ -2158,7 +1982,14 @@ export class Creatives extends React.Component {
|
|
|
2158
1982
|
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
2159
1983
|
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
2160
1984
|
|
|
2161
|
-
|
|
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;
|
|
2162
1993
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
2163
1994
|
|
|
2164
1995
|
// Compute anonymous user type and channel restrictions
|
|
@@ -2187,10 +2018,7 @@ export class Creatives extends React.Component {
|
|
|
2187
2018
|
<SlideBoxWrapper
|
|
2188
2019
|
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
2189
2020
|
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
2190
|
-
className={classnames(
|
|
2191
|
-
`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`,
|
|
2192
|
-
useLocalTemplates && slidBoxContent === 'templates' && 'creatives-slidebox--local-sms-templates',
|
|
2193
|
-
)}
|
|
2021
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
2194
2022
|
>
|
|
2195
2023
|
<CapSlideBox
|
|
2196
2024
|
header={
|
|
@@ -2215,13 +2043,12 @@ export class Creatives extends React.Component {
|
|
|
2215
2043
|
smsRegister={smsRegister}
|
|
2216
2044
|
handleClose={this.handleCloseSlideBox}
|
|
2217
2045
|
moduleType={this.props.messageDetails?.type}
|
|
2218
|
-
useLocalTemplates={useLocalTemplates}
|
|
2219
2046
|
/>
|
|
2220
2047
|
)}
|
|
2221
2048
|
content={(
|
|
2222
2049
|
<SlideBoxContent
|
|
2223
2050
|
key="creatives-container-slidebox-content"
|
|
2224
|
-
onSelectTemplate={this.
|
|
2051
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
2225
2052
|
onCreateComplete={getCreativesData}
|
|
2226
2053
|
onPreviewTemplate={this.onPreviewTemplate}
|
|
2227
2054
|
slidBoxContent={slidBoxContent}
|
|
@@ -2297,8 +2124,7 @@ export class Creatives extends React.Component {
|
|
|
2297
2124
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2298
2125
|
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
2299
2126
|
onPersonalizationTokensChange={this.handlePersonalizationTokensChange}
|
|
2300
|
-
|
|
2301
|
-
/>
|
|
2127
|
+
/>
|
|
2302
2128
|
)}
|
|
2303
2129
|
footer={this.shouldShowFooter() ? (
|
|
2304
2130
|
<SlideBoxFooter
|
|
@@ -2388,25 +2214,6 @@ Creatives.propTypes = {
|
|
|
2388
2214
|
formatMessage: PropTypes.func,
|
|
2389
2215
|
}),
|
|
2390
2216
|
stopValidation: PropTypes.func,
|
|
2391
|
-
// Local template list (e.g. for SMS fallback): when set, TemplatesV2 uses these instead of Redux.
|
|
2392
|
-
// All optional. Pass either localTemplatesConfig (object) or individual props below.
|
|
2393
|
-
localTemplatesConfig: PropTypes.shape({
|
|
2394
|
-
useLocalTemplates: PropTypes.bool,
|
|
2395
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2396
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2397
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2398
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2399
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2400
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2401
|
-
}),
|
|
2402
|
-
useLocalTemplates: PropTypes.bool,
|
|
2403
|
-
localTemplates: PropTypes.arrayOf(PropTypes.object),
|
|
2404
|
-
localTemplatesLoading: PropTypes.bool,
|
|
2405
|
-
localTemplatesFilterContent: PropTypes.node,
|
|
2406
|
-
localTemplatesSentinelContent: PropTypes.node,
|
|
2407
|
-
localTemplatesScrollContainerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
2408
|
-
localTemplatesUseSkeleton: PropTypes.bool,
|
|
2409
|
-
onSelectTemplate: PropTypes.func,
|
|
2410
2217
|
};
|
|
2411
2218
|
const mapStatesToProps = () => createStructuredSelector({
|
|
2412
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
|
}
|