@capillarytech/creatives-library 7.2.1 → 7.3.1
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/components/TopBar/assets/images/capillary_logo.png +0 -0
- package/components/TopBar/assets/images/old_capillary_logo.png +0 -0
- package/config/app.js +2 -0
- package/containers/Templates/index.js +2 -2
- package/favicon.ico +0 -0
- package/index.js +7 -0
- package/old_favicon.ico +0 -0
- package/package.json +1 -1
- package/reducers.js +2 -1
- package/services/api.js +6 -0
- package/utils/common.js +178 -0
- package/v2Components/TemplatePreview/assets/images/mobile.svg +24 -0
- package/v2Containers/App/constants.js +5 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +17 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -1
- package/v2Containers/CreativesContainer/constants.js +2 -0
- package/v2Containers/CreativesContainer/index.js +8 -0
- package/v2Containers/Email/index.js +1 -0
- package/v2Containers/FTP/_FTP.scss +14 -3
- package/v2Containers/FTP/index.js +82 -18
- package/v2Containers/FTP/messages.js +8 -0
- package/v2Containers/FTP/temp.js +11838 -0
- package/v2Containers/Templates/index.js +1 -1
- package/v2Containers/TemplatesV2/index.js +13 -0
- package/v2Containers/TemplatesV2/messages.js +4 -0
|
Binary file
|
|
Binary file
|
package/config/app.js
CHANGED
|
@@ -11,6 +11,7 @@ const config = {
|
|
|
11
11
|
dashboard_url: '/sms',
|
|
12
12
|
dashboard_url_v2: '/v2',
|
|
13
13
|
subscription_api_endpoint: '/arya/api/v1/org-settings/subscription',
|
|
14
|
+
exports_api_endpoint: '/arya/api/v1/export/data',
|
|
14
15
|
accountConfig: (strs, accountId) => `${window.location.origin}/org/config/AccountAdd?q=a&channelId=2&accountId=${accountId}&edit=1`,
|
|
15
16
|
},
|
|
16
17
|
development: {
|
|
@@ -19,6 +20,7 @@ const config = {
|
|
|
19
20
|
auth_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1/auth',
|
|
20
21
|
arya_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1',
|
|
21
22
|
subscription_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1/org-settings/subscription',
|
|
23
|
+
exports_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/arya/api/v1/export/data',
|
|
22
24
|
login_url: '/auth/login',
|
|
23
25
|
dashboard_url: '/sms',
|
|
24
26
|
dashboard_url_v2: '/v2',
|
|
@@ -866,7 +866,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
866
866
|
duplicateTemplate(template) {
|
|
867
867
|
console.log('dup template', template);
|
|
868
868
|
const duplicateObj = _.cloneDeep(template);
|
|
869
|
-
duplicateObj.name = `Copy of ${template.name} ${moment().format('MM-DD-YYYY
|
|
869
|
+
duplicateObj.name = `Copy of ${template.name} ${moment().format('MM-DD-YYYY HH:mm:ss')}`;
|
|
870
870
|
delete duplicateObj._id;
|
|
871
871
|
if (this.state.channel.toLowerCase() === "sms") {
|
|
872
872
|
this.props.smsActions.createTemplate(duplicateObj);
|
|
@@ -1115,7 +1115,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1115
1115
|
{content}
|
|
1116
1116
|
</div>
|
|
1117
1117
|
{!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> : ''}
|
|
1118
|
-
{layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={() =>
|
|
1118
|
+
{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> : ''}
|
|
1119
1119
|
{!layoutSelection && template._id === this.state.hoveredItem ? <CapButton onClick={() => this.handlePreviewClick(template)} className="preview-button" type="cancel">{this.props.intl.formatMessage(messages.previewButton)}</CapButton> : ''}
|
|
1120
1120
|
</div>);
|
|
1121
1121
|
} else if (this.state.channel.toLowerCase() === 'mobilepush') {
|
package/favicon.ico
CHANGED
|
Binary file
|
package/index.js
CHANGED
|
@@ -56,6 +56,10 @@ import MobilepushCreate from './v2Containers/MobilePush/Create';
|
|
|
56
56
|
import mobilepushCreateReducer from './v2Containers/MobilePush/Create/reducer';
|
|
57
57
|
import mobilepushCreateSaga from './v2Containers/MobilePush/Create/sagas';
|
|
58
58
|
|
|
59
|
+
import FTP from './v2Containers/FTP';
|
|
60
|
+
import FTPReducer from './v2Containers/FTP/reducer';
|
|
61
|
+
import FTPSagas from './v2Containers/FTP/sagas';
|
|
62
|
+
|
|
59
63
|
import MobilepushEdit from './v2Containers/MobilePush/Edit';
|
|
60
64
|
import mobilepushEditReducer from './v2Containers/MobilePush/Edit/reducer';
|
|
61
65
|
import mobilepushEditSaga from './v2Containers/MobilePush/Edit/sagas';
|
|
@@ -99,6 +103,7 @@ const FacebookContainer = {Facebook, facebookReducer, facebookSaga};
|
|
|
99
103
|
const ViberContainer = {Viber, viberReducer, viberSaga};
|
|
100
104
|
|
|
101
105
|
const GalleryContainer = {Gallery, galleryReducer, gallerySagas};
|
|
106
|
+
const FTPContainer = {FTP, FTPReducer, FTPSagas};
|
|
102
107
|
|
|
103
108
|
export {default as TagList} from './v2Containers/TagList/index';
|
|
104
109
|
export {default as TagListSaga} from './v2Containers/TagList/sagas';
|
|
@@ -110,6 +115,7 @@ export {default as CallTaskPreview} from './v2Components/CallTaskPreview';
|
|
|
110
115
|
export {default as EmailMobilePreview} from './v2Components/EmailMobilePreview';
|
|
111
116
|
export {default as MobilePushPreview} from './v2Components/MobilePushPreviewV2';
|
|
112
117
|
export {default as WechatRichmediaTemplatePreview} from './v2Components/TemplatePreview/WechatRichmediaTemplatePreview';
|
|
118
|
+
export {default as FTP} from './v2Containers/FTP';
|
|
113
119
|
|
|
114
120
|
CreativesContainer.CreativesContainerReducer = CreativesContainerReducer;
|
|
115
121
|
|
|
@@ -137,5 +143,6 @@ export { CapContainer,
|
|
|
137
143
|
updateCharCount,
|
|
138
144
|
FacebookContainer,
|
|
139
145
|
GalleryContainer,
|
|
146
|
+
FTPContainer,
|
|
140
147
|
ViberContainer,
|
|
141
148
|
};
|
package/old_favicon.ico
ADDED
|
Binary file
|
package/package.json
CHANGED
package/reducers.js
CHANGED
|
@@ -19,7 +19,7 @@ import templateReducer from 'containers/Templates/reducer';
|
|
|
19
19
|
import tagsReducer from 'containers/TagList/reducer';
|
|
20
20
|
import emailReducer from 'containers/Email/reducer';
|
|
21
21
|
import ebillReducer from 'containers/Ebill/reducer';
|
|
22
|
-
|
|
22
|
+
import ftpReducer from 'v2Containers/FTP/reducer';
|
|
23
23
|
/*
|
|
24
24
|
* routeReducer
|
|
25
25
|
*
|
|
@@ -64,6 +64,7 @@ export default function createReducer(asyncReducers) {
|
|
|
64
64
|
email: emailReducer,
|
|
65
65
|
ebill: ebillReducer,
|
|
66
66
|
beeEditor: beeEditorReducer,
|
|
67
|
+
FTP: ftpReducer,
|
|
67
68
|
...asyncReducers,
|
|
68
69
|
});
|
|
69
70
|
}
|
package/services/api.js
CHANGED
|
@@ -9,6 +9,7 @@ import getSchema from './getSchema';
|
|
|
9
9
|
import * as API from '../utils/ApiCaller';
|
|
10
10
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
11
11
|
let API_ENDPOINT = config.development.api_endpoint;
|
|
12
|
+
let EXPORT_API_ENDPOINT = config.development.exports_api_endpoint;
|
|
12
13
|
let CAMPAIGNS_API_ENDPOINT = config.development.campaigns_api_endpoint;
|
|
13
14
|
let API_AUTH_ENDPOINT = config.development.auth_endpoint;
|
|
14
15
|
let ARYA_ENDPOINT = config.development.arya_endpoint;
|
|
@@ -213,6 +214,11 @@ export const duplicateTemplate = ({id, channel}) => {
|
|
|
213
214
|
return request(url, getAPICallObject('GET'));
|
|
214
215
|
};
|
|
215
216
|
|
|
217
|
+
export const getFTPServers = () => {
|
|
218
|
+
const url = `${EXPORT_API_ENDPOINT}/ftplist`;
|
|
219
|
+
return request(url, getAPICallObject('GET'));
|
|
220
|
+
};
|
|
221
|
+
|
|
216
222
|
export const editWeChatTemplate = ({template}) => {
|
|
217
223
|
console.log('in api.js', template);
|
|
218
224
|
const url = `${API_ENDPOINT}/templates/WECHAT`;
|
package/utils/common.js
CHANGED
|
@@ -37,3 +37,181 @@ export const hasStore2DoorFeature = Auth.hasFeatureAccess.bind(
|
|
|
37
37
|
null,
|
|
38
38
|
STORE2DOOR_PLUS_ENABLED,
|
|
39
39
|
);
|
|
40
|
+
|
|
41
|
+
export function getTreeStructuredTags({tagsList, userLocale = 'en', offerDetails = []}) {
|
|
42
|
+
console.log('populating tags', (tagsList || []).length);
|
|
43
|
+
const mainTags = {};
|
|
44
|
+
|
|
45
|
+
_.forEach(tagsList, (temp) => {
|
|
46
|
+
const tag = temp.definition;
|
|
47
|
+
if (!tag['tag-header']) { //if tag doesn't have subtag(s), which means this tag itself is tag and not a tag header.
|
|
48
|
+
mainTags[tag.value] = {
|
|
49
|
+
name: tag.label[userLocale] || tag.label.en,
|
|
50
|
+
value: tag.value,
|
|
51
|
+
};
|
|
52
|
+
} else if (tag['tag-header'] && mainTags[tag.value]) {
|
|
53
|
+
// to check it this tag header is already available in mainTags object,
|
|
54
|
+
//If yes, it will concat the subtag
|
|
55
|
+
mainTags[tag.value].subtags = _.concat(mainTags[tag.value].subtags, tag.subtags);
|
|
56
|
+
} else if (!mainTags[tag.value]) {
|
|
57
|
+
//If tag is not available in mainTag object, new maintag will be added.
|
|
58
|
+
mainTags[tag.value] = {
|
|
59
|
+
'tag-header': true,
|
|
60
|
+
"name": tag.label[userLocale] || tag.label.en,
|
|
61
|
+
"subtags": tag.subtags,
|
|
62
|
+
"value": tag.value,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const mainTagsCloned = _.cloneDeep(mainTags);
|
|
68
|
+
//Insert subtags in tag headers and reomve them from top level
|
|
69
|
+
const result = {};
|
|
70
|
+
_.forEach(mainTagsCloned, (tag, key) => {
|
|
71
|
+
if (tag['tag-header']) {
|
|
72
|
+
const tagWithChildren = populateTagForChildren(tag, mainTagsCloned, key);
|
|
73
|
+
tagWithChildren.resolved = true;
|
|
74
|
+
result[key] = tagWithChildren;
|
|
75
|
+
} else {
|
|
76
|
+
result[key] = tag;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
//Delete extra tag headers
|
|
81
|
+
_.forEach(result, (tag) => {
|
|
82
|
+
if (tag['tag-header']) {
|
|
83
|
+
_.forEach(tag.subtags, (subtag, key) => {
|
|
84
|
+
if (result[key]) {
|
|
85
|
+
result[key].deleted = true;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
//Actually delete them
|
|
91
|
+
_.forEach(result, (tag, key) => {
|
|
92
|
+
if (tag.deleted) {
|
|
93
|
+
delete result[key];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
let combinedTags = result;
|
|
97
|
+
if (offerDetails.length) {
|
|
98
|
+
combinedTags = transformCouponTags(offerDetails, result);
|
|
99
|
+
}
|
|
100
|
+
return getTreeStructureData(combinedTags);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function transformCouponTags(offerDetails, allTags) {
|
|
104
|
+
const couponTags = {};
|
|
105
|
+
const couponTagsKeys = Object.keys(_.get(allTags, 'coupon.subtags', []));
|
|
106
|
+
const withCouponId = (obj, id) => {
|
|
107
|
+
const tempObj = {};
|
|
108
|
+
if (obj.subtags) {
|
|
109
|
+
tempObj.subtags = _.mapValues(obj.subtags, (tag) => {
|
|
110
|
+
let val = tag.value;
|
|
111
|
+
val = `${val}(${id})`;
|
|
112
|
+
const newObj = {
|
|
113
|
+
...tag,
|
|
114
|
+
value: val,
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
...withCouponId(newObj, id),
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
...obj,
|
|
123
|
+
...tempObj,
|
|
124
|
+
couponSeriesId: id,
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
offerDetails.forEach((offer) => {
|
|
128
|
+
const { id, couponName, description, couponSeriesId } = offer;
|
|
129
|
+
const couponId = id || couponSeriesId;
|
|
130
|
+
const couponSubTags = {};
|
|
131
|
+
couponTagsKeys.forEach((couponTagKey) => {
|
|
132
|
+
let val = allTags.coupon.subtags[couponTagKey].value;
|
|
133
|
+
val = `${val}(${couponId})`;
|
|
134
|
+
const newObj = {
|
|
135
|
+
...allTags.coupon.subtags[couponTagKey],
|
|
136
|
+
value: val,
|
|
137
|
+
};
|
|
138
|
+
const couponSubTagsObj = withCouponId(newObj, couponId);
|
|
139
|
+
couponSubTags[couponTagKey] = couponSubTagsObj;
|
|
140
|
+
});
|
|
141
|
+
const couponNameFinal = couponName || description;
|
|
142
|
+
const key = couponNameFinal || couponId;
|
|
143
|
+
couponTags[key] = {
|
|
144
|
+
'tag-header': true,
|
|
145
|
+
'name': couponNameFinal || couponId,
|
|
146
|
+
'desc': couponNameFinal || couponId,
|
|
147
|
+
'couponSeriesId': couponId,
|
|
148
|
+
'subtags': couponSubTags,
|
|
149
|
+
'resolved': true,
|
|
150
|
+
'couponTags': true,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
// eslint-disable-next-line no-param-reassign
|
|
154
|
+
allTags.coupon.subtags = couponTags;
|
|
155
|
+
return allTags;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function populateTagForChildren(targetTag, tagsObject, tagValue) {
|
|
159
|
+
const tag = targetTag;
|
|
160
|
+
if (tag && tag['tag-header'] && !tag.resolved) {
|
|
161
|
+
const tempSubTags = {};
|
|
162
|
+
_.forEach(tag.subtags, (subtag) => {
|
|
163
|
+
if (tagsObject[subtag]) {
|
|
164
|
+
const children = populateTagForChildren(tagsObject[subtag], tagsObject, subtag);
|
|
165
|
+
children.resolved = true;
|
|
166
|
+
tempSubTags[subtag] = children;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
tag.subtags = tempSubTags;
|
|
170
|
+
return tag;
|
|
171
|
+
}
|
|
172
|
+
return tagsObject[tagValue];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function getTreeStructureData(data) {
|
|
176
|
+
const result = [];
|
|
177
|
+
_.forOwn(data, (mainTag) => {
|
|
178
|
+
const { name, value, subtags = [] } = mainTag;
|
|
179
|
+
if (!mainTag['tag-header']) {
|
|
180
|
+
result.push({
|
|
181
|
+
title: name,
|
|
182
|
+
value: `{{${value}}}`,
|
|
183
|
+
});
|
|
184
|
+
} else {
|
|
185
|
+
const obj = {
|
|
186
|
+
title: name,
|
|
187
|
+
value: `{{${value}}}`,
|
|
188
|
+
selectable: false,
|
|
189
|
+
};
|
|
190
|
+
obj.children = getSubTags(subtags);
|
|
191
|
+
result.push(obj);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getSubTags(subtagsParam) {
|
|
198
|
+
const result = [];
|
|
199
|
+
_.forOwn(subtagsParam, (subTag) => {
|
|
200
|
+
const { name, value, subtags = [] } = subTag;
|
|
201
|
+
if (_.isEmpty(subtags)) {
|
|
202
|
+
result.push({
|
|
203
|
+
title: name,
|
|
204
|
+
value: `{{${value}}}`,
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
const obj = {
|
|
208
|
+
title: name,
|
|
209
|
+
value: `{{${value}}}`,
|
|
210
|
+
selectable: false,
|
|
211
|
+
};
|
|
212
|
+
obj.children = getSubTags(subtags);
|
|
213
|
+
result.push(obj);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
return result;
|
|
217
|
+
}
|