@capillarytech/creatives-library 7.9.13 → 7.9.15

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.
Files changed (45) hide show
  1. package/assets/group.png +0 -0
  2. package/components/Card/index.js +1 -1
  3. package/components/Card/tests/__snapshots__/index.test.js.snap +22 -0
  4. package/components/Card/tests/index.test.js +19 -7
  5. package/containers/App/constants.js +2 -1
  6. package/helpers/intl-enzym-test-helpers.js +40 -0
  7. package/index.js +6 -0
  8. package/package.json +3 -2
  9. package/routes.js +5 -0
  10. package/services/api.js +9 -15
  11. package/utils/common.js +17 -4
  12. package/v2Components/CapTagList/index.js +38 -9
  13. package/v2Components/CapTagList/messages.js +4 -0
  14. package/v2Containers/Cap/constants.js +2 -0
  15. package/v2Containers/Cap/index.js +9 -2
  16. package/v2Containers/Cap/reducer.js +5 -1
  17. package/v2Containers/Cap/selectors.js +10 -1
  18. package/v2Containers/CreativesContainer/SlideBoxContent.js +10 -4
  19. package/v2Containers/CreativesContainer/SlideBoxHeader.js +6 -1
  20. package/v2Containers/CreativesContainer/messages.js +4 -0
  21. package/v2Containers/FTP/index.js +14 -4
  22. package/v2Containers/Sms/Create/index.js +5 -6
  23. package/v2Containers/Sms/Edit/sagas.js +1 -1
  24. package/v2Containers/SmsTrai/Create/actions.js +25 -0
  25. package/v2Containers/SmsTrai/Create/constants.js +74 -0
  26. package/v2Containers/SmsTrai/Create/index.js +681 -0
  27. package/v2Containers/SmsTrai/Create/index.scss +92 -0
  28. package/v2Containers/SmsTrai/Create/messages.js +116 -0
  29. package/v2Containers/SmsTrai/Create/reducer.js +43 -0
  30. package/v2Containers/SmsTrai/Create/sagas.js +36 -0
  31. package/v2Containers/SmsTrai/Create/selectors.js +26 -0
  32. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +10351 -0
  33. package/v2Containers/SmsTrai/Create/tests/index.test.js +77 -0
  34. package/v2Containers/SmsTrai/Create/tests/mockData.js +58 -0
  35. package/v2Containers/SmsTrai/Edit/constants.js +16 -0
  36. package/v2Containers/SmsTrai/Edit/index.js +483 -0
  37. package/v2Containers/SmsTrai/Edit/messages.js +58 -0
  38. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +16103 -0
  39. package/v2Containers/SmsTrai/Edit/tests/index.test.js +61 -0
  40. package/v2Containers/SmsTrai/Edit/tests/mockData.js +36 -0
  41. package/v2Containers/SmsWrapper/index.js +75 -0
  42. package/v2Containers/SmsWrapper/tests/index.test.js +10 -0
  43. package/v2Containers/Templates/_templates.scss +2 -0
  44. package/v2Containers/Templates/index.js +89 -27
  45. package/v2Containers/Templates/messages.js +16 -0
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import { mountWithIntl } from '../../../../../app/helpers/intl-enzym-test-helpers';
3
+ import { SmsTraiCreate } from '../index';
4
+ import { SAMPLE_CSV, DOWNLOAD_ISSUES_CSV } from '../constants';
5
+ import { mockData } from './mockData';
6
+
7
+ let file = [];
8
+ const renderHelper = (fileData) => {
9
+ file = new File(mockData.contents, fileData.name, {
10
+ type: fileData.type,
11
+ });
12
+ };
13
+
14
+ jest.mock('papaparse', () => ({
15
+ parse: (file, response) => {
16
+ response.complete({ data: mockData.contents }, file);
17
+ },
18
+ }));
19
+
20
+ describe('Creatives SmsTraiCreate test/>', () => {
21
+ let renderedComponent;
22
+ const clearCreateResponse = jest.fn();
23
+ const createSMSTRAITemplates = jest.fn();
24
+ const onCreateComplete = jest.fn();
25
+ const setAttribute = jest.fn();
26
+ beforeEach(() => {
27
+ renderedComponent = mountWithIntl(
28
+ <SmsTraiCreate
29
+ actions={{ clearCreateResponse, createSMSTRAITemplates }}
30
+ onCreateComplete={onCreateComplete}
31
+ />,
32
+ );
33
+ });
34
+
35
+ it('renders UI', () => {
36
+ expect(renderedComponent).toMatchSnapshot();
37
+ });
38
+
39
+ it('clicking on Sample CSV should download sample CSV file', () => {
40
+ const event = { target: { setAttribute } };
41
+ renderedComponent.find('.download-sample-link').props().onClick(event);
42
+ expect(setAttribute).toHaveBeenCalledWith('download', SAMPLE_CSV);
43
+ });
44
+
45
+ it('done button should be disabled initially', () => {
46
+ const buttonProps = renderedComponent.find('button.done-button').props();
47
+ expect(buttonProps.disabled).toBe(true);
48
+ });
49
+
50
+ it('invalid file drop', async () => {
51
+ renderHelper(mockData.invalidFile);
52
+ const dropZone = renderedComponent.find('Dropzone').props();
53
+ await dropZone.onDrop([file]);
54
+ renderedComponent.update();
55
+ expect(renderedComponent).toMatchSnapshot();
56
+ expect(renderedComponent.find('button.done-button').props().disabled).toBe(
57
+ true,
58
+ );
59
+ });
60
+
61
+ it('valid file drop', async () => {
62
+ const event = { target: { setAttribute } };
63
+ renderHelper(mockData.validFile);
64
+ const dropZone = renderedComponent.find('Dropzone').props();
65
+ await dropZone.onDrop([file]);
66
+ renderedComponent.update();
67
+ expect(renderedComponent).toMatchSnapshot();
68
+ expect(renderedComponent.find('button.done-button').props().disabled).toBe(
69
+ false,
70
+ );
71
+ renderedComponent.find('a.download-issues-csv-link').props().onClick(event);
72
+ expect(setAttribute).toHaveBeenCalledWith('download', DOWNLOAD_ISSUES_CSV);
73
+ renderedComponent.find('button.done-button').props().onClick();
74
+ renderedComponent.update();
75
+ expect(renderedComponent).toMatchSnapshot();
76
+ });
77
+ });
@@ -0,0 +1,58 @@
1
+ export const mockData = {
2
+ invalidFile: {
3
+ type: 'application/json',
4
+ name: 'test.json',
5
+ },
6
+ validFile: {
7
+ type: 'text/csv',
8
+ name: 'test.csv',
9
+ },
10
+ contents: [
11
+ [
12
+ 'TEMPLATE ID',
13
+ 'TELEMARKETER',
14
+ 'TEMPLATE NAME',
15
+ 'TYPE',
16
+ 'SENDER ID',
17
+ 'CATEGORY',
18
+ 'REGISTERED DLT',
19
+ 'REQUESTED ON',
20
+ 'STATUS DATE',
21
+ 'APPROVAL STATUS',
22
+ 'STATUS',
23
+ 'TEMPLATE MESSAGE',
24
+ 'CONSENT TYPE',
25
+ ],
26
+ [
27
+ "'1107160277332377515'",
28
+ '--',
29
+ 'CAP71871_12',
30
+ 'Service-Explicit',
31
+ 'VISHMM',
32
+ '--',
33
+ 'Vodafone Idea',
34
+ '07/10/20 17:52',
35
+ '13/10/20 21:55',
36
+ 'Approved',
37
+ 'Active',
38
+ 'DUSSEHRA DEALS@VISHAL\n\nBUY1GET1 FREE\n{#var#}\n{#var#}\n{#var#}\n{#var#}\n+\n{#var#}\n{#var#}\n{#var#}\nTC',
39
+ 'Explicit',
40
+ ],
41
+ [
42
+ "'1107160277332377515'",
43
+ '--',
44
+ '',
45
+ 'Service-Explicit',
46
+ '',
47
+ '--',
48
+ 'Vodafone Idea',
49
+ '07/10/20 17:52',
50
+ '13/10/20 21:55',
51
+ '',
52
+ 'Active',
53
+ 'DUSSEHRA DEALS@VISHAL\n\nBUY1GET1 FREE\n{#var#}\n{#var#}\n{#var#}\n{#var#}\n+\n{#var#}\n{#var#}\n{#var#}\nTC',
54
+ 'Explicit',
55
+ ],
56
+ [''],
57
+ ],
58
+ };
@@ -0,0 +1,16 @@
1
+ /*
2
+ *
3
+ * SmsTrai constants
4
+ *
5
+ */
6
+
7
+ export const DEFAULT_ACTION = 'app/SmsTrai/DEFAULT_ACTION';
8
+ export const CHARLIMIT = 30;
9
+ export const SMS = 'SMS';
10
+ export const SMS_TRAI_VAR = '{#var#}';
11
+ export const TAG = 'TAG';
12
+ export const EMBEDDED = 'embedded';
13
+ export const DEFAULT = 'default';
14
+ export const FULL = 'full';
15
+ export const ALL = 'all';
16
+ export const LIBRARY = 'library';
@@ -0,0 +1,483 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { createStructuredSelector } from 'reselect';
3
+ import { bindActionCreators } from 'redux';
4
+ import { FormattedMessage, injectIntl } from 'react-intl';
5
+ import { get, cloneDeep, isEmpty } from 'lodash';
6
+ import styled from 'styled-components';
7
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
8
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
9
+ import CapButton from '@capillarytech/cap-ui-library/CapButton';
10
+ import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
11
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
12
+ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
13
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
14
+ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
15
+ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
16
+ import {
17
+ CAP_SPACE_16,
18
+ CAP_SPACE_12,
19
+ CAP_SPACE_24,
20
+ CAP_SPACE_32,
21
+ CAP_SPACE_04,
22
+ CAP_WHITE,
23
+ CAP_G10,
24
+ } from '@capillarytech/cap-ui-library/styled/variables';
25
+ import { makeSelectTemplateDetailsResponse } from '../../Sms/Edit/selectors';
26
+ import { makeSelectMetaEntities, setInjectedTags } from '../../Cap/selectors';
27
+ import * as actions from '../../Sms/Edit/actions';
28
+ import messages from './messages';
29
+ import TagList from '../../TagList';
30
+ import TemplatePreview from '../../../v2Components/TemplatePreview';
31
+ import withCreatives from '../../../hoc/withCreatives';
32
+
33
+ import {
34
+ CHARLIMIT,
35
+ SMS,
36
+ SMS_TRAI_VAR,
37
+ TAG,
38
+ EMBEDDED,
39
+ DEFAULT,
40
+ FULL,
41
+ ALL,
42
+ LIBRARY,
43
+ } from './constants';
44
+ let varMap = {};
45
+ const { TextArea } = CapInput;
46
+ const { CapLabelInline } = CapLabel;
47
+ export const SmsTraiEdit = (props) => {
48
+ const {
49
+ intl,
50
+ handleClose,
51
+ params,
52
+ actions,
53
+ templateDetails,
54
+ globalActions,
55
+ location,
56
+ getDefaultTags,
57
+ supportedTags,
58
+ metaEntities,
59
+ injectedTags,
60
+ onCreateComplete,
61
+ } = props || {};
62
+ const { formatMessage } = intl;
63
+ const [loading, updateLoading] = useState(true);
64
+ const [tempMsgArray, updateTempMsgArray] = useState([]);
65
+ const [updatedSmsEditor, setUpdatedSmsEditor] = useState([]);
66
+ const [tags, updateTags] = useState([]);
67
+ const [textAreaId, updateTextAreaId] = useState();
68
+ const [isValidationError, updateIsValidationError] = useState(false);
69
+ let totalVarCount = 0;
70
+ const SMSTraiFooter = styled.div`
71
+ background-color: ${CAP_WHITE};
72
+ position: fixed;
73
+ bottom: 0;
74
+ width: 100%;
75
+ margin-left: -32px;
76
+ padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
77
+ .ant-btn {
78
+ margin-right: ${CAP_SPACE_16};
79
+ }
80
+ }
81
+ `;
82
+ const TraiEditTemplateDetails = styled.div`
83
+ margin-bottom: ${CAP_SPACE_16};
84
+ ${CapLabelInline} {
85
+ margin-right: ${CAP_SPACE_12};
86
+ }
87
+ `;
88
+ useEffect(() => {
89
+ const { id } = params || {};
90
+ if (id) {
91
+ actions.getTemplateDetails(id);
92
+ //fetching tags
93
+ const query = {
94
+ layout: SMS,
95
+ type: TAG,
96
+ context:
97
+ location.query.type === EMBEDDED ? location.query.module : DEFAULT,
98
+ embedded: location.query.type === EMBEDDED ? location.query.type : FULL,
99
+ };
100
+ if (getDefaultTags) {
101
+ query.context = getDefaultTags;
102
+ }
103
+ globalActions.fetchSchemaForEntity(query);
104
+ }
105
+ return () => {
106
+ actions.resetEditTemplate();
107
+ };
108
+ }, []);
109
+
110
+ //computing placeholder array for mapping values and rendering dynamic form
111
+ useEffect(() => {
112
+ if (templateDetails && !isEmpty(templateDetails)) {
113
+ let msg = get(templateDetails, `versions.base.sms-editor`);
114
+ const templateMessageArray = [];
115
+ //converting sms-editor string to an array split at '{#var#}'
116
+ //split and push string before '{#var#}[0 to index]', push '{#var#}',
117
+ //split and repeat for remaining string[index+7 to length]
118
+ while (msg.length !== 0) {
119
+ const index = msg.search(SMS_TRAI_VAR);
120
+ if (index !== -1) {
121
+ templateMessageArray.push(msg.substring(0, index));
122
+ templateMessageArray.push(SMS_TRAI_VAR);
123
+ msg = msg.substring(index + 7, msg.length);
124
+ } else {
125
+ templateMessageArray.push(msg);
126
+ break;
127
+ }
128
+ }
129
+
130
+ const filteredTemplateMessageArray = templateMessageArray.filter(
131
+ (i) => i.trim() !== '',
132
+ );
133
+ updateTempMsgArray(filteredTemplateMessageArray);
134
+ //stop spinner
135
+ updateLoading(false);
136
+ }
137
+ }, [templateDetails]);
138
+
139
+ useEffect(() => {
140
+ if (tempMsgArray.length !== 0) {
141
+ //if varMapped and updated-sms-editor is already present on non first edits
142
+ if (!isEmpty(get(templateDetails, `versions.base.var-mapped`))) {
143
+ varMap = cloneDeep(get(templateDetails, `versions.base.var-mapped`));
144
+ setUpdatedSmsEditor(
145
+ get(templateDetails, `versions.base.updated-sms-editor`),
146
+ );
147
+ } else {
148
+ //computing varMap for first edit
149
+ let counter = 1;
150
+ for (let i = 0; i < tempMsgArray.length; i++) {
151
+ if (tempMsgArray[i] === SMS_TRAI_VAR) {
152
+ const nextElem =
153
+ tempMsgArray[i === tempMsgArray.length - 1 ? 0 : i + 1];
154
+ if (tempMsgArray[i] !== nextElem) {
155
+ varMap[`${tempMsgArray[i]}_${i - counter + 1}`] = {
156
+ data: '',
157
+ count: counter,
158
+ };
159
+ counter = 1;
160
+ } else {
161
+ counter++;
162
+ }
163
+ }
164
+ }
165
+ setUpdatedSmsEditor(tempMsgArray);
166
+ }
167
+ }
168
+ }, [tempMsgArray]);
169
+
170
+ useEffect(() => {
171
+ const previewCountElem = document.getElementsByClassName(
172
+ 'character-count-col',
173
+ );
174
+ if (previewCountElem.length === 1) {
175
+ previewCountElem[0].style.visibility = 'hidden';
176
+ }
177
+ }, []);
178
+
179
+ //Saving on done start
180
+ const onUpdateTemplateComplete = (editResponse, errorMsg) => {
181
+ if (editResponse?.templateId) {
182
+ CapNotification.success({
183
+ message: formatMessage(messages.smsEditNotification),
184
+ });
185
+ actions.clearEditResponse();
186
+ onCreateComplete();
187
+ } else if (errorMsg) {
188
+ CapNotification.error({
189
+ message: errorMsg,
190
+ });
191
+ }
192
+ };
193
+ const onDoneCallback = () => {
194
+ if (updatedSmsEditor.includes(SMS_TRAI_VAR)) {
195
+ //during save textbox should not be empty
196
+ updateIsValidationError(true);
197
+ } else {
198
+ //start spinner
199
+ updateLoading(true);
200
+ templateDetails.versions.base['var-mapped'] = varMap;
201
+ templateDetails.versions.base['updated-sms-editor'] = updatedSmsEditor;
202
+ templateDetails.versions.history = [templateDetails.versions.base];
203
+ actions.editTemplate(templateDetails, onUpdateTemplateComplete);
204
+ }
205
+ };
206
+ //Saving on done end
207
+
208
+ // tag code start
209
+ useEffect(() => {
210
+ let tag =
211
+ metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
212
+ if (
213
+ location.query.type === EMBEDDED &&
214
+ location.query.module === LIBRARY &&
215
+ !getDefaultTags
216
+ ) {
217
+ tag = supportedTags;
218
+ }
219
+ updateTags(tag);
220
+ }, [metaEntities]);
221
+
222
+ const handleOnTagsContextChange = (data) => {
223
+ const query = {
224
+ layout: SMS,
225
+ type: TAG,
226
+ context:
227
+ (data || '').toLowerCase() === ALL
228
+ ? DEFAULT
229
+ : (data || '').toLowerCase(),
230
+ embedded: location.query.type === EMBEDDED ? location.query.type : FULL,
231
+ };
232
+ globalActions.fetchSchemaForEntity(query);
233
+ };
234
+
235
+ const onTagSelect = (data) => {
236
+ if (textAreaId && varMap && updatedSmsEditor) {
237
+ const tempArr = [...updatedSmsEditor];
238
+ //when trying to insert tag in empty textarea,{#var#} is replaced with "" and then tag is added
239
+ if (tempArr[textAreaId] === SMS_TRAI_VAR) {
240
+ for (
241
+ let i = 0;
242
+ i < varMap[`${SMS_TRAI_VAR}_${textAreaId}`].count;
243
+ i++
244
+ ) {
245
+ tempArr[textAreaId + i] = '';
246
+ }
247
+ }
248
+ const messageData = `${tempArr[textAreaId]} {{${data}}}`;
249
+ tempArr[textAreaId] = messageData;
250
+ varMap[`${SMS_TRAI_VAR}_${textAreaId}`].data = messageData;
251
+ setUpdatedSmsEditor(tempArr);
252
+ }
253
+ };
254
+ //setting the id of currently selected text area, is used onTagSelect
255
+ const setTextAreaId = (event) => {
256
+ updateTextAreaId(Number(event.target.id));
257
+ };
258
+ // tag code end
259
+
260
+ // on change event of Text Area
261
+ const textAreaValueChange = ({ target: { value, id } }) => {
262
+ id = Number(id);
263
+ const arr = [...updatedSmsEditor];
264
+ varMap[`${SMS_TRAI_VAR}_${id}`].data = value;
265
+ if (value === '') {
266
+ for (let i = 0; i < varMap[`${SMS_TRAI_VAR}_${id}`].count; i++) {
267
+ arr[id + i] = SMS_TRAI_VAR;
268
+ }
269
+ } else {
270
+ for (let i = 0; i < varMap[`${SMS_TRAI_VAR}_${id}`].count; i++) {
271
+ if (i === 0) {
272
+ arr[id] = varMap[`${SMS_TRAI_VAR}_${id}`].data;
273
+ } else {
274
+ arr[id + i] = '';
275
+ }
276
+ }
277
+ }
278
+ setUpdatedSmsEditor(arr);
279
+ };
280
+
281
+ const textAreaValue = (idValue) => {
282
+ if (idValue && updatedSmsEditor) {
283
+ if (
284
+ updatedSmsEditor[idValue] &&
285
+ updatedSmsEditor[idValue] !== SMS_TRAI_VAR
286
+ ) {
287
+ return updatedSmsEditor[idValue];
288
+ } else {
289
+ return '';
290
+ }
291
+ }
292
+ return '';
293
+ };
294
+
295
+ const capHeading = (index, varCount) => {
296
+ if ((index, varCount)) {
297
+ return (
298
+ <CapHeading
299
+ key={`label${index}`}
300
+ type="h6"
301
+ style={{ margin: `${CAP_SPACE_04} 0`, float: 'right' }}
302
+ >
303
+ {formatMessage(messages.textAreaCounts, {
304
+ varCounts: varCount,
305
+ var: SMS_TRAI_VAR,
306
+ charCounts: varCount * CHARLIMIT,
307
+ })}
308
+ </CapHeading>
309
+ );
310
+ }
311
+ };
312
+
313
+ const renderedContent = () => {
314
+ const renderArray = [];
315
+ if (tempMsgArray?.length !== 0) {
316
+ let varCount = 0;
317
+ tempMsgArray.map((elem, index) => {
318
+ let prevElem = '';
319
+ if (elem.includes(SMS_TRAI_VAR)) {
320
+ prevElem =
321
+ tempMsgArray[[index === 0 ? tempMsgArray.length - 1 : index - 1]];
322
+ varCount++;
323
+ totalVarCount++;
324
+ if (prevElem !== SMS_TRAI_VAR) {
325
+ renderArray.push(
326
+ <TextArea
327
+ id={index}
328
+ key={`${elem}${index}`}
329
+ placeholder={props.intl.formatMessage(
330
+ messages.inputplaceHolderText,
331
+ )}
332
+ autosize={{ minRows: 1, maxRows: 3 }}
333
+ onChange={textAreaValueChange}
334
+ value={textAreaValue(index)}
335
+ onFocus={setTextAreaId}
336
+ errorMessage={
337
+ isValidationError &&
338
+ updatedSmsEditor[index] === SMS_TRAI_VAR &&
339
+ formatMessage(messages.textAreaError)
340
+ }
341
+ />,
342
+ );
343
+ }
344
+ if (index === tempMsgArray.length - 1) {
345
+ renderArray.push(capHeading(index, varCount));
346
+ varCount = 0;
347
+ }
348
+ } else if (varCount > 0) {
349
+ renderArray.push(
350
+ capHeading(index, varCount),
351
+ <CapHeading
352
+ key={`${elem}${index}`}
353
+ style={{ margin: `${CAP_SPACE_16} 0` }}
354
+ >
355
+ {elem}
356
+ </CapHeading>,
357
+ );
358
+ varCount = 0;
359
+ } else {
360
+ renderArray.push(
361
+ <CapHeading
362
+ key={`${elem}${index}`}
363
+ style={{ margin: `${CAP_SPACE_16} 0` }}
364
+ >
365
+ {elem}
366
+ </CapHeading>,
367
+ );
368
+ }
369
+ });
370
+ }
371
+ return renderArray;
372
+ };
373
+
374
+ // to compute the length of the message
375
+ //30 characters is blocked per'{#var#}' and the remaining string length is added to it
376
+ const smsLengthForVar = () => {
377
+ const msgLenWithoutVar =
378
+ tempMsgArray?.filter((i) => i !== SMS_TRAI_VAR)?.join('').length || 0;
379
+ const totalMessageLength = msgLenWithoutVar + totalVarCount * CHARLIMIT;
380
+ return (
381
+ <CapHeading type="h5" style={{ marginTop: CAP_SPACE_04, float: 'right' }}>
382
+ {formatMessage(messages.totalCharacters, {
383
+ smsCount: Math.ceil(totalMessageLength / 160),
384
+ number: totalMessageLength,
385
+ })}
386
+ </CapHeading>
387
+ );
388
+ };
389
+
390
+ return (
391
+ <>
392
+ <CapSpin spinning={loading}>
393
+ <CapRow>
394
+ {templateDetails && !isEmpty(templateDetails) && (
395
+ <TraiEditTemplateDetails>
396
+ <CapLabelInline type="label1">
397
+ {formatMessage(messages.templateLabel)}
398
+ </CapLabelInline>
399
+ <CapLabelInline type="label2">
400
+ {templateDetails.versions.base.template_name}
401
+ </CapLabelInline>
402
+ <CapLabelInline type="label1">
403
+ {formatMessage(messages.traiEditSeperator)}
404
+ </CapLabelInline>
405
+ <CapLabelInline type="label1">
406
+ {formatMessage(messages.senderIdlabel)}
407
+ </CapLabelInline>
408
+ <CapLabelInline type="label2">
409
+ {templateDetails.versions.base.header}
410
+ </CapLabelInline>
411
+ </TraiEditTemplateDetails>
412
+ )}
413
+ <CapColumn span={14}>
414
+ <CapRow>
415
+ <CapHeader
416
+ title={formatMessage(messages.traiEditTitle)}
417
+ size="regular"
418
+ suffix={
419
+ <TagList
420
+ label={formatMessage(messages.addLabels)}
421
+ onTagSelect={onTagSelect}
422
+ location={location}
423
+ tags={tags || []}
424
+ onContextChange={handleOnTagsContextChange}
425
+ injectedTags={injectedTags || {}}
426
+ />
427
+ }
428
+ />
429
+ </CapRow>
430
+
431
+ <CapRow
432
+ style={{
433
+ backgroundColor: CAP_G10,
434
+ padding: CAP_SPACE_16,
435
+ }}
436
+ >
437
+ {renderedContent()}
438
+ </CapRow>
439
+ <CapRow>{smsLengthForVar()}</CapRow>
440
+ <div style={{ marginBottom: '100px' }} />
441
+ </CapColumn>
442
+ <CapColumn span={10}>
443
+ <TemplatePreview
444
+ channel={SMS}
445
+ content={[updatedSmsEditor.join('')]}
446
+ />
447
+ </CapColumn>
448
+ </CapRow>
449
+ <SMSTraiFooter>
450
+ <CapButton onClick={onDoneCallback} className="create-msg">
451
+ <FormattedMessage {...messages.saveButtonLabel} />
452
+ </CapButton>
453
+ <CapButton
454
+ onClick={handleClose}
455
+ className="cancel-msg"
456
+ type="secondary"
457
+ >
458
+ <FormattedMessage {...messages.cancelButtonLabel} />
459
+ </CapButton>
460
+ </SMSTraiFooter>
461
+ </CapSpin>
462
+ </>
463
+ );
464
+ };
465
+
466
+ const mapStateToProps = createStructuredSelector({
467
+ templateDetails: makeSelectTemplateDetailsResponse(),
468
+ metaEntities: makeSelectMetaEntities(),
469
+ injectedTags: setInjectedTags(),
470
+ });
471
+
472
+ const mapDispatchToProps = (dispatch) => {
473
+ return {
474
+ actions: bindActionCreators(actions, dispatch),
475
+ };
476
+ };
477
+
478
+ export default withCreatives({
479
+ WrappedComponent: injectIntl(SmsTraiEdit),
480
+ mapStateToProps,
481
+ mapDispatchToProps,
482
+ userAuth: true,
483
+ });
@@ -0,0 +1,58 @@
1
+ /*
2
+ * SmsTrai Messages
3
+ *
4
+ * This contains all the text for the SmsTrai component.
5
+ */
6
+ import { defineMessages } from 'react-intl';
7
+ const prefix = 'app.v2containers.SmsTrai.Edit';
8
+
9
+ export default defineMessages({
10
+ saveButtonLabel: {
11
+ id: `${prefix}.saveButtonLabel`,
12
+ defaultMessage: 'Save',
13
+ },
14
+ cancelButtonLabel: {
15
+ id: `${prefix}.cancelButtonLabel`,
16
+ defaultMessage: 'Cancel',
17
+ },
18
+ traiEditTitle: {
19
+ id: `${prefix}.traiEditTitle`,
20
+ defaultMessage: 'Message',
21
+ },
22
+ addLabels: {
23
+ id: `${prefix}.addLabels`,
24
+ defaultMessage: 'Add labels',
25
+ },
26
+ inputplaceHolderText: {
27
+ id: `${prefix}.inputplaceHolderText`,
28
+ defaultMessage: 'Add labels or text or combination of both',
29
+ },
30
+ textAreaCounts: {
31
+ id: `${prefix}.textAreaCounts`,
32
+ defaultMessage: '{varCounts} Variables {var}: max. {charCounts} characters',
33
+ },
34
+ totalCharacters: {
35
+ id: `${prefix}.totalCharacters`,
36
+ defaultMessage: '{smsCount} SMS ({number} characters)',
37
+ },
38
+ smsEditNotification: {
39
+ id: `${prefix}.smsEditNotification`,
40
+ defaultMessage: 'Trai SMS template updated successfully',
41
+ },
42
+ textAreaError: {
43
+ id: `${prefix}.textAreaError`,
44
+ defaultMessage: 'Template cannot be empty',
45
+ },
46
+ templateLabel: {
47
+ id: `${prefix}.templateLabel`,
48
+ defaultMessage: 'Template',
49
+ },
50
+ traiEditSeperator: {
51
+ id: `${prefix}.traiEditSeperator`,
52
+ defaultMessage: '|',
53
+ },
54
+ senderIdlabel: {
55
+ id: `${prefix}.senderIdlabel`,
56
+ defaultMessage: 'Sender ID',
57
+ },
58
+ });