@capillarytech/creatives-library 7.13.7 → 7.13.9

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.13.7",
4
+ "version": "7.13.9",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -2,8 +2,11 @@ import cloneDeep from "lodash/cloneDeep";
2
2
  import isEmpty from "lodash/isEmpty";
3
3
  import forOwn from "lodash/forOwn";
4
4
  import isNumber from "lodash/isNumber";
5
+ import Bugsnag from '@bugsnag/js';
6
+
5
7
  /* eslint-disable no-unused-expressions */
6
8
  import { parse } from "node-html-parser";
9
+ import { EMAIL } from '../v2Containers/CreativesContainer/constants';
7
10
 
8
11
  // example cdn url
9
12
  // https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=100,height=100,quality=75,format=auto/intouch_creative_assets/005710a7-6412-44fe-a19f-e72456b1.jpg
@@ -12,8 +15,6 @@ import { parse } from "node-html-parser";
12
15
  * regex tests presence of intouch_creative_assets in the url.
13
16
  * We are not testing for extensions such as jpg/png because some channels like LINE - IMAGEMAP url doesn't contain extension.
14
17
  */
15
- const regex = /https:\/\/.*intouch_creative_assets.*$/;
16
- const INTOUCH_CREATIVE_ASSETS = "intouch_creative_assets";
17
18
  const SPECIFIED = "specified";
18
19
  const FORMAT_TYPES = { AUTO: "auto" };
19
20
  const QUALITY_TYPE = {
@@ -21,9 +22,13 @@ const QUALITY_TYPE = {
21
22
  PRESERVE: "preserve",
22
23
  };
23
24
  const CREATIVES_CDN_BASE_URL_KEY = 'CREATIVES_CDN_BASE_URL';
25
+ const CREATIVES_S3_BUCKET_PATH_KEY = 'CREATIVES_S3_BUCKET_PATH';
24
26
  const CREATIVES_CDN_QUALITY_CONFIG_KEY = 'CREATIVES_CDN_QUALITY_CONFIG';
25
27
  const CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY = 'CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX';
26
28
 
29
+ const HTTPS_STR = "https://"
30
+ const ALLOWED_EXTENSIONS_STR = ".*(?:jpg|png|jpeg)$"
31
+ const ANY_STR = ".*"
27
32
 
28
33
  /**
29
34
  * CHANNEL_CONFIGS maintains the transformation details for each channel (and optionally subchannel ex. FACEBOOK/LINE)
@@ -141,21 +146,31 @@ export const getCdnUrl = ({
141
146
  const CREATIVES_CDN_BASE_URL = getLocalStorageItem(CREATIVES_CDN_BASE_URL_KEY);
142
147
  const CREATIVES_CDN_QUALITY_CONFIG = getLocalStorageItem(CREATIVES_CDN_QUALITY_CONFIG_KEY, true);
143
148
  const CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX = getLocalStorageItem(CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY);
144
-
149
+ let CREATIVES_S3_BUCKET_PATH = getLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
150
+
151
+ //remove all leading and trailing forward slash with empty string, if leading/trailing forward slash is present in node env by mistake then url will not be correct hence removing them.
152
+ CREATIVES_S3_BUCKET_PATH = CREATIVES_S3_BUCKET_PATH?.replace(/^\/|\/$/g, '');
153
+
145
154
  //Basic validations on data stored in local storage.
146
155
  if (
147
156
  typeof CREATIVES_CDN_QUALITY_CONFIG !== "object" ||
148
157
  Array.isArray(CREATIVES_CDN_QUALITY_CONFIG) ||
149
158
  CREATIVES_CDN_QUALITY_CONFIG === null ||
150
159
  typeof CREATIVES_CDN_BASE_URL !== "string" ||
151
- typeof CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX !== "string"
160
+ typeof CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX !== "string" ||
161
+ typeof CREATIVES_S3_BUCKET_PATH !== 'string'
152
162
  )
153
163
  return url;
154
164
 
155
165
  const QUALITY = CREATIVES_CDN_QUALITY_CONFIG?.[channelName] || CREATIVES_CDN_QUALITY_CONFIG?.DEFAULT;
156
166
 
167
+ const regexWithExtension = new RegExp(HTTPS_STR + ANY_STR + CREATIVES_S3_BUCKET_PATH + ANY_STR + ALLOWED_EXTENSIONS_STR)
168
+ const regexWithoutExtension = new RegExp(HTTPS_STR + ANY_STR + CREATIVES_S3_BUCKET_PATH + ANY_STR);
169
+
170
+ let skipTransformations = true;
171
+
157
172
  if (
158
- !regex.test(url) ||
173
+ !regexWithoutExtension.test(url) ||
159
174
  !CHANNEL_CONFIGS?.[channelName] ||
160
175
  (channelSubType && !CHANNEL_CONFIGS?.[channelName]?.[channelSubType]) ||
161
176
  !CREATIVES_CDN_BASE_URL ||
@@ -163,8 +178,13 @@ export const getCdnUrl = ({
163
178
  !QUALITY
164
179
  )
165
180
  return url;
166
-
167
- const [, assetKey] = url.split(INTOUCH_CREATIVE_ASSETS);
181
+
182
+ //Skip transformations if extensions are not proper. Else consider transformations if available.
183
+ if(regexWithExtension.test(url)){
184
+ skipTransformations = false;
185
+ }
186
+
187
+ const [, assetKey] = url.split(CREATIVES_S3_BUCKET_PATH);
168
188
 
169
189
  let newUrl = `${CREATIVES_CDN_BASE_URL}`;
170
190
 
@@ -177,7 +197,7 @@ export const getCdnUrl = ({
177
197
  applicableTransformations = CHANNEL_CONFIGS?.[channelName]?.transformations;
178
198
  }
179
199
 
180
- if (!isEmpty(applicableTransformations)) {
200
+ if (!isEmpty(applicableTransformations) && !skipTransformations) {
181
201
 
182
202
  newUrl += `/${CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX}/`;
183
203
 
@@ -215,15 +235,21 @@ export const getCdnUrl = ({
215
235
  break;
216
236
  }
217
237
  } catch (e) {
218
- console.log("some error occured while applying transformation",e);
238
+ Bugsnag.leaveBreadcrumb("some error occured while applying transformation")
239
+ Bugsnag.notify(e, (event) => {
240
+ event.severity = "error";
241
+ });
219
242
  }
220
243
  })
221
244
  }
222
- newUrl += `/${INTOUCH_CREATIVE_ASSETS}${assetKey}`;
245
+ newUrl += `/${CREATIVES_S3_BUCKET_PATH}${assetKey}`;
223
246
  return newUrl;
224
247
 
225
248
  }catch(e){
226
- console.log('Some exception occurred in getCdnUrl',e);
249
+ Bugsnag.leaveBreadcrumb("Some exception occurred in getCdnUrl");
250
+ Bugsnag.notify(e, (event) => {
251
+ event.severity = "error";
252
+ });
227
253
  return url;
228
254
  }
229
255
  };
@@ -234,27 +260,30 @@ export const getCdnUrl = ({
234
260
  * @returns htmlContents with updated urls in image tag
235
261
  */
236
262
  export const updateImagesInHtml = (htmlContents) => {
263
+ if(!htmlContents || typeof htmlContents !== "string"){
264
+ return htmlContents;
265
+ }
237
266
  const copiedHtmlContents = htmlContents;
238
267
  try {
239
268
  const root = parse(htmlContents);
240
- root.querySelectorAll("img").forEach((element) => {
269
+ root?.querySelectorAll("img")?.forEach((element) => {
241
270
  const imageSrc = element.getAttribute("src");
242
- const isAsset = regex.test(imageSrc);
243
- if (isAsset) {
244
- const height = element.getAttribute("height");
245
- const width = element.getAttribute("width");
246
- const newUrl = getCdnUrl({
247
- url: imageSrc,
248
- height,
249
- width,
250
- channelName: "EMAIL",
251
- });
252
- element.setAttribute("src", newUrl);
253
- }
271
+ const height = element.getAttribute("height");
272
+ const width = element.getAttribute("width");
273
+ const newUrl = getCdnUrl({
274
+ url: imageSrc,
275
+ height,
276
+ width,
277
+ channelName: EMAIL,
278
+ });
279
+ element.setAttribute("src", newUrl);
254
280
  });
255
281
  return root.toString();
256
282
  } catch (e) {
257
- console.log("An error occured while updating images in html", e);
283
+ Bugsnag.leaveBreadcrumb("An error occured while updating images in html")
284
+ Bugsnag.notify(e, (event) => {
285
+ event.severity = "error";
286
+ });
258
287
  return copiedHtmlContents; //return received input directly in case an exception is thrown
259
288
  }
260
289
  };
@@ -277,7 +306,12 @@ export const transformEmailTemplates = (contents) => {
277
306
  });
278
307
  return contentsCopy;
279
308
  } catch (e) {
280
- console.log("Some error has occured while transforming email templates", e);
309
+ Bugsnag.leaveBreadcrumb(
310
+ "Some error has occured while transforming email templates"
311
+ );
312
+ Bugsnag.notify(e, (event) => {
313
+ event.severity = "error";
314
+ });
281
315
  return contents; //return received input directly in case an exception is thrown
282
316
  }
283
317
  };
@@ -313,8 +347,12 @@ export function removeAllCdnLocalStorageItems() {
313
347
  removeLocalStorageItem(CREATIVES_CDN_BASE_URL_KEY);
314
348
  removeLocalStorageItem(CREATIVES_CDN_QUALITY_CONFIG_KEY);
315
349
  removeLocalStorageItem(CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY);
350
+ removeLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
316
351
  }catch(e){
317
- console.log('some error occured while deleting all keys for cdn', e);
352
+ Bugsnag.leaveBreadcrumb("some error occured while deleting all keys for cdn");
353
+ Bugsnag.notify(e, (event) => {
354
+ event.severity = "error";
355
+ });
318
356
  }
319
357
  }
320
358
 
@@ -348,6 +386,15 @@ export function saveCdnConfigs(configsResponse) {
348
386
  removeLocalStorageItem(CREATIVES_CDN_BASE_URL_KEY);
349
387
  }
350
388
 
389
+ if (configsResponse?.bucketPath) {
390
+ localStorage.setItem(
391
+ CREATIVES_S3_BUCKET_PATH_KEY,
392
+ configsResponse?.bucketPath
393
+ );
394
+ } else {
395
+ removeLocalStorageItem(CREATIVES_S3_BUCKET_PATH_KEY);
396
+ }
397
+
351
398
  if (!isEmpty(configsResponse?.qualityCfg)) {
352
399
  const qualityString = JSON.stringify(configsResponse?.qualityCfg);
353
400
  localStorage.setItem(CREATIVES_CDN_QUALITY_CONFIG_KEY, qualityString);
@@ -364,6 +411,9 @@ export function saveCdnConfigs(configsResponse) {
364
411
  removeLocalStorageItem(CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX_KEY);
365
412
  }
366
413
  } catch (e) {
367
- console.log("some error while setting localstorage cdn configs");
414
+ Bugsnag.leaveBreadcrumb("some error while setting localstorage cdn configs");
415
+ Bugsnag.notify(e, (event) => {
416
+ event.severity = "error";
417
+ });
368
418
  }
369
419
  }
@@ -5,6 +5,7 @@ beforeEach(() => {
5
5
  var localStorageMock = (function () {
6
6
  var store = {
7
7
  CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX: "cdn-cgi/image",
8
+ CREATIVES_S3_BUCKET_PATH: "intouch_creative_assets",
8
9
  CREATIVES_CDN_BASE_URL: "https://storage.crm.n.content-cdn.io",
9
10
  CREATIVES_CDN_QUALITY_CONFIG:
10
11
  '{"EMAIL":75,"RCS":75,"VIBER":75,"WHATSAPP":75,"MOBILE_PUSH":75,"FACEBOOK":75,"LINE":75,"DEFAULT":75}',
@@ -32,6 +33,9 @@ afterEach(() => {
32
33
  "CREATIVES_CDN_QUALITY_CONFIG",
33
34
  '{"EMAIL":75,"RCS":75,"VIBER":75,"WHATSAPP":75,"MOBILE_PUSH":75,"FACEBOOK":75,"LINE":75,"DEFAULT":75}'
34
35
  );
36
+ localStorage.setItem(
37
+ "CREATIVES_S3_BUCKET_PATH", "intouch_creative_assets"
38
+ );
35
39
  });
36
40
 
37
41
  describe("cdnTransformationTests", () => {
@@ -83,6 +87,44 @@ describe("cdnTransformationTests", () => {
83
87
  expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
84
88
  });
85
89
 
90
+ it("Should replace s3 url with cdn url for email when bucket name is other than intouch_creatives_assets in case of prod.", () => {
91
+ localStorage.setItem("CREATIVES_S3_BUCKET_PATH", "fileservice.in/intouch_creative_assets");
92
+ const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
93
+ const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
94
+ url: TEST_S3_URL,
95
+ channelName: "EMAIL",
96
+ height: 100,
97
+ width: 200,
98
+ });
99
+ const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
100
+ expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
101
+ });
102
+
103
+ it("Should replace s3 url with cdn url for email when bucket name is other than intouch_creatives_assets in case of prod. It should remove leading/trailing forward slashes from bucket path", () => {
104
+ localStorage.setItem("CREATIVES_S3_BUCKET_PATH", "/fileservice.in/intouch_creative_assets/");
105
+ const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
106
+ const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
107
+ url: TEST_S3_URL,
108
+ channelName: "EMAIL",
109
+ height: 100,
110
+ width: 200,
111
+ });
112
+ const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/fileservice.in/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
113
+ expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
114
+ });
115
+
116
+ it("Should replace s3 url with cdn url for email without transformation for formats other than jpg/png/jpeg", () => {
117
+ const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.avif`; //this is random url
118
+ const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
119
+ url: TEST_S3_URL,
120
+ channelName: "EMAIL",
121
+ height: 100,
122
+ width: 200,
123
+ });
124
+ const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.avif`;
125
+ expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
126
+ });
127
+
86
128
  it("should replace cdn url with new cdn url for email incase h/w etc changed", () => {
87
129
  const TEST_S3_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=200,height=100,format=auto,quality=75,/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8.jpg`;
88
130
  const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
@@ -95,14 +137,14 @@ describe("cdnTransformationTests", () => {
95
137
  expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
96
138
  });
97
139
 
98
- it("should replace cdn url with new cdn url incase channelName is LINE and channelSubType is RICH_MESSAGE ", () => {
140
+ it("should replace cdn url with new cdn url incase channelName is LINE and channelSubType is RICH_MESSAGE without transformation", () => {
99
141
  const TEST_S3_URL = `https://crm-nightly-new-fileservice.s3.amazonaws.com/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8`;
100
142
  const GENERATED_CDN_URL = cdnUtils.getCdnUrl({
101
143
  url: TEST_S3_URL,
102
144
  channelName: "LINE",
103
145
  channelSubType: "RICH_MESSAGE",
104
146
  });
105
- const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/cdn-cgi/image/width=1040,quality=75,/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8`;
147
+ const EXPECTED_CDN_URL = `https://storage.crm.n.content-cdn.io/intouch_creative_assets/2c9233ed-0959-4aff-b749-9171b5c8`;
106
148
  expect(GENERATED_CDN_URL).toEqual(EXPECTED_CDN_URL);
107
149
  });
108
150
 
@@ -152,6 +194,12 @@ describe("cdnTransformationTests", () => {
152
194
  const expected = mockdata.emailRawTransformed;
153
195
  expect(htmlContentsOutput).toEqual(expected);
154
196
  });
197
+
198
+ it("should return input itself if input is either among undefined/null/empty string", () => {
199
+ expect(cdnUtils.updateImagesInHtml(undefined)).toEqual(undefined);
200
+ expect(cdnUtils.updateImagesInHtml(null)).toEqual(null);
201
+ expect(cdnUtils.updateImagesInHtml("")).toEqual("");
202
+ });
155
203
  });
156
204
 
157
205
  describe("transformEmailTemplate()", () => {
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
11
11
  import React from 'react';
12
12
  import _ from 'lodash';
13
13
  import { Tabs, Table, Modal} from 'antd';
14
- import { CapSpin, CapDrawer, CapButton, CapInput, CapPopover, CapImage, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon} from '@capillarytech/cap-ui-library';
14
+ import { CapSpin, CapDrawer, CapButton, CapInput, CapPopover, CapImage, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon, CapTooltip} from '@capillarytech/cap-ui-library';
15
15
  import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
16
16
  import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
17
17
  import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05, FONT_COLOR_04 } from '@capillarytech/cap-ui-library/styled/variables';
@@ -2800,22 +2800,28 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2800
2800
  break;
2801
2801
  case "checkbox":
2802
2802
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2803
+ const { disabled , hoverText } = val || {};
2803
2804
  if (styling === 'semantic') {
2804
2805
  columns.push(
2805
2806
  <CapColumn key="input" span={val.width} offset={val.offset}>
2806
- <CapCheckbox
2807
- key={val.id}
2808
- className={`${ifError ? 'error' : ''}`}
2809
- errorMessage={val.errorMessage && ifError ? val.errorMessage : ''}
2810
- onChange={(e) => this.updateFormData(e.target.checked, val, val.submitAction)}
2811
- checked={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2812
- defaultChecked={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2813
- style={val.style ? val.style : {}}
2814
- disabled={val.disabled}
2815
- inductiveText={val.inductiveText}
2807
+ <CapTooltip
2808
+ title={ disabled && hoverText ? hoverText : '' }
2809
+ placement="topLeft"
2816
2810
  >
2811
+ <CapCheckbox
2812
+ key={val.id}
2813
+ className={`${ifError ? 'error' : ''}`}
2814
+ errorMessage={val.errorMessage && ifError ? val.errorMessage : ''}
2815
+ onChange={(e) => this.updateFormData(e.target.checked, val, val.submitAction)}
2816
+ checked={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2817
+ defaultChecked={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2818
+ style={val.style ? val.style : {}}
2819
+ disabled={val.disabled}
2820
+ inductiveText={val.inductiveText}
2821
+ >
2817
2822
  {val.label}
2818
- </CapCheckbox>
2823
+ </CapCheckbox>
2824
+ </CapTooltip>
2819
2825
  </CapColumn>
2820
2826
  );
2821
2827
  }
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import { injectIntl } from 'react-intl';
3
+ import '@testing-library/jest-dom';
4
+ import FormBuilder from '../index';
5
+ import { Provider } from 'react-redux';
6
+ import configureStore from '../../../store';
7
+ import {
8
+ render,
9
+ screen,
10
+ fireEvent,
11
+ waitFor
12
+ } from '../../../utils/test-utils';
13
+ import { mockData } from './mockData';
14
+
15
+
16
+ const ComponentToRender = injectIntl(FormBuilder);
17
+ const renderComponent = props => {
18
+ const store = configureStore({}, null);
19
+ return render(
20
+ <Provider store={store}>
21
+ <ComponentToRender {...props} />
22
+ </Provider>,
23
+ );
24
+ };
25
+
26
+ describe("test for checkbox form builder",() => {
27
+ const onFormValidityChange=jest.fn();
28
+ const props={
29
+ ...mockData,
30
+ onFormValidityChange
31
+ }
32
+ renderComponent(props);
33
+ it("add action button to notification disabled in ios", async () => {
34
+ const addNotifBtn=screen.getByLabelText("Add action buttons to notification")
35
+ expect(addNotifBtn).toBeDisabled();
36
+ fireEvent.mouseOver(addNotifBtn);
37
+ await waitFor(() => {
38
+ expect(screen.getByText("This section is being revamped. Till then it will remain disabled.")).toBeInTheDocument();
39
+ })
40
+ })
41
+ })
@@ -0,0 +1,120 @@
1
+ export const mockData = {
2
+ schema:{
3
+ "containers": [
4
+ {
5
+ "id": "pane",
6
+ "supportedEvents": [
7
+ "onTabChange"
8
+ ],
9
+ "panes": [
10
+ {
11
+ "isSupported": true,
12
+ "sectionsHeaders": [
13
+ {
14
+ "type": "multicols",
15
+ "inputFields": [
16
+ {
17
+ "rowStyle": {
18
+ "display": "flex",
19
+ "flex": 1
20
+ },
21
+ "cols": [
22
+ {
23
+ "id": "tab-header",
24
+ "metaType": "label",
25
+ "value": "iOS",
26
+ "primitive": true,
27
+ "dynamicTab": false,
28
+ "type": "div",
29
+ "width": 5,
30
+ "offset": 0,
31
+ "onlyDisplay": true,
32
+ "colStyle": {
33
+ "flex": 1
34
+ },
35
+ "injectedEvents": {}
36
+ }
37
+ ]
38
+ }
39
+ ],
40
+ "actionFields": []
41
+ }
42
+ ],
43
+ "sections": [
44
+ {
45
+ "type": "parent",
46
+ "width": 16,
47
+ "rowStyle": {
48
+ "height": "100%"
49
+ },
50
+ "childSections": [
51
+ {
52
+ "colStyle": {
53
+ "paddingTop": "16px",
54
+ "paddingLeft": "16px",
55
+ "borderRight": "1px solid #d9d9d9",
56
+ "height": "70vh",
57
+ "overflowY": "auto"
58
+ },
59
+ "width": 16,
60
+ "type": "parent",
61
+ "childSections": [
62
+ {
63
+ "type": "multicols",
64
+ "inputFields": [
65
+ {
66
+ "identifier": "add-sec-cta-ios",
67
+ "cols": [
68
+ {
69
+ "id": "add-sec-cta-ios",
70
+ "metaType": "label",
71
+ "dynamicTab": false,
72
+ "label": "Add action buttons to notification",
73
+ "styling": "semantic",
74
+ "type": "checkbox",
75
+ "customComponent": false,
76
+ "datatype": "boolean",
77
+ "fluid": true,
78
+ "onlyDisplay": false,
79
+ "offset": 0,
80
+ "colStyle": {
81
+ "flex": 1
82
+ },
83
+ "submitAction": "addSecondaryCtaIos",
84
+ "supportedEvents": [
85
+ "addSecondaryCtaIos"
86
+ ],
87
+ "disabled": true,
88
+ "hoverText": "This section is being revamped. Till then it will remain disabled.",
89
+ "injectedEvents": {}
90
+ }
91
+ ]
92
+ }
93
+ ],
94
+ "actionFields": []
95
+ }
96
+ ]
97
+ },
98
+ ]
99
+ }
100
+ ]
101
+ }
102
+ ],
103
+ "type": "tabs",
104
+ "defaultPanes": 1,
105
+ "additionalPanes": 0,
106
+ "injectedEvents": {}
107
+ }
108
+ ],
109
+ "channel": "MOBILEPUSH",
110
+ "module": "Campaigns",
111
+ "type": "LAYOUT"
112
+ },
113
+ location:{
114
+ "pathname": "/mobilepush/create/image",
115
+ "query": {
116
+ "type": false,
117
+ "module": "default"
118
+ }
119
+ }
120
+ }
@@ -99,7 +99,7 @@ class NewCallTask extends React.Component { // eslint-disable-line react/prefer-
99
99
  };
100
100
 
101
101
  render() {
102
- const { intl, isLoading, metaEntities, selectedOfferDetails } = this.props;
102
+ const { intl, isLoading, metaEntities, selectedOfferDetails , injectedTags} = this.props;
103
103
  const { formatMessage } = intl;
104
104
  const { subject, messageBody, description, callTaskActionType } = this.state;
105
105
  const tags = metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
@@ -125,6 +125,7 @@ class NewCallTask extends React.Component { // eslint-disable-line react/prefer-
125
125
  tags={tags}
126
126
  onTagSelect={this.onTagSelect}
127
127
  selectedOfferDetails={selectedOfferDetails}
128
+ injectedTags={injectedTags}
128
129
  />
129
130
  <CapInput.TextArea
130
131
  setInputRef={this.setInputRef}
@@ -177,6 +178,7 @@ NewCallTask.propTypes = {
177
178
  selectedOfferDetails: PropTypes.array,
178
179
  messageDetails: PropTypes.object,
179
180
  mode: PropTypes.string,
181
+ injectedTags: PropTypes.object,
180
182
  };
181
183
 
182
184
  export default injectIntl(NewCallTask);
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import { injectIntl } from 'react-intl';
3
+ import '@testing-library/jest-dom';
4
+ import { Provider } from 'react-redux';
5
+ import { browserHistory } from 'react-router';
6
+ import NewCallTask from '../index';
7
+ import configureStore from '../../../store';
8
+ import mockData from './mockData'
9
+ import {
10
+ render,
11
+ } from '../../../utils/test-utils';
12
+ import { Router } from "express";
13
+ const ComponentToRender = injectIntl(NewCallTask);
14
+
15
+ const renderComponent = (props) => {
16
+ const store = configureStore({}, browserHistory);
17
+ return render(
18
+ <Router>
19
+ <Provider store={store}>
20
+ <ComponentToRender {...props} />
21
+ </Provider>
22
+ </Router>,
23
+ );
24
+ };
25
+
26
+ describe("test for NewCallTask", () => {
27
+ const onCallTaskSubmit = jest.fn();
28
+ const props = {
29
+ ...mockData,
30
+ onCallTaskSubmit,
31
+ };
32
+
33
+ it("New call task", async () => {
34
+ renderComponent(props);
35
+ });
36
+ });
@@ -0,0 +1,20 @@
1
+ const mockData= {
2
+ injectedTags: {},
3
+ templateData: {},
4
+ messageDetails: {},
5
+ isLoading: true,
6
+ selectedOfferDetails: [],
7
+ location: {
8
+ pathname: "/NewCallTask",
9
+ query: {
10
+ type: false,
11
+ module: "default",
12
+ },
13
+ },
14
+ match: {
15
+ path: '/NewCallTask',
16
+ url: '/creatives/ui/v2',
17
+ isExact: true,
18
+ params: {},
19
+ }
20
+ }
@@ -16,7 +16,7 @@ import {
16
16
  } from '@capillarytech/cap-ui-library';
17
17
  import { injectIntl, intlShape } from 'react-intl';
18
18
  import { createStructuredSelector } from 'reselect';
19
- import { makeSelectMetaEntities, isLoadingMetaEntities } from '../Cap/selectors';
19
+ import { makeSelectMetaEntities, isLoadingMetaEntities, setInjectedTags } from '../Cap/selectors';
20
20
  import * as globalActions from '../Cap/actions';
21
21
  import * as actions from "./actions";
22
22
  import makeSelectCallTask from './selectors';
@@ -71,7 +71,7 @@ export class CallTask extends React.Component { // eslint-disable-line react/pre
71
71
  };
72
72
  }
73
73
  render() {
74
- const { intl, onCallTaskSubmit, templateData, loadingMetaEntities, metaEntities, selectedOfferDetails, messageDetails } = this.props;
74
+ const { intl, onCallTaskSubmit, templateData, loadingMetaEntities, metaEntities, selectedOfferDetails, messageDetails, injectedTags } = this.props;
75
75
  const { formatMessage } = intl;
76
76
  const { mode } = this.state;
77
77
  return (
@@ -85,6 +85,7 @@ export class CallTask extends React.Component { // eslint-disable-line react/pre
85
85
  onCallTaskSubmit={onCallTaskSubmit}
86
86
  selectedOfferDetails={selectedOfferDetails}
87
87
  messageDetails={messageDetails}
88
+ injectedTags={injectedTags || {}}
88
89
  />
89
90
  :
90
91
  <div>
@@ -144,6 +145,7 @@ const mapStateToProps = createStructuredSelector({
144
145
  CallTask: makeSelectCallTask(),
145
146
  metaEntities: makeSelectMetaEntities(),
146
147
  loadingMetaEntities: isLoadingMetaEntities(),
148
+ injectedTags: setInjectedTags(),
147
149
  });
148
150
 
149
151
  function mapDispatchToProps(dispatch) {
@@ -782,6 +782,8 @@ export const response = {
782
782
  supportedEvents: [
783
783
  "addSecondaryCtaIos",
784
784
  ],
785
+ disabled: true,
786
+ hoverText: "This section is being revamped. Till then it will remain disabled.",
785
787
  },
786
788
  ],
787
789
  },
@@ -1690,6 +1692,8 @@ export const response = {
1690
1692
  supportedEvents: [
1691
1693
  "addSecondaryCtaIos",
1692
1694
  ],
1695
+ disabled: true,
1696
+ hoverText: "This section is being revamped. Till then it will remain disabled.",
1693
1697
  },
1694
1698
  ],
1695
1699
  },
@@ -93,6 +93,8 @@ function* getCdnTransformationConfig() {
93
93
  if (res?.success && res?.status?.code === 200) {
94
94
  const cdnConfigs = res?.response;
95
95
  saveCdnConfigs(cdnConfigs);
96
+ } else {
97
+ removeAllCdnLocalStorageItems();
96
98
  }
97
99
  } catch (error) {
98
100
  console.log("some error occured during getCdnTransformationConfig call");