@capillarytech/creatives-library 7.17.195 → 7.17.196
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/config/app.js +2 -0
- package/containers/App/constants.js +1 -0
- package/initialState.js +3 -0
- package/package.json +1 -1
- package/services/api.js +20 -0
- package/services/tests/api.test.js +148 -0
- package/utils/common.js +7 -0
- package/utils/tagValidations.js +99 -1
- package/utils/tests/tagValidations.test.js +392 -2
- package/v2Components/Ckeditor/index.js +1 -1
- package/v2Components/ErrorInfoNote/index.js +89 -0
- package/v2Components/ErrorInfoNote/messages.js +29 -0
- package/v2Components/ErrorInfoNote/style.scss +72 -0
- package/v2Components/FormBuilder/_formBuilder.scss +4 -1
- package/v2Components/FormBuilder/index.js +170 -69
- package/v2Components/FormBuilder/messages.js +8 -0
- package/v2Containers/Cap/actions.js +8 -0
- package/v2Containers/Cap/constants.js +4 -0
- package/v2Containers/Cap/mockData.js +74 -0
- package/v2Containers/Cap/reducer.js +12 -0
- package/v2Containers/Cap/sagas.js +28 -1
- package/v2Containers/Cap/selectors.js +5 -0
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +1 -0
- package/v2Containers/Cap/tests/reducer.test.js +50 -0
- package/v2Containers/Cap/tests/saga.test.js +81 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -3
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +40 -17
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +45 -6
- package/v2Containers/CreativesContainer/index.scss +13 -1
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +16 -0
- package/v2Containers/Email/_email.scss +3 -0
- package/v2Containers/Email/index.js +2 -0
- package/v2Containers/EmailWrapper/index.js +3 -0
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +3 -0
- package/v2Containers/MobilePush/Edit/constants.js +0 -5
- package/v2Containers/MobilePush/Edit/index.js +15 -73
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +93 -0
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +12 -0
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +12 -0
|
@@ -6,9 +6,20 @@ import {
|
|
|
6
6
|
REQUEST,
|
|
7
7
|
SUCCESS,
|
|
8
8
|
FAILURE,
|
|
9
|
+
GET_LIQUID_TAGS_SUCCESS,
|
|
10
|
+
GET_LIQUID_TAGS_FAILURE,
|
|
11
|
+
GET_LIQUID_TAGS_REQUEST,
|
|
12
|
+
GET_SCHEMA_FOR_ENTITY_SUCCESS,
|
|
9
13
|
} from '../constants';
|
|
10
14
|
import reducer from '../reducer';
|
|
11
15
|
import initialState from '../../../initialState';
|
|
16
|
+
import {
|
|
17
|
+
expectedStateGetLiquidTagsRequest,
|
|
18
|
+
expectedStateGetLiquidTagsFailure,
|
|
19
|
+
expectedStateGetLiquidTagsSuccess,
|
|
20
|
+
expectedStateGetSchemaForEntitySuccessTAG,
|
|
21
|
+
expectedStateGetSchemaForEntitySuccess
|
|
22
|
+
} from '../mockData';
|
|
12
23
|
|
|
13
24
|
const mockedInitialState = fromJS(initialState.cap);
|
|
14
25
|
|
|
@@ -56,4 +67,43 @@ describe('should handle GET_SUPPORT_VIDEOS_CONFIG', () => {
|
|
|
56
67
|
demoVideoAndLinkJSONStatus: FAILURE,
|
|
57
68
|
});
|
|
58
69
|
});
|
|
70
|
+
it('handles the GET_LIQUID_TAGS_REQUEST action', () => {
|
|
71
|
+
const action = {
|
|
72
|
+
type: GET_LIQUID_TAGS_REQUEST,
|
|
73
|
+
};
|
|
74
|
+
expect(reducer(mockedInitialState, action).toJS()).toEqual(expectedStateGetLiquidTagsRequest);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('handles the GET_LIQUID_TAGS_FAILURE action', () => {
|
|
78
|
+
const action = {
|
|
79
|
+
type: GET_LIQUID_TAGS_FAILURE,
|
|
80
|
+
};
|
|
81
|
+
expect(reducer(mockedInitialState, action).toJS()).toEqual(expectedStateGetLiquidTagsFailure);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('handles the GET_LIQUID_TAGS_SUCCESS action', () => {
|
|
85
|
+
const action = {
|
|
86
|
+
type: GET_LIQUID_TAGS_SUCCESS,
|
|
87
|
+
};
|
|
88
|
+
expect(reducer(mockedInitialState, action).toJS()).toEqual(expectedStateGetLiquidTagsSuccess);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('handles the GET_SCHEMA_FOR_ENTITY_SUCCESS action with action type as TAG', () => {
|
|
92
|
+
const action = {
|
|
93
|
+
type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
|
|
94
|
+
data: {metaEntities:{standard:{"random": "32"}}},
|
|
95
|
+
entityType: "TAG"
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
expect(reducer(mockedInitialState, action).toJS()).toEqual(expectedStateGetSchemaForEntitySuccessTAG);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('handles the GET_SCHEMA_FOR_ENTITY_SUCCESS action', () => {
|
|
102
|
+
const action = {
|
|
103
|
+
type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
|
|
104
|
+
data: {metaEntities:{standard:{"random": "32"}}},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
expect(reducer(mockedInitialState, action).toJS()).toEqual(expectedStateGetSchemaForEntitySuccess);
|
|
108
|
+
});
|
|
59
109
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { take, fork, cancel, takeLatest } from 'redux-saga/effects';
|
|
2
2
|
import { expectSaga } from 'redux-saga-test-plan';
|
|
3
3
|
import * as matchers from 'redux-saga-test-plan/matchers';
|
|
4
|
-
import { authorize, loginFlow, fetchSchemaForEntity, getSupportVideosConfig, watchForGetVideosConfig, watchFetchSchemaForEntity } from '../sagas';
|
|
4
|
+
import { authorize, loginFlow, fetchSchemaForEntity, getSupportVideosConfig, watchForGetVideosConfig, watchFetchSchemaForEntity,watchLiquidEntity, getLiquidTags } from '../sagas';
|
|
5
5
|
import { throwError } from 'redux-saga-test-plan/providers';
|
|
6
6
|
import * as api from '../../../services/api';
|
|
7
7
|
import {
|
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
GET_SUPPORT_VIDEOS_CONFIG_SUCCESS,
|
|
15
15
|
GET_SUPPORT_VIDEOS_CONFIG_FAILURE,
|
|
16
16
|
GET_SCHEMA_FOR_ENTITY_REQUEST,
|
|
17
|
+
GET_LIQUID_TAGS_SUCCESS,
|
|
18
|
+
GET_LIQUID_TAGS_FAILURE,
|
|
19
|
+
GET_LIQUID_TAGS_REQUEST,
|
|
17
20
|
} from '../constants';
|
|
18
21
|
import { callback, error, error2, videoConfigData } from '../../mockdata';
|
|
19
22
|
|
|
@@ -207,4 +210,81 @@ describe('watchFetchSchemaForEntity saga', () => {
|
|
|
207
210
|
takeLatest(GET_SCHEMA_FOR_ENTITY_REQUEST, fetchSchemaForEntity),
|
|
208
211
|
);
|
|
209
212
|
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
describe('getLiquidTags saga', () => {
|
|
217
|
+
it('handles successful API response', () => {
|
|
218
|
+
const action = { data: 'templateContent', callback: () =>{}};
|
|
219
|
+
const result = { result :{errors: [{message: "error in content"}]} };
|
|
220
|
+
|
|
221
|
+
expectSaga(getLiquidTags, action)
|
|
222
|
+
.provide([
|
|
223
|
+
[matchers.call.fn(api.getLiquidTags, 'templateContent'), result],
|
|
224
|
+
[matchers.call.fn(api.askAiraForLiquid, { templateContent: 'templateContent', errorMessage: result?.result?.errors[0]?.message }), { result: { errors: [] } }],
|
|
225
|
+
])
|
|
226
|
+
.call.fn(action.callback, result)
|
|
227
|
+
.put({ type: GET_LIQUID_TAGS_SUCCESS })
|
|
228
|
+
.run();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('handles successful API response for askAira', () => {
|
|
232
|
+
const action = { data: 'templateContent', callback: () =>{}};
|
|
233
|
+
const result = { result :{errors: [{message: "error in content"}]} };
|
|
234
|
+
|
|
235
|
+
expectSaga(getLiquidTags, action)
|
|
236
|
+
.provide([
|
|
237
|
+
[matchers.call.fn(api.getLiquidTags, 'templateContent'), result],
|
|
238
|
+
[matchers.call.fn(api.askAiraForLiquid, { templateContent: 'templateContent', errorMessage: result?.result?.errors[0]?.message }), {result: { errors: [{message: "Something went wrong"}]} }],
|
|
239
|
+
])
|
|
240
|
+
.call.fn(action.callback, result)
|
|
241
|
+
.put({ type: GET_LIQUID_TAGS_SUCCESS })
|
|
242
|
+
.run();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('handles API response with errors', () => {
|
|
246
|
+
const action = { data: 'templateContent' };
|
|
247
|
+
const result = { errors: [{ message: 'Error message' }] };
|
|
248
|
+
|
|
249
|
+
expectSaga(getLiquidTags, action)
|
|
250
|
+
.provide([
|
|
251
|
+
[matchers.call.fn(api.getLiquidTags, 'templateContent'), result],
|
|
252
|
+
[matchers.call.fn(api.askAiraForLiquid, { templateContent: 'templateContent', errorMessage: result.errors[0].message }), {result: { errors: [{message: "Something went wrong"}]} }],
|
|
253
|
+
])
|
|
254
|
+
.not.call.fn(action.callback, result)
|
|
255
|
+
.put({ type: GET_LIQUID_TAGS_FAILURE, error: true })
|
|
256
|
+
.run();
|
|
257
|
+
});
|
|
258
|
+
it('handles API response with undefined', () => {
|
|
259
|
+
const action = { data: 'templateContent' };
|
|
260
|
+
const result = undefined;
|
|
261
|
+
|
|
262
|
+
expectSaga(getLiquidTags, action)
|
|
263
|
+
.provide([
|
|
264
|
+
[matchers.call.fn(api.getLiquidTags, 'templateContent'), result],
|
|
265
|
+
])
|
|
266
|
+
.not.call.fn(action.callback, result)
|
|
267
|
+
.put({ type: GET_LIQUID_TAGS_FAILURE, error: true })
|
|
268
|
+
.run();
|
|
269
|
+
});
|
|
270
|
+
it('handles error thrown during API call', () => {
|
|
271
|
+
const action = { data: 'templateContent' };
|
|
272
|
+
const error = new Error('API error');
|
|
273
|
+
|
|
274
|
+
expectSaga(getLiquidTags, action)
|
|
275
|
+
.provide([
|
|
276
|
+
[matchers.call.fn(api.getLiquidTags, 'templateContent'), throwError(error)],
|
|
277
|
+
])
|
|
278
|
+
.put({ type: GET_LIQUID_TAGS_FAILURE, error })
|
|
279
|
+
.run();
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('watchForGetLiquidTags saga', () => {
|
|
284
|
+
const generator = watchLiquidEntity();
|
|
285
|
+
it('should call watchers functions', () => {
|
|
286
|
+
expect(generator.next().value).toEqual(
|
|
287
|
+
takeLatest(GET_LIQUID_TAGS_REQUEST, getLiquidTags),
|
|
288
|
+
);
|
|
289
|
+
});
|
|
210
290
|
});
|
|
@@ -153,7 +153,7 @@ export function SlideBoxContent(props) {
|
|
|
153
153
|
hideTestAndPreviewBtn,
|
|
154
154
|
getCmsTemplatesInProgress = false,
|
|
155
155
|
moduleType,
|
|
156
|
-
|
|
156
|
+
showLiquidErrorInFooter,
|
|
157
157
|
} = props;
|
|
158
158
|
const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
159
159
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
@@ -602,6 +602,7 @@ export function SlideBoxContent(props) {
|
|
|
602
602
|
onTestContentClicked={onTestContentClicked}
|
|
603
603
|
getCmsTemplatesInProgress={getCmsTemplatesInProgress}
|
|
604
604
|
moduleType={moduleType}
|
|
605
|
+
showLiquidErrorInFooter={showLiquidErrorInFooter}
|
|
605
606
|
/>
|
|
606
607
|
)}
|
|
607
608
|
{(isEditEmailWithId || isEmailEditWithContent) && (
|
|
@@ -629,6 +630,7 @@ export function SlideBoxContent(props) {
|
|
|
629
630
|
onPreviewContentClicked={onPreviewContentClicked}
|
|
630
631
|
onTestContentClicked={onTestContentClicked}
|
|
631
632
|
moduleType={moduleType}
|
|
633
|
+
showLiquidErrorInFooter={showLiquidErrorInFooter}
|
|
632
634
|
/>
|
|
633
635
|
)}
|
|
634
636
|
{isEditMPush &&
|
|
@@ -653,7 +655,6 @@ export function SlideBoxContent(props) {
|
|
|
653
655
|
onTestContentClicked={onTestContentClicked}
|
|
654
656
|
type={type}
|
|
655
657
|
hideTestAndPreviewBtn={hideTestAndPreviewBtn}
|
|
656
|
-
creativesMode={creativesMode}
|
|
657
658
|
/>
|
|
658
659
|
}
|
|
659
660
|
{isCreateMPush &&
|
|
@@ -919,6 +920,6 @@ SlideBoxContent.propTypes = {
|
|
|
919
920
|
smsRegister: PropTypes.any,
|
|
920
921
|
getCmsTemplatesInProgress: PropTypes.bool,
|
|
921
922
|
moduleType: PropTypes.string,
|
|
922
|
-
|
|
923
|
+
showLiquidErrorInFooter: PropTypes.bool,
|
|
923
924
|
};
|
|
924
925
|
export default SlideBoxContent;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FormattedMessage } from 'react-intl';
|
|
3
|
-
import
|
|
3
|
+
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
4
|
+
import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
5
|
+
import CapError from '@capillarytech/cap-ui-library/CapError';
|
|
4
6
|
import PropTypes from 'prop-types';
|
|
5
7
|
import messages from './messages';
|
|
8
|
+
import ErrorInfoNote from '../../v2Components/ErrorInfoNote';
|
|
9
|
+
import { PREVIEW } from './constants';
|
|
10
|
+
|
|
6
11
|
function getFullModeSaveBtn(slidBoxContent) {
|
|
7
12
|
return slidBoxContent === "editTemplate" ?
|
|
8
13
|
<FormattedMessage {...messages.creativesTemplatesUpdate}/>
|
|
@@ -10,36 +15,53 @@ function getFullModeSaveBtn(slidBoxContent) {
|
|
|
10
15
|
<FormattedMessage {...messages.creativesTemplatesSaveFullMode}/>;
|
|
11
16
|
}
|
|
12
17
|
function SlideBoxFooter(props) {
|
|
13
|
-
const {
|
|
18
|
+
const {
|
|
19
|
+
slidBoxContent,
|
|
20
|
+
onSave,
|
|
21
|
+
onEditTemplate,
|
|
22
|
+
onCreateNextStep,
|
|
23
|
+
isFullMode,
|
|
24
|
+
fetchingCmsData,
|
|
25
|
+
isTemplateNameEmpty,
|
|
26
|
+
errorMessages,
|
|
27
|
+
isLiquidValidationError,
|
|
28
|
+
} = props;
|
|
14
29
|
return (
|
|
15
|
-
<div>
|
|
30
|
+
<div className='template-footer-width'>
|
|
31
|
+
{isLiquidValidationError && (<ErrorInfoNote errorMessages={errorMessages} />)}
|
|
16
32
|
<div>
|
|
17
33
|
{props.shouldShowDoneFooter() && (
|
|
18
34
|
<div>
|
|
19
|
-
{
|
|
35
|
+
{isFullMode && isTemplateNameEmpty && (
|
|
20
36
|
<CapError type="error">
|
|
21
37
|
<FormattedMessage {...messages.templateNameEmpty} />
|
|
22
38
|
</CapError>
|
|
23
|
-
}
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
)}
|
|
40
|
+
<CapRow>
|
|
41
|
+
<CapButton
|
|
42
|
+
onClick={onSave}
|
|
43
|
+
disabled={isTemplateNameEmpty || fetchingCmsData || false}
|
|
44
|
+
>
|
|
45
|
+
{isFullMode ? (
|
|
46
|
+
getFullModeSaveBtn(slidBoxContent)
|
|
47
|
+
) : (
|
|
48
|
+
<FormattedMessage {...messages.creativesTemplatesSave} />
|
|
49
|
+
)}
|
|
50
|
+
</CapButton>
|
|
51
|
+
</CapRow>
|
|
31
52
|
{/* {isFullMode && <CapButton type="secondary" onClick={onDiscard}><FormattedMessage {...messages.creativesTemplatesDiscard}/></CapButton>} */}
|
|
32
|
-
</div>
|
|
33
|
-
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
{props.shouldShowContinueFooter() && (
|
|
34
56
|
<CapButton onClick={onCreateNextStep}>
|
|
35
57
|
<FormattedMessage {...messages.continue} />
|
|
36
58
|
</CapButton>
|
|
37
|
-
|
|
38
|
-
{slidBoxContent ===
|
|
59
|
+
)}
|
|
60
|
+
{slidBoxContent === PREVIEW && (
|
|
39
61
|
<CapButton onClick={onEditTemplate} type="secondary">
|
|
40
62
|
<FormattedMessage {...messages.creativesTemplatesEdit} />
|
|
41
63
|
</CapButton>
|
|
42
|
-
|
|
64
|
+
)}
|
|
43
65
|
</div>
|
|
44
66
|
</div>
|
|
45
67
|
);
|
|
@@ -53,5 +75,6 @@ SlideBoxFooter.propTypes = {
|
|
|
53
75
|
shouldShowDoneFooter: PropTypes.func,
|
|
54
76
|
isFullMode: PropTypes.bool,
|
|
55
77
|
isTemplateNameEmpty: PropTypes.bool,
|
|
78
|
+
isLiquidValidationError: PropTypes.bool,
|
|
56
79
|
};
|
|
57
80
|
export default SlideBoxFooter;
|
|
@@ -30,3 +30,4 @@ export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOAD
|
|
|
30
30
|
export const WHATSAPP_HELP_DOC_LINK = "https://docs.capillarytech.com/docs/create-whatsapp-template";
|
|
31
31
|
|
|
32
32
|
export const ENABLE_AI_SUGGESTIONS = "ENABLE_AI_SUGGESTIONS";
|
|
33
|
+
export const LIQUID_SUPPORTED_CHANNELS = [EMAIL];
|
|
@@ -41,6 +41,7 @@ import { WHATSAPP_STATUSES, WHATSAPP_MEDIA_TYPES } from '../Whatsapp/constants';
|
|
|
41
41
|
|
|
42
42
|
import { updateImagesInHtml } from '../../utils/cdnTransformation';
|
|
43
43
|
import { IOS } from '../InApp/constants';
|
|
44
|
+
import { CAP_SPACE_28, CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64, CAP_SPACE_72, CAP_SPACE_80 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
44
45
|
|
|
45
46
|
const classPrefix = 'add-creatives-section';
|
|
46
47
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
@@ -48,7 +49,8 @@ const CREATIVES_CONTAINER = 'creativesContainer';
|
|
|
48
49
|
const SlideBoxWrapper = styled.div`
|
|
49
50
|
.cap-slide-box-v2-container{
|
|
50
51
|
.slidebox-header, .slidebox-content-container, .slidebox-footer{
|
|
51
|
-
|
|
52
|
+
margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
|
|
53
|
+
padding: 0 rem;
|
|
52
54
|
&.has-footer{
|
|
53
55
|
overflow-x: hidden;
|
|
54
56
|
}
|
|
@@ -68,6 +70,8 @@ export class Creatives extends React.Component {
|
|
|
68
70
|
currentChannel: this.props.channel || 'sms',
|
|
69
71
|
weChatTemplateType: '',
|
|
70
72
|
weChatMaptemplateStep: 0,
|
|
73
|
+
isLiquidValidationError: false,
|
|
74
|
+
errorMessages: [],
|
|
71
75
|
};
|
|
72
76
|
this.creativesTemplateSteps = {
|
|
73
77
|
1: 'modeSelection',
|
|
@@ -1129,6 +1133,12 @@ export class Creatives extends React.Component {
|
|
|
1129
1133
|
}
|
|
1130
1134
|
}
|
|
1131
1135
|
}
|
|
1136
|
+
|
|
1137
|
+
showLiquidErrorInFooter = (errorMessages) => {
|
|
1138
|
+
const isError = ( errorMessages?.STANDARD_ERROR_MSG?.length > 0 || errorMessages?.LIQUID_ERROR_MSG?.length > 0);
|
|
1139
|
+
this.setState({isLiquidValidationError: isError, errorMessages});
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1132
1142
|
shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
|
|
1133
1143
|
const {slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppCreateMode, weChatTemplateType} = this.state;
|
|
1134
1144
|
let isShowContinueFooter = false;
|
|
@@ -1169,7 +1179,23 @@ export class Creatives extends React.Component {
|
|
|
1169
1179
|
return true;
|
|
1170
1180
|
}
|
|
1171
1181
|
render() {
|
|
1172
|
-
const {
|
|
1182
|
+
const {
|
|
1183
|
+
slidBoxContent,
|
|
1184
|
+
isGetFormData,
|
|
1185
|
+
showSlideBox,
|
|
1186
|
+
templateData,
|
|
1187
|
+
currentChannel,
|
|
1188
|
+
emailCreateMode,
|
|
1189
|
+
templateStep,
|
|
1190
|
+
isLoadingContent,
|
|
1191
|
+
mobilePushCreateMode,
|
|
1192
|
+
isDiscardMessage,
|
|
1193
|
+
weChatTemplateType,
|
|
1194
|
+
weChatMaptemplateStep,
|
|
1195
|
+
isTemplateNameEmpty,
|
|
1196
|
+
isLiquidValidationError,
|
|
1197
|
+
errorMessages,
|
|
1198
|
+
} = this.state;
|
|
1173
1199
|
const {
|
|
1174
1200
|
isFullMode,
|
|
1175
1201
|
creativesMode,
|
|
@@ -1188,10 +1214,21 @@ export class Creatives extends React.Component {
|
|
|
1188
1214
|
smsRegister,
|
|
1189
1215
|
enableNewChannels,
|
|
1190
1216
|
} = this.props;
|
|
1191
|
-
const mapTemplateCreate =
|
|
1217
|
+
const mapTemplateCreate =
|
|
1218
|
+
slidBoxContent === "createTemplate" &&
|
|
1219
|
+
weChatTemplateType === MAP_TEMPLATE &&
|
|
1220
|
+
templateStep !== "modeSelection";
|
|
1221
|
+
const slideBoxWrapperMargin =
|
|
1222
|
+
errorMessages?.STANDARD_ERROR_MSG?.length > 0 && errorMessages?.LIQUID_ERROR_MSG?.length > 0
|
|
1223
|
+
? CAP_SPACE_64
|
|
1224
|
+
: errorMessages?.LIQUID_ERROR_MSG?.length > 0
|
|
1225
|
+
? CAP_SPACE_56
|
|
1226
|
+
: errorMessages?.STANDARD_ERROR_MSG?.length > 0
|
|
1227
|
+
? CAP_SPACE_32
|
|
1228
|
+
: 0;
|
|
1192
1229
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
1193
1230
|
return (
|
|
1194
|
-
<SlideBoxWrapper className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}>
|
|
1231
|
+
<SlideBoxWrapper slideBoxWrapperMargin={slideBoxWrapperMargin} className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}>
|
|
1195
1232
|
<CapSlideBox
|
|
1196
1233
|
header={
|
|
1197
1234
|
this.shouldShowHeader() && <SlideBoxHeader
|
|
@@ -1274,8 +1311,8 @@ export class Creatives extends React.Component {
|
|
|
1274
1311
|
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
1275
1312
|
getCmsTemplatesInProgress={this.props.Templates?.getCmsTemplatesInProgress}
|
|
1276
1313
|
moduleType={this.props.messageDetails?.type}
|
|
1277
|
-
|
|
1278
|
-
|
|
1314
|
+
showLiquidErrorInFooter={this.showLiquidErrorInFooter}
|
|
1315
|
+
/>
|
|
1279
1316
|
}
|
|
1280
1317
|
footer={this.shouldShowFooter() &&
|
|
1281
1318
|
<SlideBoxFooter
|
|
@@ -1293,6 +1330,8 @@ export class Creatives extends React.Component {
|
|
|
1293
1330
|
shouldShowDoneFooter={this.shouldShowDoneFooter}
|
|
1294
1331
|
fetchingCmsData={fetchingCmsData}
|
|
1295
1332
|
isTemplateNameEmpty={isTemplateNameEmpty}
|
|
1333
|
+
isLiquidValidationError ={isLiquidValidationError}
|
|
1334
|
+
errorMessages={errorMessages}
|
|
1296
1335
|
/>
|
|
1297
1336
|
}
|
|
1298
1337
|
handleClose={this.handleCloseSlideBox}
|
|
@@ -69,4 +69,16 @@ $classPrefix: add-creatives-section;
|
|
|
69
69
|
i {
|
|
70
70
|
height: $ICON_SIZE_M;
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|
|
73
|
+
.liquid-error {
|
|
74
|
+
display: flex;
|
|
75
|
+
gap: $CAP_SPACE_04;
|
|
76
|
+
color: $CAP_COLOR_03;
|
|
77
|
+
vertical-align: text-top;
|
|
78
|
+
align-items: center;
|
|
79
|
+
margin-left: $CAP_SPACE_24;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.template-footer-width {
|
|
83
|
+
width: 100%;;
|
|
84
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports[`Test SlideBoxContent container campaign message, add creative click rcs 1`] = `
|
|
4
4
|
<CreativesContainer__SlideBoxWrapper
|
|
5
5
|
className="add-creatives-section creatives-library-mode "
|
|
6
|
+
slideBoxWrapperMargin={0}
|
|
6
7
|
>
|
|
7
8
|
<CapSlideBox
|
|
8
9
|
closeIconPosition="right"
|
|
@@ -33,6 +34,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click rcs
|
|
|
33
34
|
onWechatTemplateChange={[Function]}
|
|
34
35
|
saveMessage={[Function]}
|
|
35
36
|
setIsLoadingContent={[Function]}
|
|
37
|
+
showLiquidErrorInFooter={[Function]}
|
|
36
38
|
showTemplateName={[Function]}
|
|
37
39
|
slidBoxContent="templates"
|
|
38
40
|
templateData={
|
|
@@ -77,6 +79,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click rcs
|
|
|
77
79
|
exports[`Test SlideBoxContent container campaign message, add creative click whatsapp 1`] = `
|
|
78
80
|
<CreativesContainer__SlideBoxWrapper
|
|
79
81
|
className="add-creatives-section creatives-library-mode "
|
|
82
|
+
slideBoxWrapperMargin={0}
|
|
80
83
|
>
|
|
81
84
|
<CapSlideBox
|
|
82
85
|
closeIconPosition="right"
|
|
@@ -107,6 +110,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click wha
|
|
|
107
110
|
onWechatTemplateChange={[Function]}
|
|
108
111
|
saveMessage={[Function]}
|
|
109
112
|
setIsLoadingContent={[Function]}
|
|
113
|
+
showLiquidErrorInFooter={[Function]}
|
|
110
114
|
showTemplateName={[Function]}
|
|
111
115
|
slidBoxContent="templates"
|
|
112
116
|
templateData={
|
|
@@ -151,6 +155,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click wha
|
|
|
151
155
|
exports[`Test SlideBoxContent container campaign message, whatsapp edit all data 1`] = `
|
|
152
156
|
<CreativesContainer__SlideBoxWrapper
|
|
153
157
|
className="add-creatives-section creatives-library-mode "
|
|
158
|
+
slideBoxWrapperMargin={0}
|
|
154
159
|
>
|
|
155
160
|
<CapSlideBox
|
|
156
161
|
closeIconPosition="right"
|
|
@@ -181,6 +186,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
|
|
|
181
186
|
onWechatTemplateChange={[Function]}
|
|
182
187
|
saveMessage={[Function]}
|
|
183
188
|
setIsLoadingContent={[Function]}
|
|
189
|
+
showLiquidErrorInFooter={[Function]}
|
|
184
190
|
showTemplateName={[Function]}
|
|
185
191
|
slidBoxContent="editTemplate"
|
|
186
192
|
templateStep="modeSelection"
|
|
@@ -191,6 +197,8 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
|
|
|
191
197
|
footer={
|
|
192
198
|
<SlideBoxFooter
|
|
193
199
|
currentChannel="WHATSAPP"
|
|
200
|
+
errorMessages={Array []}
|
|
201
|
+
isLiquidValidationError={false}
|
|
194
202
|
onCreateNextStep={[Function]}
|
|
195
203
|
onDiscard={[Function]}
|
|
196
204
|
onEditTemplate={[Function]}
|
|
@@ -227,6 +235,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
|
|
|
227
235
|
exports[`Test SlideBoxContent container campaign message, whatsapp edit min data 1`] = `
|
|
228
236
|
<CreativesContainer__SlideBoxWrapper
|
|
229
237
|
className="add-creatives-section creatives-library-mode "
|
|
238
|
+
slideBoxWrapperMargin={0}
|
|
230
239
|
>
|
|
231
240
|
<CapSlideBox
|
|
232
241
|
closeIconPosition="right"
|
|
@@ -257,6 +266,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
|
|
|
257
266
|
onWechatTemplateChange={[Function]}
|
|
258
267
|
saveMessage={[Function]}
|
|
259
268
|
setIsLoadingContent={[Function]}
|
|
269
|
+
showLiquidErrorInFooter={[Function]}
|
|
260
270
|
showTemplateName={[Function]}
|
|
261
271
|
slidBoxContent="editTemplate"
|
|
262
272
|
templateStep="modeSelection"
|
|
@@ -267,6 +277,8 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
|
|
|
267
277
|
footer={
|
|
268
278
|
<SlideBoxFooter
|
|
269
279
|
currentChannel="WHATSAPP"
|
|
280
|
+
errorMessages={Array []}
|
|
281
|
+
isLiquidValidationError={false}
|
|
270
282
|
onCreateNextStep={[Function]}
|
|
271
283
|
onDiscard={[Function]}
|
|
272
284
|
onEditTemplate={[Function]}
|
|
@@ -303,6 +315,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
|
|
|
303
315
|
exports[`Test SlideBoxContent container it should clear the url, on channel change from new whatsapp to another 1`] = `
|
|
304
316
|
<CreativesContainer__SlideBoxWrapper
|
|
305
317
|
className="add-creatives-section creatives-library-mode "
|
|
318
|
+
slideBoxWrapperMargin={0}
|
|
306
319
|
>
|
|
307
320
|
<CapSlideBox
|
|
308
321
|
closeIconPosition="right"
|
|
@@ -333,6 +346,7 @@ exports[`Test SlideBoxContent container it should clear the url, on channel chan
|
|
|
333
346
|
onWechatTemplateChange={[Function]}
|
|
334
347
|
saveMessage={[Function]}
|
|
335
348
|
setIsLoadingContent={[Function]}
|
|
349
|
+
showLiquidErrorInFooter={[Function]}
|
|
336
350
|
showTemplateName={[Function]}
|
|
337
351
|
slidBoxContent="editTemplate"
|
|
338
352
|
templateStep="modeSelection"
|
|
@@ -343,6 +357,8 @@ exports[`Test SlideBoxContent container it should clear the url, on channel chan
|
|
|
343
357
|
footer={
|
|
344
358
|
<SlideBoxFooter
|
|
345
359
|
currentChannel="WHATSAPP"
|
|
360
|
+
errorMessages={Array []}
|
|
361
|
+
isLiquidValidationError={false}
|
|
346
362
|
onCreateNextStep={[Function]}
|
|
347
363
|
onDiscard={[Function]}
|
|
348
364
|
onEditTemplate={[Function]}
|
|
@@ -2732,6 +2732,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2732
2732
|
type={CmsSettings.type}
|
|
2733
2733
|
isEmailLoading={isLoading}
|
|
2734
2734
|
moduleType={moduleType}
|
|
2735
|
+
showLiquidErrorInFooter={this.props.showLiquidErrorInFooter}
|
|
2735
2736
|
/> : ''}
|
|
2736
2737
|
</Col>
|
|
2737
2738
|
</Row>
|
|
@@ -2788,6 +2789,7 @@ Email.propTypes = {
|
|
|
2788
2789
|
onPreviewContentClicked: PropTypes.func,
|
|
2789
2790
|
onTestContentClicked: PropTypes.func,
|
|
2790
2791
|
moduleType: PropTypes.string,
|
|
2792
|
+
showLiquidErrorInFooter: PropTypes.func,
|
|
2791
2793
|
};
|
|
2792
2794
|
|
|
2793
2795
|
const mapStateToProps = (state, props) => createStructuredSelector({
|
|
@@ -214,6 +214,7 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
|
|
|
214
214
|
editor,
|
|
215
215
|
currentOrgDetails,
|
|
216
216
|
moduleType,
|
|
217
|
+
showLiquidErrorInFooter,
|
|
217
218
|
} = this.props;
|
|
218
219
|
const {
|
|
219
220
|
templateName,
|
|
@@ -278,6 +279,7 @@ export class EmailWrapper extends React.Component { // eslint-disable-line react
|
|
|
278
279
|
defaultData={{ 'template-name': templateName }}
|
|
279
280
|
cap={cap}
|
|
280
281
|
showTemplateName={showTemplateName}
|
|
282
|
+
showLiquidErrorInFooter = {showLiquidErrorInFooter}
|
|
281
283
|
onValidationFail={onValidationFail}
|
|
282
284
|
forwardedTags={forwardedTags}
|
|
283
285
|
selectedOfferDetails={selectedOfferDetails}
|
|
@@ -321,6 +323,7 @@ EmailWrapper.propTypes = {
|
|
|
321
323
|
isUploading: PropTypes.bool,
|
|
322
324
|
setIsLoadingContent: PropTypes.func,
|
|
323
325
|
showTemplateName: PropTypes.func,
|
|
326
|
+
showLiquidErrorInFooter: PropTypes.func,
|
|
324
327
|
onValidationFail: PropTypes.func,
|
|
325
328
|
forwardedTags: PropTypes.object,
|
|
326
329
|
selectedOfferDetails: PropTypes.array,
|
|
@@ -23084,11 +23084,14 @@ new message content.",
|
|
|
23084
23084
|
Object {
|
|
23085
23085
|
"app": Object {},
|
|
23086
23086
|
"cap": Object {
|
|
23087
|
+
"fetchingLiquidTags": false,
|
|
23087
23088
|
"fetchingSchema": true,
|
|
23088
23089
|
"fetchingSchemaError": "",
|
|
23090
|
+
"liquidTags": Array [],
|
|
23089
23091
|
"messages": Array [],
|
|
23090
23092
|
"metaEntities": Object {
|
|
23091
23093
|
"layouts": Array [],
|
|
23094
|
+
"tagLookupMap": Object {},
|
|
23092
23095
|
"tags": Array [],
|
|
23093
23096
|
},
|
|
23094
23097
|
"orgID": "",
|
|
@@ -33,8 +33,3 @@ export const GET_WECRM_ACCOUNTS_FAILURE = "app/v2Containers/MobilePush/GET_WECRM
|
|
|
33
33
|
export const GET_MOBILEPUSH_TEMPLATES_LIST_REQUEST = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_REQUEST';
|
|
34
34
|
export const GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS';
|
|
35
35
|
export const GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE';
|
|
36
|
-
|
|
37
|
-
export const MAPP_SDK = 'MAPP_SDK';
|
|
38
|
-
export const EMBEDDED = 'EMBEDDED';
|
|
39
|
-
export const EDIT = 'EDIT';
|
|
40
|
-
export const PREVIEW = 'PREVIEW';
|