@capillarytech/creatives-library 6.16.0 → 7.0.0

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.
@@ -1,509 +0,0 @@
1
- /* eslint-disable react/sort-comp */
2
- /* eslint-disable dot-notation */
3
- /* eslint-disable no-undef */
4
- /*
5
- *
6
- * MobilepushWrapper
7
- *
8
- */
9
- import PropTypes from 'prop-types';
10
- import React from 'react';
11
- import { bindActionCreators } from 'redux';
12
- import { FormattedMessage, intlShape } from 'react-intl';
13
- import { createStructuredSelector } from 'reselect';
14
- import {
15
- CapRadioCard,
16
- CapSpin,
17
- CapHeading,
18
- CapHeader,
19
- CapButton,
20
- CapIcon,
21
- CapLink,
22
- CapRow,
23
- CapColumn,
24
- CapInput,
25
- CapLabel,
26
- CapTag,
27
- CapTreeSelect,
28
- CapDivider,
29
- } from '@capillarytech/cap-ui-library';
30
- import { find, cloneDeep, findIndex, isEmpty, isEqual, filter } from 'lodash';
31
- import * as actions from './actions';
32
- import { makeSelectFTP, makeSelectMetaEntities } from './selectors';
33
- import withCreatives from '../../hoc/withCreatives';
34
- import messages from './messages';
35
- import './_FTP.scss';
36
- import * as globalActions from '../../containers/Cap/actions';
37
- import { TagList } from '../TagList';
38
- import { NO_COMMUNICATION } from '../App/constants';
39
- import { getTreeStructuredTags } from '../../utils/common';
40
-
41
- const UIView = {
42
- serverSelection: 'serverSelection',
43
- configureMessage: 'configureMessage',
44
- };
45
- const { CapLabelInline } = CapLabel;
46
- export class FTP extends React.Component { // eslint-disable-line react/prefer-stateless-function
47
- constructor(props) {
48
- super(props);
49
- this.state = this.getInitialState();
50
- }
51
- getInitialState = () => {
52
- const mode = this.props.mode || 'create';
53
- let stateObj = {};
54
- if (mode === 'create') {
55
- const { formatMessage } = this.props.intl;
56
- const headerTagList = [{
57
- header: formatMessage(messages.customerID),
58
- tag: '{{user_id}}',
59
- }];
60
- stateObj = {
61
- mode,
62
- selectedServer: null,
63
- viewMode: UIView.serverSelection,
64
- headerTagList,
65
- messageContent: '',
66
- tagsTree: [],
67
- };
68
- } else {
69
- const { messageContent = {} } = this.props.messageDetails || {};
70
- const messageContent1 = (messageContent['message_content_id_1'] || {}).messageBody;
71
- const headerTagList = (messageContent['message_content_id_1'] || {}).headerTagList || [];
72
- stateObj = {
73
- mode,
74
- selectedServer: null,
75
- viewMode: UIView.configureMessage,
76
- headerTagList,
77
- messageContent: messageContent1,
78
- tagsTree: [],
79
- };
80
- }
81
- return stateObj;
82
- };
83
-
84
- setFTPServerInState = (FTPServers) => {
85
- const { deliverySetting = {} } = this.props.messageDetails;
86
- const configId = deliverySetting.channelSetting[NO_COMMUNICATION].endPointConfigs.ftpConfigId;
87
- const selectedServer = find(FTPServers, {id: configId});
88
- this.setState({ selectedServer });
89
- };
90
-
91
- componentDidMount() {
92
- this.props.actions.getFTPServers();
93
- const query = {
94
- layout: 'SMS',
95
- type: 'TAG',
96
- context: 'outbound',
97
- embedded: 'embedded',
98
- };
99
- this.props.globalActions.fetchSchemaForEntity(query);
100
- }
101
-
102
- componentWillReceiveProps(nextProps) {
103
- if (
104
- !isEmpty(((nextProps.metaEntities || {}).tags || {}).standard) &&
105
- !isEqual(((nextProps.metaEntities || {}).tags || {}).standard, ((this.props.metaEntities || {}).tags || {}).standard)
106
- ) {
107
- const tags = getTreeStructuredTags({tagsList: nextProps.metaEntities.tags.standard, offerDetails: nextProps.selectedOfferDetails});
108
- this.setState({ tagsTree: tags}, () => this.disableUsedColumns());
109
- }
110
-
111
- if (
112
- nextProps.mode === 'edit' &&
113
- (nextProps.FTP || {}).FTPServers.length &&
114
- !isEqual((nextProps.FTP || {}).FTPServers, (this.props.FTP || {}).FTPServers)
115
- ) {
116
- this.setFTPServerInState(nextProps.FTP.FTPServers);
117
- }
118
- }
119
-
120
- onChangeFTPServer = (e) => {
121
- const { value } = e.target;
122
- const { FTPServers = [] } = this.props.FTP || {};
123
- const selectedServer = find(FTPServers, {id: value});
124
- this.setState({ selectedServer, viewMode: UIView.configureMessage});
125
- };
126
-
127
- onTagSelect = (data) => {
128
- this.insertAtCursor(`{{${data}}}`);
129
- };
130
-
131
- setInputRef = (textarea) => {
132
- this.textArea = textarea;
133
- };
134
-
135
- getServerSelectionContent = () => {
136
- const { getFTPServersInProgress } = this.props.FTP || {};
137
- const { formatMessage } = this.props.intl;
138
- const serverOptions = this.getServerOptions();
139
- const { selectedServer } = this.state;
140
- return (
141
- <CapSpin spinning={getFTPServersInProgress}>
142
- <CapHeading
143
- type="h3"
144
- className="select-account-header"
145
- >
146
- {formatMessage(messages.ftpServer)}
147
- </CapHeading>
148
- <CapHeading type="h6" className="manage-ftp-setting-div">
149
- {formatMessage(messages.ftpServerDesc)}
150
- <CapLink
151
- title={formatMessage(messages.manageFTPSettings)}
152
- className="select-server"
153
- onClick={this.handleManageFTPSettings}
154
- />
155
- </CapHeading>
156
- <CapRadioCard
157
- className="select-account"
158
- onChange={this.onChangeFTPServer}
159
- panes={serverOptions}
160
- cardHeight="48px"
161
- cardWidth="276px"
162
- size="small"
163
- defaultValue={selectedServer}
164
- selected={selectedServer}
165
- />
166
- </CapSpin>
167
- );
168
- };
169
-
170
- getServerOptions = () => {
171
- const { FTPServers = [] } = this.props.FTP || {};
172
- return (FTPServers).map(({
173
- // eslint-disable-next-line camelcase
174
- ftp_tag = '',
175
- id,
176
- }) => ({
177
- key: ftp_tag,
178
- value: id,
179
- title: ftp_tag,
180
- icon: <CapIcon.CapIconAvatar text={ftp_tag[0]} width="auto" height="2rem"/>,
181
- }));
182
- };
183
-
184
- getMessageContent = () => {
185
- const { messageContent } = this.state;
186
- const { formatMessage } = this.props.intl;
187
- const { metaEntities, selectedOfferDetails } = this.props;
188
- const tagsRaw = metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
189
- return (
190
- <CapRow>
191
- <CapColumn span={11}>
192
- <div className="message-content-title">
193
- <TagList
194
- className="FTP-tagList"
195
- label={formatMessage(messages.addLabel)}
196
- tags={tagsRaw}
197
- onTagSelect={this.onTagSelect}
198
- selectedOfferDetails={selectedOfferDetails}
199
- />
200
- <CapInput.TextArea
201
- setInputRef={this.setInputRef}
202
- label={formatMessage(messages.messageHeader)}
203
- onChange={this.updateMessageBody}
204
- value={messageContent}
205
- />
206
- </div>
207
- </CapColumn>
208
- </CapRow>
209
- );
210
- };
211
-
212
- getCsvColumns = () => {
213
- const { headerTagList = [], tagsTree = [] } = this.state;
214
- const { formatMessage } = this.props.intl;
215
- const tagsWithoutOptout = tagsTree.length && tagsTree.filter((tag) => tag.value !== '{{optout}}');
216
- const headerTagElements = headerTagList.map((item, index) => (
217
- index !== 0 && <div className="column-selection-container">
218
- <CapSpin spinning={!tagsWithoutOptout.length}>
219
- <CapTreeSelect
220
- dropdownClassName="select-csv-col-dropdown"
221
- treeData={tagsWithoutOptout}
222
- className="select-csv-column"
223
- value={!isEmpty(item.header) ? item.header : formatMessage(messages.selectTag)}
224
- onChange={(option, label) => this.selectCsvColumn(option, label, index)}
225
- showSearch
226
- />
227
- <CapIcon
228
- type="close"
229
- size="m"
230
- onClick={() => this.removeCsvColumn(item)}
231
- className="remove-csv-column"
232
- />
233
- </CapSpin>
234
- </div>
235
- ));
236
- headerTagElements.unshift(
237
- <CapLabelInline
238
- className="column-selection-container-cid"
239
- type="label2"
240
- style={{fontSize: 14, fontWeight: 500}}
241
- >
242
- <FormattedMessage {...messages.customerID}/>
243
- </CapLabelInline>
244
- );
245
- return headerTagElements;
246
- };
247
-
248
- getConfigureCsvContent = () => {
249
- const { formatMessage } = this.props.intl;
250
- return (
251
- <>
252
- <CapRow className="configure-csv-container">
253
- <CapColumn span={8} className="configure-csv">
254
- <CapHeader
255
- title={formatMessage(messages.configureCsv)}
256
- size="regular"
257
- className="select-account-header"
258
- />
259
- </CapColumn>
260
- <CapColumn span={3} offset={13} className="add-column">
261
- <CapButton
262
- type="flat"
263
- isAddBtn
264
- onClick={this.addNewColumn}
265
- >
266
- <FormattedMessage {...messages.addColumn} />
267
- </CapButton>
268
- </CapColumn>
269
- </CapRow>
270
- {this.getCsvColumns()}
271
- </>
272
- );
273
- }
274
-
275
- getConfigureMessageContent = () => {
276
- const { formatMessage } = this.props.intl;
277
- const { selectedServer = {}, headerTagList = [] } = this.state;
278
- const emptyHeaderTagList = filter(headerTagList, {tag: ''});
279
- const disableDoneButton = isEmpty(selectedServer) || emptyHeaderTagList.length;
280
- return (
281
- <CapSpin spinning={false}>
282
- <div className="scrollable-section">
283
- <CapHeader
284
- title={formatMessage(messages.ftpServer)}
285
- size="regular"
286
- className="select-account-header"
287
- />
288
- <div className="selected-server-name">
289
- <CapIcon.CapIconAvatar
290
- className="server-avtar"
291
- text={((selectedServer || {}).ftp_tag || [])[0]}
292
- width="auto"
293
- height="2rem"
294
- />
295
- <CapHeading
296
- type="h4"
297
- className="server-name"
298
- >
299
- {(selectedServer || {}).ftp_tag}
300
- </CapHeading>
301
- <CapLink
302
- title={formatMessage(messages.change)}
303
- className="server-change"
304
- onClick={this.showAccountSelection}
305
- />
306
- </div>
307
- <CapDivider />
308
- {this.getConfigureCsvContent()}
309
- <CapDivider />
310
- <div className="ftp-message-container">
311
- <CapHeader
312
- title={formatMessage(messages.messageContent)}
313
- description={formatMessage(messages.optional)}
314
- size="regular"
315
- inline
316
- />
317
- {this.getMessageContent()}
318
- </div>
319
- </div>
320
- <CapButton
321
- type="primary"
322
- disabled={disableDoneButton}
323
- onClick={this.saveFtpMessage}
324
- >
325
- <FormattedMessage {...messages.done} />
326
- </CapButton>
327
- </CapSpin>
328
- );
329
- };
330
-
331
- getColumnsHeaderPreview = (headerTagList) => (
332
- <div className="ftp-preview-data-col-container">
333
- { headerTagList.map((tag) => (
334
- <CapTag type="static" className="ftp-preview-data-col-tag">
335
- {tag.header}
336
- </CapTag>
337
- ))}
338
- </div>
339
- );
340
-
341
- getPreviewModeContents = () => {
342
- const { contents = [] } = this.props;
343
- const { messageBody = '', headerTagList = [] } = contents[0] || {};
344
- return (
345
- <div className="ftp-preview-container">
346
- <CapHeading className="ftp-preview-message-title" type="h3">
347
- <FormattedMessage {...messages.messageContent}/>
348
- </CapHeading>
349
- <CapLabel type="label2" className="ftp-preview-message-content">
350
- {messageBody}
351
- </CapLabel>
352
- <CapHeading className="ftp-preview-data-title" type="h3">
353
- <FormattedMessage {...messages.dataPreview}/>
354
- </CapHeading>
355
- {this.getColumnsHeaderPreview(headerTagList)}
356
- </div>
357
- );
358
- };
359
-
360
- showAccountSelection = () => {
361
- this.setState({ viewMode: UIView.serverSelection, selectedServer: null, headerTagList: [], messageContent: ''});
362
- };
363
-
364
- selectCsvColumn = (option, label, index) => {
365
- const { headerTagList } = this.state;
366
- const clonedHeaderTagList = cloneDeep(headerTagList);
367
- const obj = {
368
- header: label[0],
369
- tag: option,
370
- };
371
- clonedHeaderTagList[index] = obj;
372
- this.setState({ headerTagList: clonedHeaderTagList}, () => this.disableUsedColumns());
373
- };
374
-
375
- disableUsedColumns = () => {
376
- const { headerTagList = [] } = this.state;
377
- const { selectedOfferDetails = [], metaEntities = {} } = this.props;
378
- const tags = getTreeStructuredTags({tagsList: (metaEntities.tags || {}).standard, offerDetails: selectedOfferDetails});
379
- const clonnedTagsTree = cloneDeep(tags);
380
- headerTagList.map((headerTag) => {
381
- const pos = findIndex(clonnedTagsTree, {value: headerTag.tag});
382
- if (pos > -1) {
383
- clonnedTagsTree[pos] = {
384
- disabled: true,
385
- ...clonnedTagsTree[pos],
386
- };
387
- }
388
- return null;
389
- });
390
- this.setState({tagsTree: clonnedTagsTree});
391
- };
392
-
393
- handleManageFTPSettings = () => {
394
- const path = `/exports/configurations`;
395
- window.open(path, '_blank');
396
- };
397
-
398
- removeCsvColumn = (item) => {
399
- const { headerTagList } = this.state;
400
- const clonedHeaderTagList = cloneDeep(headerTagList);
401
- const index = findIndex(headerTagList, (val) => val.tag === item.tag);
402
- clonedHeaderTagList.splice(index, 1);
403
- this.setState({ headerTagList: clonedHeaderTagList}, () => this.disableUsedColumns());
404
- };
405
-
406
- addNewColumn = () => {
407
- const { headerTagList } = this.state;
408
- const clonedHeaderTagList = cloneDeep(headerTagList);
409
- const newCsvObj = {
410
- header: '',
411
- tag: '',
412
- };
413
- clonedHeaderTagList.push(newCsvObj);
414
- this.setState({ headerTagList: clonedHeaderTagList});
415
- };
416
-
417
- insertAtCursor = (myValue) => {
418
- this.textArea.focus();
419
- const textAreaRef = this.textArea.textAreaRef;
420
- let pos = textAreaRef.selectionEnd + myValue.length;
421
- //IE support
422
- let newMessage = textAreaRef.value + myValue;
423
- if (document.selection) {
424
- this.textArea.focus();
425
- const sel = document.selection.createRange();
426
- sel.text = myValue;
427
- } else if (textAreaRef.selectionStart || textAreaRef.selectionStart === '0') { //MOZILLA and others
428
- const startPos = textAreaRef.selectionStart;
429
- const endPos = textAreaRef.selectionEnd;
430
- newMessage = textAreaRef.value.substring(0, startPos) + myValue + textAreaRef.value.substring(endPos, textAreaRef.value.length);
431
- pos = startPos + myValue.length;
432
- }
433
- this.setState({
434
- messageContent: newMessage,
435
- }, () => {
436
- textAreaRef.selectionStart = pos;
437
- textAreaRef.selectionEnd = pos;
438
- });
439
- };
440
-
441
- updateMessageBody = (e) => {
442
- this.setState({
443
- messageContent: e.target.value,
444
- });
445
- };
446
-
447
- saveFtpMessage = () => {
448
- const { onFTPSubmit } = this.props;
449
- const { FTPServers = [] } = this.props.FTP || {};
450
- const { selectedServer = {}, headerTagList = [], messageContent = '' } = this.state;
451
- onFTPSubmit({
452
- channel: "FTP",
453
- endPointConfigs: {
454
- endPointType: "FTP",
455
- ftpConfigId: selectedServer.id,
456
- },
457
- headerTagList,
458
- messageContent,
459
- FTPServers,
460
- });
461
- };
462
-
463
- render() {
464
- const { viewMode } = this.state;
465
- const { serverSelection } = UIView;
466
- const { mode } = this.props;
467
- return (
468
- mode === 'preview' ?
469
- this.getPreviewModeContents() :
470
- (viewMode === serverSelection ?
471
- this.getServerSelectionContent() :
472
- this.getConfigureMessageContent()
473
- )
474
- );
475
- }
476
- }
477
-
478
- FTP.propTypes = {
479
- actions: PropTypes.object.isRequired,
480
- FTP: PropTypes.object,
481
- intl: intlShape.isRequired,
482
- globalActions: PropTypes.object,
483
- onFTPSubmit: PropTypes.func,
484
- messageDetails: PropTypes.object,
485
- mode: PropTypes.string,
486
- contents: PropTypes.array,
487
- metaEntities: PropTypes.object,
488
- selectedOfferDetails: PropTypes.array,
489
- };
490
-
491
-
492
- function mapDispatchToProps(dispatch) {
493
- return {
494
- actions: bindActionCreators(actions, dispatch),
495
- globalActions: bindActionCreators(globalActions, dispatch),
496
- };
497
- }
498
-
499
- const mapStateToProps = createStructuredSelector({
500
- FTP: makeSelectFTP(),
501
- metaEntities: makeSelectMetaEntities(),
502
- });
503
-
504
- export default withCreatives({
505
- WrappedComponent: FTP,
506
- mapStateToProps,
507
- mapDispatchToProps,
508
- suserAuth: true,
509
- });
@@ -1,60 +0,0 @@
1
- import { defineMessages } from 'react-intl';
2
-
3
- export default defineMessages({
4
- ftpServerDesc: {
5
- id: 'creatives.containersV2.FTP.ftpServerDesc',
6
- defaultMessage: 'Select the FTP server to send the message data. To add another FTP location, ',
7
- },
8
- ftpServer: {
9
- id: 'creatives.containersV2.FTP.ftpServer',
10
- defaultMessage: 'FTP Server',
11
- },
12
- configureCsv: {
13
- id: 'creatives.containersV2.FTP.configureCsv',
14
- defaultMessage: 'Configure CSV',
15
- },
16
- addColumn: {
17
- id: 'creatives.containersV2.FTP.addColumn',
18
- defaultMessage: 'Add column',
19
- },
20
- selectTag: {
21
- id: 'creatives.containersV2.FTP.selectTag',
22
- defaultMessage: 'Select tag',
23
- },
24
- done: {
25
- id: 'creatives.containersV2.FTP.done',
26
- defaultMessage: 'Done',
27
- },
28
- customerID: {
29
- id: 'creatives.containersV2.FTP.customerID',
30
- defaultMessage: 'Customer ID',
31
- },
32
- change: {
33
- id: 'creatives.containersV2.FTP.change',
34
- defaultMessage: 'Change',
35
- },
36
- manageFTPSettings: {
37
- id: 'creatives.containersV2.FTP.manageFTPSettings',
38
- defaultMessage: 'manage FTP settings',
39
- },
40
- addLabel: {
41
- id: 'creatives.containersV2.FTP.addLabel',
42
- defaultMessage: 'Add Labels',
43
- },
44
- messageHeader: {
45
- id: 'creatives.containersV2.FTP.messageHeader',
46
- defaultMessage: 'Message',
47
- },
48
- messageContent: {
49
- id: 'creatives.containersV2.FTP.messageContent',
50
- defaultMessage: 'Message Content',
51
- },
52
- optional: {
53
- id: 'creatives.containersV2.FTP.optional',
54
- defaultMessage: '(optional)',
55
- },
56
- dataPreview: {
57
- id: 'creatives.containersV2.FTP.dataPreview',
58
- defaultMessage: 'Data Preview',
59
- },
60
- });
@@ -1,32 +0,0 @@
1
- import { fromJS } from 'immutable';
2
- import * as types from './constants';
3
-
4
- const initialState = fromJS({
5
- getFTPServersInProgress: false,
6
- FTPServers: [],
7
- getFTPServersError: false,
8
- });
9
-
10
- function createReducer(state = initialState, action) {
11
- switch (action.type) {
12
- case types.GET_FTP_SERVERS_REQUEST:
13
- return state
14
- .set('getFTPServersInProgress', true)
15
- .set('FTPServers', [])
16
- .set('getFTPServersInProgress', true);
17
- case types.GET_FTP_SERVERS_SUCCESS:
18
- return state
19
- .set('getFTPServersInProgress', false)
20
- .set('FTPServers', action.data)
21
- .set('getFTPServersInProgress', false);
22
- case types.GET_FTP_SERVERS_FAILURE:
23
- return state
24
- .set('getFTPServersInProgress', false)
25
- .set('FTPServers', [])
26
- .set('getFTPServersInProgress', true);
27
- default:
28
- return state;
29
- }
30
- }
31
-
32
- export default createReducer;
@@ -1,26 +0,0 @@
1
- import { take, cancel, call, put, takeLatest } from 'redux-saga/effects';
2
- import { LOCATION_CHANGE } from 'react-router-redux';
3
- import * as Api from '../../services/api';
4
- import * as types from './constants';
5
-
6
- // Individual exports for testing
7
- export function* getFTPServers() {
8
- try {
9
- const result = yield call(Api.getFTPServers);
10
- yield put({ type: types.GET_FTP_SERVERS_SUCCESS, data: result.response });
11
- } catch (error) {
12
- yield put({ type: types.GET_FTP_SERVERS_FAILURE, error });
13
- }
14
- }
15
-
16
-
17
- function* watchGetFTPServers() {
18
- const watcher = yield takeLatest(types.GET_FTP_SERVERS_REQUEST, getFTPServers);
19
- yield take(LOCATION_CHANGE);
20
- yield cancel(watcher);
21
- }
22
-
23
- // All sagas to be loaded
24
- export default [
25
- watchGetFTPServers,
26
- ];
@@ -1,20 +0,0 @@
1
- import { createSelector } from 'reselect';
2
- import { fromJS } from 'immutable';
3
-
4
- const selectFTPMessageCreateDomain = () => (state) => state.get('FTP') || fromJS({});
5
- const selectCapDomain = (state) => state.get('cap');
6
-
7
- const makeSelectFTP = () => createSelector(
8
- selectFTPMessageCreateDomain(),
9
- (substate = fromJS({})) => substate.toJS()
10
- );
11
- const makeSelectMetaEntities = () => createSelector(
12
- selectCapDomain,
13
- (globalState = fromJS({})) => globalState.get('metaEntities')
14
- );
15
-
16
-
17
- export {
18
- makeSelectFTP,
19
- makeSelectMetaEntities,
20
- };