@capillarytech/creatives-library 8.0.87-alpha.24 → 8.0.87-alpha.3
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/containers/Templates/constants.js +0 -6
- package/containers/Templates/index.js +24 -44
- package/initialState.js +0 -1
- package/package.json +1 -1
- package/services/api.js +13 -28
- package/services/tests/api.test.js +1 -5
- package/utils/commonUtils.js +10 -64
- package/utils/tests/commonUtil.test.js +3 -108
- package/v2Components/CapImageUpload/index.js +10 -13
- package/v2Components/CapVideoUpload/index.js +9 -12
- package/v2Components/CapWhatsappCTA/messages.js +0 -4
- package/v2Components/FormBuilder/constants.js +0 -8
- package/v2Components/FormBuilder/index.js +5 -9
- package/v2Components/TemplatePreview/_templatePreview.scss +0 -20
- package/v2Components/TemplatePreview/index.js +105 -160
- package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +6 -6
- package/v2Containers/Cap/actions.js +0 -8
- package/v2Containers/Cap/constants.js +0 -4
- package/v2Containers/Cap/reducer.js +0 -6
- package/v2Containers/Cap/sagas.js +0 -23
- package/v2Containers/Cap/selectors.js +0 -6
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +0 -1
- package/v2Containers/Cap/tests/saga.test.js +1 -90
- package/v2Containers/CreativesContainer/SlideBoxContent.js +1 -5
- package/v2Containers/CreativesContainer/constants.js +1 -11
- package/v2Containers/CreativesContainer/index.js +9 -175
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -3
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -25
- package/v2Containers/CreativesContainer/tests/index.test.js +0 -2
- package/v2Containers/EmailWrapper/constants.js +1 -11
- package/v2Containers/EmailWrapper/index.js +298 -116
- package/v2Containers/MobilePush/Create/index.js +0 -1
- package/v2Containers/Sms/Edit/index.js +0 -1
- package/v2Containers/Templates/_templates.scss +0 -47
- package/v2Containers/Templates/index.js +5 -55
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +156 -177
- package/v2Containers/TemplatesV2/index.js +1 -8
- package/v2Containers/Whatsapp/constants.js +1 -87
- package/v2Containers/Whatsapp/index.js +193 -721
- package/v2Containers/Whatsapp/index.scss +1 -52
- package/v2Containers/Whatsapp/messages.js +2 -38
- package/v2Containers/Whatsapp/styles.scss +0 -5
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +91842 -28813
- package/v2Containers/Whatsapp/tests/__snapshots__/utils.test.js.snap +0 -6
- package/v2Containers/Whatsapp/tests/mockData.js +7 -3
- package/v2Containers/Whatsapp/tests/utils.test.js +1 -178
- package/v2Containers/Whatsapp/utils.js +0 -52
- package/v2Containers/Zalo/index.js +65 -76
- package/v2Containers/Zalo/index.scss +0 -8
- package/v2Containers/Zalo/messages.js +3 -3
- package/v2Containers/mockdata.js +0 -5
- package/utils/tests/transformerUtils.test.js +0 -2127
- package/utils/transformerUtils.js +0 -420
- package/v2Components/CapWhatsappCarouselButton/constant.js +0 -56
- package/v2Components/CapWhatsappCarouselButton/index.js +0 -446
- package/v2Components/CapWhatsappCarouselButton/index.scss +0 -39
- package/v2Components/CapWhatsappCarouselButton/tests/index.test.js +0 -237
- package/v2Components/TemplatePreview/assets/images/empty_image_preview.svg +0 -4
- package/v2Components/TemplatePreview/assets/images/empty_video_preview.svg +0 -4
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +0 -192
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +0 -343
- package/v2Containers/EmailWrapper/mockdata/mockdata.js +0 -119
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
- package/v2Containers/EmailWrapper/tests/index.test.js +0 -101
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +0 -601
|
@@ -43,9 +43,3 @@ export const RESET_TEMPLATE = "app/containers/Templates/RESET_TEMPLATE";
|
|
|
43
43
|
export const RESET_TEMPLATE_DATA = "app/containers/Templates/RESET_TEMPLATE_DATA";
|
|
44
44
|
export const RESET_UPLOAD_DATA = "app/containers/Templates/RESET_UPLOAD_DATA";
|
|
45
45
|
export const CLEAR_TEMPLATE_STORE_DATA = "app/containers/Templates/CLEAR_TEMPLATE_STORE_DATA";
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export const TRUE = 'true';
|
|
49
|
-
export const FALSE = 'false';
|
|
50
|
-
export const EMAIL = 'email';
|
|
51
|
-
export const TYPE_EMBEDDED = 'embedded';
|
|
@@ -57,8 +57,6 @@ import lineCreateReducer from '../Line/Create/reducer';
|
|
|
57
57
|
import { ebillSaga } from '../Ebill/sagas';
|
|
58
58
|
import { lineCreateSaga } from '../Line/Create/sagas';
|
|
59
59
|
import { duplicateMPushSaga } from '../MobilePush/Create/sagas';
|
|
60
|
-
import { FALSE, TRUE, TYPE_EMBEDDED } from './constants';
|
|
61
|
-
import { DEFAULT } from '../../v2Containers/Cap/constants';
|
|
62
60
|
|
|
63
61
|
const MenuItem = Menu.Item;
|
|
64
62
|
const Option = Select.Option;
|
|
@@ -916,49 +914,31 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
916
914
|
|
|
917
915
|
handleEdmDefaultTemplateSelection = (isSelected, id) => {
|
|
918
916
|
if (isSelected) {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
const isEdmSupport = this.props?.location?.query?.isEdmSupport !== FALSE;
|
|
917
|
+
const data = _.find(this.props.Templates.cmsTemplates, {_id: id});
|
|
918
|
+
const type = this.props.location.query.type
|
|
919
|
+
const module = this.props.location.query.module ? this.props.location.query.module : 'default';
|
|
920
|
+
const isLanguageSupport = this.props.location.query.isLanguageSupport ? this.props.location.query.isLanguageSupport : true;
|
|
921
|
+
const isEdmSupport = (this.props.location.query.isEdmSupport !== "false") || false;
|
|
925
922
|
let getQuery = '';
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
type: TYPE_EMBEDDED,
|
|
938
|
-
module,
|
|
939
|
-
isLanguageSupport: isLanguageSupport ? 1 : 0,
|
|
940
|
-
isEdmSupport: isEdmSupport ? 1 : 0,
|
|
941
|
-
projectId: template?.versions?.base?.drag_drop_id,
|
|
942
|
-
} : {
|
|
943
|
-
module,
|
|
944
|
-
isLanguageSupport: isLanguageSupport ? 1 : 0,
|
|
945
|
-
isEdmSupport: isEdmSupport ? 1 : 0,
|
|
946
|
-
projectId: template?.versions?.base?.drag_drop_id,
|
|
947
|
-
};
|
|
948
|
-
} else {
|
|
949
|
-
getQuery = (type === TYPE_EMBEDDED) ? {type: TYPE_EMBEDDED, module} : {module};
|
|
950
|
-
}
|
|
923
|
+
|
|
924
|
+
this.props.actions.setEdmTemplate(data);
|
|
925
|
+
if (this.state.channel && this.state.channel.toLowerCase() === 'email') {
|
|
926
|
+
getQuery = (type === 'embedded') ? {type: 'embedded', module, isLanguageSupport, isEdmSupport} : {module, isLanguageSupport, isEdmSupport};
|
|
927
|
+
} else {
|
|
928
|
+
getQuery = (type === 'embedded') ? {type: 'embedded', module} : {module};
|
|
929
|
+
}
|
|
930
|
+
if (this.isEnabledInLibraryModule("callCreateFromProps")) {
|
|
931
|
+
this.props.createNew();
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
951
934
|
|
|
952
|
-
|
|
953
|
-
this.props.
|
|
954
|
-
return;
|
|
955
|
-
}
|
|
935
|
+
const queryParams = commonUtil.createQueryString(getQuery);
|
|
936
|
+
// this.props.router.push(`${pathName}${queryParams}`);
|
|
956
937
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
}
|
|
938
|
+
this.props.router.push({
|
|
939
|
+
pathname: `/${this.state.channel.toLowerCase()}/create`,
|
|
940
|
+
search: getQuery,
|
|
941
|
+
});
|
|
962
942
|
}
|
|
963
943
|
};
|
|
964
944
|
|
|
@@ -1148,7 +1128,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1148
1128
|
const imgSrc = template && template.versions && template.versions.base ? template.versions.base.preview_http_url : '';
|
|
1149
1129
|
const ifPreviewGenerated = template && template.versions && template.versions.base ? template.versions.base.isPreviewGenerated : 0;
|
|
1150
1130
|
content = <img src={imgSrc || ''} alt={this.props.intl.formatMessage(messages.previewGenerateText)} width="100%" height="100%"/>;
|
|
1151
|
-
|
|
1131
|
+
|
|
1152
1132
|
temp.content = (
|
|
1153
1133
|
<div
|
|
1154
1134
|
className="sms-template-content">
|
|
@@ -1156,7 +1136,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1156
1136
|
{content}
|
|
1157
1137
|
</div>
|
|
1158
1138
|
{!layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={(e) => this.handleEditClick(e, template._id)} className="edit-button" type="secondary">{type === 'embedded' ? this.props.intl.formatMessage(messages.selectButton) : this.props.intl.formatMessage(messages.editButton)}</CapButton> : ''}
|
|
1159
|
-
{layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={(event) =>{this.handleEdmDefaultTemplateSelection(true, template
|
|
1139
|
+
{layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={(event) =>{this.handleEdmDefaultTemplateSelection(true, template._id); event.stopPropagation();}} className="select-button" type="secondary">{type === 'embedded' ? this.props.intl.formatMessage(messages.selectDefaultButton) : this.props.intl.formatMessage(messages.selectDefaultButton)}</CapButton> : ''}
|
|
1160
1140
|
{!layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={() => this.handlePreviewClick(template)} className="preview-button" type="cancel">{this.props.intl.formatMessage(messages.previewButton)}</CapButton> : ''}
|
|
1161
1141
|
</div>);
|
|
1162
1142
|
} else if (this.state.channel.toLowerCase() === 'mobilepush') {
|
package/initialState.js
CHANGED
package/package.json
CHANGED
package/services/api.js
CHANGED
|
@@ -9,7 +9,7 @@ import config from '../config/app';
|
|
|
9
9
|
import pathConfig from '../config/path';
|
|
10
10
|
import getSchema from './getSchema';
|
|
11
11
|
import * as API from '../utils/ApiCaller';
|
|
12
|
-
import { addBaseToTemplate
|
|
12
|
+
import { addBaseToTemplate } from '../utils/commonUtils';
|
|
13
13
|
import { EMAIL, SMS } from '../v2Containers/CreativesContainer/constants';
|
|
14
14
|
let API_ENDPOINT = config.development.api_endpoint;
|
|
15
15
|
let EXPORT_API_ENDPOINT = config.development.exports_api_endpoint;
|
|
@@ -118,7 +118,7 @@ function request(url, options, handleUnauthorizedStatus) {
|
|
|
118
118
|
.catch((error) => error);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeaders = false, orgUnitId = false
|
|
121
|
+
function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeaders = false, orgUnitId = false) {
|
|
122
122
|
const token = loadItem('token');
|
|
123
123
|
const orgID = loadItem('orgID');
|
|
124
124
|
const user = loadItem('user');
|
|
@@ -145,8 +145,8 @@ function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeader
|
|
|
145
145
|
headers['X-CAP-REMOTE-USER'] = user.refID;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
if (
|
|
149
|
-
headers[
|
|
148
|
+
if (process.env.NODE_ENV !== 'production' && orgID !== undefined) {
|
|
149
|
+
headers['X-CAP-API-AUTH-ORG-ID'] = orgID;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
if (process.env.NODE_ENV !== 'production' && token !== undefined) {
|
|
@@ -359,13 +359,7 @@ export const fetchSchemaForEntity = async ({queryParams}) => {
|
|
|
359
359
|
});
|
|
360
360
|
}
|
|
361
361
|
const url = `${API_ENDPOINT}/meta/${queryParams.type}?query=${JSON.stringify(queryParams)}`;
|
|
362
|
-
|
|
363
|
-
const customFields = get(result, 'response.metaEntities.custom', {});
|
|
364
|
-
if (customFields && Object.keys(customFields)?.length > 0) {
|
|
365
|
-
const transformedData = transformCustomFieldsData(customFields);
|
|
366
|
-
result.response.metaEntities.custom = transformedData;
|
|
367
|
-
}
|
|
368
|
-
return result;
|
|
362
|
+
return request(url, getAPICallObject('GET'));// request(url, getAPICallObject('GET'));
|
|
369
363
|
};
|
|
370
364
|
|
|
371
365
|
export const fetchWeCrmAccounts = (sourceName) => {
|
|
@@ -477,12 +471,14 @@ export const getUnsubscribeUrl = () => {
|
|
|
477
471
|
return request(url, getAPICallObject('POST', body));
|
|
478
472
|
};
|
|
479
473
|
|
|
480
|
-
export const getMarketingObjectives = (channel) =>
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
)
|
|
474
|
+
export const getMarketingObjectives = (channel) =>
|
|
475
|
+
request(
|
|
476
|
+
`${CAMPAIGNS_API_ENDPOINT}/socialObjectives?channel=${channel}`,
|
|
477
|
+
getAPICallObject('GET', null, false, true),
|
|
478
|
+
);
|
|
484
479
|
|
|
485
|
-
export const getAllLineStickers = () =>
|
|
480
|
+
export const getAllLineStickers = () =>
|
|
481
|
+
request(`${API_ENDPOINT}/meta/sticker`, getAPICallObject('GET'));
|
|
486
482
|
|
|
487
483
|
|
|
488
484
|
export const createCustomRow = (data) => {
|
|
@@ -524,13 +520,7 @@ export const checkBulkDuplicates = (data) => {
|
|
|
524
520
|
export const createWhatsappTemplate = ({payload, gupshupMediaFile }) => {
|
|
525
521
|
const data = new FormData();
|
|
526
522
|
data.append('payload', JSON.stringify(payload));
|
|
527
|
-
|
|
528
|
-
gupshupMediaFile.forEach((file, index) => {
|
|
529
|
-
data.append(`gupshupMediaFile_${index}`, file);
|
|
530
|
-
});
|
|
531
|
-
} else {
|
|
532
|
-
data.append('gupshupMediaFile', gupshupMediaFile);
|
|
533
|
-
}
|
|
523
|
+
data.append('gupshupMediaFile', gupshupMediaFile);
|
|
534
524
|
const url = `${API_ENDPOINT}/templates/WHATSAPP`;
|
|
535
525
|
return request(url, getAPICallObject('POST', data, true));
|
|
536
526
|
};
|
|
@@ -579,9 +569,4 @@ export const getLiquidTags = (content) => {
|
|
|
579
569
|
return request(url, getAPICallObject("POST", { content }, false, true));
|
|
580
570
|
};
|
|
581
571
|
|
|
582
|
-
export const createCentralCommsMetaId = (payload, metaType = 'TRANSACTION') => {
|
|
583
|
-
const url = `${API_ENDPOINT}/common/central-comms/meta-id/${metaType}`;
|
|
584
|
-
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
585
|
-
};
|
|
586
|
-
|
|
587
572
|
export {request, getAPICallObject};
|
|
@@ -86,11 +86,7 @@ describe('uploadFile -- whatsapp image upload', () => {
|
|
|
86
86
|
describe('createWhatsappTemplate -- Test with valid responses', () => {
|
|
87
87
|
it('Should return correct response', () =>
|
|
88
88
|
expect(
|
|
89
|
-
createWhatsappTemplate(
|
|
90
|
-
).toEqual(Promise.resolve()));
|
|
91
|
-
it('Should return correct response when single file is present', () =>
|
|
92
|
-
expect(
|
|
93
|
-
createWhatsappTemplate({gupshupMediaFile: sampleFile, payload: mockData.createWhatsappPayload}),
|
|
89
|
+
createWhatsappTemplate(sampleFile, mockData.createWhatsappPayload),
|
|
94
90
|
).toEqual(Promise.resolve()));
|
|
95
91
|
});
|
|
96
92
|
|
package/utils/commonUtils.js
CHANGED
|
@@ -9,77 +9,23 @@ export const apiMessageFormatHandler = (id, fallback) => (
|
|
|
9
9
|
);
|
|
10
10
|
|
|
11
11
|
export const addBaseToTemplate = (template) => {
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} = {},
|
|
16
|
-
} = template || {};
|
|
12
|
+
const { versions: {
|
|
13
|
+
history = [],
|
|
14
|
+
} = {}} = template || {};
|
|
17
15
|
if (history?.length) {
|
|
18
16
|
return ({
|
|
19
17
|
...template,
|
|
20
18
|
versions: {
|
|
21
19
|
...template.versions,
|
|
22
|
-
base:
|
|
20
|
+
base:{
|
|
23
21
|
...history[0],
|
|
24
|
-
...( !history?.[0]?.subject && { subject: get(template, 'versions.base.subject') })
|
|
25
|
-
|
|
26
|
-
}
|
|
22
|
+
...( !history?.[0]?.subject && { subject: get(template, 'versions.base.subject') })
|
|
23
|
+
}
|
|
24
|
+
}
|
|
27
25
|
});
|
|
28
26
|
}
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const isEmbeddedEditOrPreview = (queryType, creativesMode) => queryType === EMBEDDED && [EDIT, PREVIEW].includes(creativesMode);
|
|
33
|
-
|
|
34
|
-
export const transformCustomFieldsData = (customFields) => {
|
|
35
|
-
// Define mapping of scopes to their display names
|
|
36
|
-
const scopeMapping = {
|
|
37
|
-
loyalty_registration: 'Registration custom fields',
|
|
38
|
-
loyalty_transaction: 'Registration custom fields',
|
|
39
|
-
store_custom_fields: 'Organization custom fields',
|
|
40
|
-
org_custom_field: 'Organization custom fields',
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Initialize result structure with all possible sections
|
|
44
|
-
const result = Object.values(scopeMapping).reduce((acc, sectionName) => {
|
|
45
|
-
acc[sectionName] = {
|
|
46
|
-
name: sectionName,
|
|
47
|
-
subtags: {},
|
|
48
|
-
};
|
|
49
|
-
return acc;
|
|
50
|
-
}, {});
|
|
51
|
-
|
|
52
|
-
// Process each custom field
|
|
53
|
-
Object.values(customFields).forEach((field) => {
|
|
54
|
-
const {scope = ''} = field;
|
|
55
|
-
const sectionName = scopeMapping[scope];
|
|
56
|
-
|
|
57
|
-
if (sectionName) {
|
|
58
|
-
// Determine the prefix based on scope
|
|
59
|
-
let prefix = 'custom_field';
|
|
60
|
-
if (scope === 'org_custom_field') {
|
|
61
|
-
prefix = 'org_custom_field';
|
|
62
|
-
} else if (scope === 'store_custom_fields') {
|
|
63
|
-
prefix = 'store_custom_field';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const fieldKey = `${prefix}.${field?.name}`;
|
|
67
|
-
// Add field to appropriate section
|
|
68
|
-
result[sectionName].subtags[fieldKey] = {
|
|
69
|
-
name: field?.name,
|
|
70
|
-
desc: field?.name || field?.label,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// Remove empty sections (those with no subtags)
|
|
76
|
-
Object.keys(result).forEach((sectionName) => {
|
|
77
|
-
if (Object.keys(result[sectionName]?.subtags)?.length === 0) {
|
|
78
|
-
delete result[sectionName];
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return result;
|
|
27
|
+
return template;
|
|
83
28
|
};
|
|
84
29
|
|
|
85
|
-
export const
|
|
30
|
+
export const isEmbeddedEditOrPreview = (queryType, creativesMode) => queryType === EMBEDDED &&
|
|
31
|
+
[EDIT, PREVIEW].includes(creativesMode);
|
|
@@ -2,9 +2,10 @@ import "@testing-library/jest-dom";
|
|
|
2
2
|
import get from 'lodash/get';
|
|
3
3
|
import { getTreeStructuredTags } from "../common";
|
|
4
4
|
import * as mockdata from "./common.mockdata";
|
|
5
|
-
import { addBaseToTemplate, isEmbeddedEditOrPreview
|
|
5
|
+
import { addBaseToTemplate, isEmbeddedEditOrPreview } from "../commonUtils";
|
|
6
6
|
import { EMBEDDED, FULL } from "../../v2Containers/Whatsapp/constants";
|
|
7
7
|
import { CREATE, EDIT, PREVIEW } from "../../v2Containers/App/constants";
|
|
8
|
+
import { query } from "express";
|
|
8
9
|
|
|
9
10
|
jest.mock('@capillarytech/cap-ui-utils', () => ({
|
|
10
11
|
Auth: {
|
|
@@ -37,7 +38,7 @@ describe('addBaseToTemplate', () => {
|
|
|
37
38
|
versions: {
|
|
38
39
|
history: ['v1', 'v2', 'v3'],
|
|
39
40
|
base: {
|
|
40
|
-
0:
|
|
41
|
+
"0":"v","1":"1","subject":undefined,
|
|
41
42
|
},
|
|
42
43
|
},
|
|
43
44
|
};
|
|
@@ -114,109 +115,3 @@ describe('isEmbeddedEditOrPreview', () => {
|
|
|
114
115
|
expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(false);
|
|
115
116
|
});
|
|
116
117
|
});
|
|
117
|
-
|
|
118
|
-
describe('transformCustomFieldsData', () => {
|
|
119
|
-
it('should transform registration custom fields correctly', () => {
|
|
120
|
-
const input = {
|
|
121
|
-
1: {
|
|
122
|
-
name: 'age_group',
|
|
123
|
-
label: 'Age Group',
|
|
124
|
-
scope: 'loyalty_registration',
|
|
125
|
-
},
|
|
126
|
-
2: {
|
|
127
|
-
name: 'gender',
|
|
128
|
-
label: 'Gender',
|
|
129
|
-
scope: 'loyalty_registration',
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const expected = {
|
|
134
|
-
'Registration custom fields': {
|
|
135
|
-
name: 'Registration custom fields',
|
|
136
|
-
subtags: {
|
|
137
|
-
'custom_field.age_group': {
|
|
138
|
-
name: 'age_group',
|
|
139
|
-
desc: 'age_group',
|
|
140
|
-
},
|
|
141
|
-
'custom_field.gender': {
|
|
142
|
-
name: 'gender',
|
|
143
|
-
desc: 'gender',
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
expect(transformCustomFieldsData(input)).toEqual(expected);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('should transform organization custom fields correctly', () => {
|
|
153
|
-
const input = {
|
|
154
|
-
1: {
|
|
155
|
-
name: 'org_phone',
|
|
156
|
-
label: 'Phone',
|
|
157
|
-
scope: 'org_custom_field',
|
|
158
|
-
},
|
|
159
|
-
2: {
|
|
160
|
-
name: 'store_location',
|
|
161
|
-
label: 'Location',
|
|
162
|
-
scope: 'store_custom_fields',
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const expected = {
|
|
167
|
-
'Organization custom fields': {
|
|
168
|
-
name: 'Organization custom fields',
|
|
169
|
-
subtags: {
|
|
170
|
-
'org_custom_field.org_phone': {
|
|
171
|
-
name: 'org_phone',
|
|
172
|
-
desc: 'org_phone',
|
|
173
|
-
},
|
|
174
|
-
'store_custom_field.store_location': {
|
|
175
|
-
name: 'store_location',
|
|
176
|
-
desc: 'store_location',
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
expect(transformCustomFieldsData(input)).toEqual(expected);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('should handle empty input correctly', () => {
|
|
186
|
-
expect(transformCustomFieldsData({})).toEqual({});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it('should handle fields with missing properties', () => {
|
|
190
|
-
const input = {
|
|
191
|
-
1: {
|
|
192
|
-
scope: 'loyalty_registration',
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const expected = {
|
|
197
|
-
'Registration custom fields': {
|
|
198
|
-
name: 'Registration custom fields',
|
|
199
|
-
subtags: {
|
|
200
|
-
'custom_field.undefined': {
|
|
201
|
-
name: undefined,
|
|
202
|
-
desc: undefined,
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
expect(transformCustomFieldsData(input)).toEqual(expected);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should ignore fields with invalid scope', () => {
|
|
212
|
-
const input = {
|
|
213
|
-
1: {
|
|
214
|
-
name: 'test',
|
|
215
|
-
label: 'Test',
|
|
216
|
-
scope: 'invalid_scope',
|
|
217
|
-
},
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
expect(transformCustomFieldsData(input)).toEqual({});
|
|
221
|
-
});
|
|
222
|
-
});
|
|
@@ -44,7 +44,6 @@ function CapImageUpload(props) {
|
|
|
44
44
|
imageData,
|
|
45
45
|
channel,
|
|
46
46
|
channelSpecificStyle,
|
|
47
|
-
showReUploadButton = true,
|
|
48
47
|
} = props;
|
|
49
48
|
const {
|
|
50
49
|
formatMessage,
|
|
@@ -225,18 +224,16 @@ function CapImageUpload(props) {
|
|
|
225
224
|
</>
|
|
226
225
|
);
|
|
227
226
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
);
|
|
239
|
-
}
|
|
227
|
+
return (
|
|
228
|
+
<CapButton
|
|
229
|
+
className="dragger-button re-upload"
|
|
230
|
+
type="flat"
|
|
231
|
+
onClick={onReUpload}
|
|
232
|
+
style={channelSpecificStyle ? { marginTop: '-16px'} : {}}
|
|
233
|
+
>
|
|
234
|
+
<FormattedMessage {...messages.imageReUpload} />
|
|
235
|
+
</CapButton>
|
|
236
|
+
);
|
|
240
237
|
}, [isImageError, imageSrc]);
|
|
241
238
|
|
|
242
239
|
return (
|
|
@@ -39,7 +39,6 @@ function CapVideoUpload(props) {
|
|
|
39
39
|
errorMessage,
|
|
40
40
|
showVideoNameAndDuration = true,
|
|
41
41
|
formClassName = 'video-form',
|
|
42
|
-
showReUploadButton = true,
|
|
43
42
|
} = props;
|
|
44
43
|
const [isVideoError, updateVideoErrorMessage] = useState(false);
|
|
45
44
|
const [isVideo, updateVideoStatus] = useState(false);
|
|
@@ -247,17 +246,15 @@ function CapVideoUpload(props) {
|
|
|
247
246
|
const videoDurationValue = moment('1900-01-01 00:00:00').add(videoDuration, 'seconds').format("HH.mm.ss"); // to get the duration of video
|
|
248
247
|
return (
|
|
249
248
|
<Fragment key={videoSrc}>
|
|
250
|
-
{
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
</div>
|
|
260
|
-
)}
|
|
249
|
+
<div style={{ overflow: 'hidden' }}>
|
|
250
|
+
<CapButton
|
|
251
|
+
className="dragger-button video-reupload"
|
|
252
|
+
type="flat"
|
|
253
|
+
onClick={onReUpload}
|
|
254
|
+
>
|
|
255
|
+
<FormattedMessage {...messages.imageReUpload} />
|
|
256
|
+
</CapButton>
|
|
257
|
+
</div>
|
|
261
258
|
<div className={showVideoNameAndDuration ? 'video-panel' : 'video-panel-wp'}>
|
|
262
259
|
<video
|
|
263
260
|
width="230"
|
|
@@ -44,7 +44,7 @@ import EDMEditor from "../Edmeditor";
|
|
|
44
44
|
import BeeEditor from '../../v2Containers/BeeEditor';
|
|
45
45
|
import CustomPopOver from '../CustomPopOver';
|
|
46
46
|
import messages from './messages';
|
|
47
|
-
import { makeSelectMetaEntities, selectCurrentOrgDetails, selectLiquidStateDetails
|
|
47
|
+
import { makeSelectMetaEntities, selectCurrentOrgDetails, selectLiquidStateDetails } from "../../v2Containers/Cap/selectors";
|
|
48
48
|
import * as actions from "../../v2Containers/Cap/actions";
|
|
49
49
|
import './_formBuilder.scss';
|
|
50
50
|
import {updateCharCount, checkUnicode} from "../../utils/smsCharCountV2";
|
|
@@ -52,11 +52,10 @@ import { checkSupport, extractNames, preprocessHtml, validateIfTagClosed } from
|
|
|
52
52
|
import { SMS, MOBILE_PUSH, LINE, ENABLE_AI_SUGGESTIONS,AI_CONTENT_BOT_DISABLED, EMAIL, LIQUID_SUPPORTED_CHANNELS } from '../../v2Containers/CreativesContainer/constants';
|
|
53
53
|
import globalMessages from '../../v2Containers/Cap/messages';
|
|
54
54
|
import { convert } from 'html-to-text';
|
|
55
|
-
import {
|
|
55
|
+
import { OUTBOUND } from './constants';
|
|
56
56
|
import { GET_TRANSLATION_MAPPED } from '../../containers/TagList/constants';
|
|
57
57
|
import moment from 'moment';
|
|
58
58
|
import { CUSTOMER_BARCODE_TAG , COPY_OF, ENTRY_TRIGGER_TAG_REGEX} from '../../containers/App/constants';
|
|
59
|
-
import { REQUEST } from '../../v2Containers/Cap/constants'
|
|
60
59
|
import { hasLiquidSupportFeature, isEmailUnsubscribeTagMandatory } from '../../utils/common';
|
|
61
60
|
import { isUrl } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
62
61
|
import { bindActionCreators } from 'redux';
|
|
@@ -1083,7 +1082,6 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1083
1082
|
}
|
|
1084
1083
|
});}
|
|
1085
1084
|
}
|
|
1086
|
-
|
|
1087
1085
|
saveForm(saveForm) {
|
|
1088
1086
|
if (this.props.isNewVersionFlow && !saveForm) {
|
|
1089
1087
|
this.props.getValidationData();
|
|
@@ -1094,7 +1092,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1094
1092
|
const templateContent = this.state.formData?.base?.en?.["template-content"] || "";
|
|
1095
1093
|
//Converts given HTML content to plain text string.
|
|
1096
1094
|
const content = convert(
|
|
1097
|
-
templateContent
|
|
1095
|
+
templateContent
|
|
1098
1096
|
);
|
|
1099
1097
|
/*
|
|
1100
1098
|
The `handleResult` function is used as a callback for `getLiquidTags` to handle the results post-processing.
|
|
@@ -3795,7 +3793,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3795
3793
|
|
|
3796
3794
|
|
|
3797
3795
|
return (
|
|
3798
|
-
<CapSpin spinning={Boolean(
|
|
3796
|
+
<CapSpin spinning={Boolean(this.liquidFlow && this.props.liquidExtractionInProgress)} tip={this.props.intl.formatMessage(messages.liquidSpinText)} >
|
|
3799
3797
|
<CapRow>
|
|
3800
3798
|
{this.props.schema && this.renderForm()}
|
|
3801
3799
|
<SlideBox
|
|
@@ -3829,7 +3827,6 @@ FormBuilder.defaultProps = {
|
|
|
3829
3827
|
isNewVersionFlow: false,
|
|
3830
3828
|
userLocale: localStorage.getItem('jlocale') || 'en',
|
|
3831
3829
|
showLiquidErrorInFooter: () => {},
|
|
3832
|
-
metaDataStatus: "",
|
|
3833
3830
|
};
|
|
3834
3831
|
|
|
3835
3832
|
FormBuilder.propTypes = {
|
|
@@ -3877,13 +3874,12 @@ FormBuilder.propTypes = {
|
|
|
3877
3874
|
isFullMode: PropTypes.bool,
|
|
3878
3875
|
currentOrgDetails: PropTypes.object,
|
|
3879
3876
|
liquidExtractionInProgress: PropTypes.bool,
|
|
3880
|
-
showLiquidErrorInFooter: PropTypes.func
|
|
3877
|
+
showLiquidErrorInFooter: PropTypes.func,
|
|
3881
3878
|
};
|
|
3882
3879
|
|
|
3883
3880
|
const mapStateToProps = createStructuredSelector({
|
|
3884
3881
|
currentOrgDetails: selectCurrentOrgDetails(),
|
|
3885
3882
|
liquidExtractionInProgress: selectLiquidStateDetails(),
|
|
3886
|
-
metaDataStatus: selectMetaDataStatus(),
|
|
3887
3883
|
metaEntities: makeSelectMetaEntities(),
|
|
3888
3884
|
});
|
|
3889
3885
|
|
|
@@ -567,10 +567,6 @@
|
|
|
567
567
|
font-size: 10px;
|
|
568
568
|
font-family: 'open-sans';
|
|
569
569
|
}
|
|
570
|
-
&.message-pop-carousel {
|
|
571
|
-
position: relative;
|
|
572
|
-
margin-right: $CAP_SPACE_04;
|
|
573
|
-
}
|
|
574
570
|
}
|
|
575
571
|
}
|
|
576
572
|
.android-push-message-Container, .iphone-push-message-Container{
|
|
@@ -751,22 +747,6 @@
|
|
|
751
747
|
width: 153px;
|
|
752
748
|
}
|
|
753
749
|
}
|
|
754
|
-
|
|
755
|
-
.msg-container-carousel {
|
|
756
|
-
display: flex;
|
|
757
|
-
flex-direction: column;
|
|
758
|
-
.scroll-container {
|
|
759
|
-
overflow-x: auto;
|
|
760
|
-
display: flex;
|
|
761
|
-
padding-top: $CAP_SPACE_06;
|
|
762
|
-
padding-right: $CAP_SPACE_06;
|
|
763
|
-
white-space: nowrap;
|
|
764
|
-
scrollbar-width: none; // Hide scrollbar in Firefox
|
|
765
|
-
&::-webkit-scrollbar {
|
|
766
|
-
display: none; // Hide scrollbar in Chrome/Safari/Opera
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
750
|
}
|
|
771
751
|
|
|
772
752
|
.align-center {
|