@capillarytech/creatives-library 8.0.98 → 8.0.100

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": "8.0.98",
4
+ "version": "8.0.100",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -1 +1,9 @@
1
1
  export const OUTBOUND = 'OUTBOUND';
2
+ export const GLOBAL_CONVERT_OPTIONS = {
3
+ selectors: [
4
+ ...[1, 2, 3, 4, 5, 6].map(level => ({
5
+ selector: `h${level}`,
6
+ options: { uppercase: false }
7
+ }))
8
+ ]
9
+ };
@@ -52,7 +52,7 @@ 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 { OUTBOUND } from './constants';
55
+ import { GLOBAL_CONVERT_OPTIONS, 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';
@@ -1092,7 +1092,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1092
1092
  const templateContent = this.state.formData?.base?.en?.["template-content"] || "";
1093
1093
  //Converts given HTML content to plain text string.
1094
1094
  const content = convert(
1095
- templateContent
1095
+ templateContent, GLOBAL_CONVERT_OPTIONS
1096
1096
  );
1097
1097
  /*
1098
1098
  The `handleResult` function is used as a callback for `getLiquidTags` to handle the results post-processing.
@@ -0,0 +1,152 @@
1
+ import {
2
+ SMS,
3
+ MOBILE_PUSH,
4
+ EMAIL
5
+ } from "../../v2Containers/CreativesContainer/constants";
6
+
7
+ /**
8
+ * Transform form data to API payload format
9
+ * @param {object} formData - The form data from the UI
10
+ * @param {string} channel - The communication channel (EMAIL, SMS, WECHAT, MOBILE_PUSH)
11
+ * @param {object} params - Additional parameters like sourceEntityId, ouId, etc.
12
+ * @returns {object} - The formatted API payload
13
+ */
14
+ export const transformFormDataToAPIPayload = (
15
+ formData,
16
+ loyaltyMetaData = {}
17
+ ) => {
18
+ console.log("**** # transformDataToAPIPyaload: ", {
19
+ formData,
20
+ loyaltyMetaData
21
+ });
22
+ const {
23
+ actionId,
24
+ actionName,
25
+ ouId,
26
+ clientName,
27
+ module,
28
+ metaId,
29
+ setMetaId = () => {},
30
+ channel,
31
+ transformedMessageDetails
32
+ } = loyaltyMetaData;
33
+
34
+ const { emailDeliverySettings } = transformedMessageDetails;
35
+ const upperCaseChannel = channel.toUpperCase();
36
+
37
+ // Base response structure
38
+ const response = {
39
+ ouId: ouId || -1,
40
+ sourceEntityId: actionId,
41
+ channel: upperCaseChannel || this.props.schema.channel.toUpperCase(),
42
+ module,
43
+ executionParams: {},
44
+ clientName: clientName || "EMF"
45
+ };
46
+
47
+ switch (upperCaseChannel) {
48
+ case EMAIL: {
49
+ const subject = formData["template-subject"] || "";
50
+ const htmlContent = formData?.base?.en?.["template-content"] || "";
51
+
52
+ return {
53
+ ...response,
54
+ emailDeliverySettings: emailDeliverySettings || {},
55
+ emailMessageContent: {
56
+ channel: EMAIL,
57
+ messageBody: htmlContent,
58
+ messageSubject: subject
59
+ }
60
+ };
61
+ }
62
+
63
+ case SMS: {
64
+ // Extract SMS content from formData
65
+ const smsContent = formData["sms-editor"] || "";
66
+ const templateId = formData.template_id || "";
67
+ const templateName = formData.template_name || "";
68
+ const header = formData.header || "";
69
+ const varMapped = formData["var-mapped"] || {};
70
+
71
+ return {
72
+ ...response,
73
+ smsDeliverySettings: {
74
+ additionalSettings: {
75
+ skipRateLimit: false
76
+ },
77
+ channelSettings: {
78
+ channel: SMS,
79
+ senderId: header || ""
80
+ }
81
+ },
82
+ smsMessageContent: {
83
+ channel: SMS,
84
+ messageBody: smsContent,
85
+ templateId,
86
+ templateName,
87
+ varMapped
88
+ }
89
+ };
90
+ }
91
+
92
+ case MOBILE_PUSH: {
93
+ // Extract Mobile Push content
94
+ const androidContent = formData.ANDROID || {};
95
+ const iosContent = formData.IOS || {};
96
+
97
+ return {
98
+ ...response,
99
+ mobilePushDeliverySettings: {
100
+ additionalSettings: {
101
+ skipRateLimit: false
102
+ },
103
+ channelSettings: {
104
+ channel: MOBILE_PUSH
105
+ }
106
+ },
107
+ mobilePushMessageContent: {
108
+ channel: MOBILE_PUSH,
109
+ androidContent: {
110
+ title: androidContent.title || "",
111
+ body: androidContent.message || "",
112
+ type: androidContent.type || "TEXT",
113
+ custom: androidContent.custom || {}
114
+ },
115
+ iosContent: {
116
+ title: iosContent.title || "",
117
+ body: iosContent.message || "",
118
+ type: iosContent.type || "TEXT",
119
+ custom: iosContent.custom || {}
120
+ }
121
+ }
122
+ };
123
+ }
124
+
125
+ // case WECHAT: {
126
+ // // Extract WeChat content
127
+ // const wechatContent = formData.content || {};
128
+
129
+ // return {
130
+ // ...response,
131
+ // wechatDeliverySettings: {
132
+ // additionalSettings: {
133
+ // skipRateLimit: false
134
+ // },
135
+ // channelSettings: {
136
+ // channel: WECHAT
137
+ // }
138
+ // },
139
+ // wechatMessageContent: {
140
+ // channel: WECHAT,
141
+ // messageBody: wechatContent.body || "",
142
+ // templateId: wechatContent.templateId || "",
143
+ // templateName: wechatContent.templateName || "",
144
+ // varMapped: wechatContent.varMapped || {}
145
+ // }
146
+ // };
147
+ // }
148
+
149
+ default:
150
+ return response;
151
+ }
152
+ };
@@ -405,10 +405,16 @@ export const Whatsapp = (props) => {
405
405
  videoSrc: carousel?.videoUrl,
406
406
  videoPreviewImg: carousel?.videoPreviewImg,
407
407
  }),
408
+ karixFileHandle: carousel?.karixFileHandle || '',
408
409
  buttons: carousel?.buttons?.map((button) => ({
409
410
  ...button,
410
411
  buttonType: button?.type,
411
412
  })),
413
+ assetList: {
414
+ previewUrl: carousel?.videoPreviewImg,
415
+ videoSrc: carousel?.videoUrl,
416
+ fileHandle: carousel?.karixFileHandle,
417
+ }
412
418
  };
413
419
  })
414
420
  );
@@ -1130,7 +1136,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
1130
1136
  videoSize={WHATSAPP_VIDEO_SIZE}
1131
1137
  isFullMode={isFullMode}
1132
1138
  uploadAsset={uploadWhatsappAsset}
1133
- uploadedAssetList={carouselData?.[activeIndex]?.assetList || []}
1139
+ uploadedAssetList={isMediaTypeCarousel ? carouselData?.[activeIndex]?.assetList : assetList}
1134
1140
  onVideoUploadUpdateAssestList={setUpdateWhatsappVideoSrc}
1135
1141
  videoData={editData}
1136
1142
  className="cap-custom-video-upload"
@@ -11,6 +11,7 @@ import {
11
11
  } from '../utils';
12
12
  import mockdata from '../../mockdata';
13
13
  import { HOST_ICS, PHONE_NUMBER, QUICK_REPLY } from '../constants';
14
+ import { WHATSAPP_MEDIA_TYPES } from '../../Whatsapp/constants';
14
15
 
15
16
  const {
16
17
  whatsappPreviewTemplateData,
@@ -179,4 +180,101 @@ describe('Test utils', () => {
179
180
  expect(result[3].props.children[0].props.type).toBe('call');
180
181
  });
181
182
  });
183
+
184
+ describe('carousel functionality', () => {
185
+ const mockTemplate = {
186
+ versions: {
187
+ base: {
188
+ content: {
189
+ whatsapp: {
190
+ languages: [{ content: 'Test message' }],
191
+ carouselData: [
192
+ {
193
+ mediaType: 'image',
194
+ imageUrl: 'https://example.com/image.jpg',
195
+ },
196
+ {
197
+ mediaType: 'video',
198
+ videoUrl: 'https://example.com/video.mp4',
199
+ videoPreviewImg: 'https://example.com/preview.jpg',
200
+ },
201
+ ],
202
+ },
203
+ },
204
+ },
205
+ },
206
+ };
207
+
208
+ it('should return original carousel data when isPreview is false', () => {
209
+ const result = getWhatsappContent(mockTemplate, false);
210
+ expect(result.carouselData).toEqual([
211
+ {
212
+ mediaType: 'image',
213
+ imageUrl: 'https://example.com/image.jpg',
214
+ },
215
+ {
216
+ mediaType: 'video',
217
+ videoUrl: 'https://example.com/video.mp4',
218
+ videoPreviewImg: 'https://example.com/preview.jpg',
219
+ },
220
+ ]);
221
+ expect(result.carouselMediaType).toBeUndefined();
222
+ });
223
+
224
+ it('should transform carousel data correctly when isPreview is true', () => {
225
+ const result = getWhatsappContent(mockTemplate, true);
226
+
227
+ expect(result.carouselData).toEqual([
228
+ {
229
+ mediaType: 'image',
230
+ imageUrl: 'https://example.com/image.jpg',
231
+ imageSrc: 'https://example.com/image.jpg',
232
+ },
233
+ {
234
+ mediaType: 'video',
235
+ videoUrl: 'https://example.com/video.mp4',
236
+ videoPreviewImg: 'https://example.com/preview.jpg',
237
+ videoSrc: 'https://example.com/video.mp4',
238
+ },
239
+ ]);
240
+ expect(result.carouselMediaType).toBe('image');
241
+ });
242
+
243
+ it('should handle empty carousel data', () => {
244
+ const emptyTemplate = {
245
+ versions: {
246
+ base: {
247
+ content: {
248
+ whatsapp: {
249
+ languages: [{ content: 'Test message' }],
250
+ carouselData: [],
251
+ },
252
+ },
253
+ },
254
+ },
255
+ };
256
+
257
+ const result = getWhatsappContent(emptyTemplate, true);
258
+ expect(result.carouselData).toEqual([]);
259
+ expect(result.carouselMediaType).toBeUndefined();
260
+ });
261
+
262
+ it('should handle undefined carousel data', () => {
263
+ const undefinedTemplate = {
264
+ versions: {
265
+ base: {
266
+ content: {
267
+ whatsapp: {
268
+ languages: [{ content: 'Test message' }],
269
+ },
270
+ },
271
+ },
272
+ },
273
+ };
274
+
275
+ const result = getWhatsappContent(undefinedTemplate, true);
276
+ expect(result.carouselData).toEqual([]);
277
+ expect(result.carouselMediaType).toBeUndefined();
278
+ });
279
+ });
182
280
  });
@@ -114,6 +114,22 @@ export const getWhatsappContent = (template, isPreview) => {
114
114
  break;
115
115
  }
116
116
 
117
+ const getCarouselData = () => {
118
+ if (isPreview && carouselData?.length) {
119
+ return carouselData.map((carousel) => {
120
+ if (carousel?.mediaType === WHATSAPP_MEDIA_TYPES.IMAGE.toLowerCase()) {
121
+ carousel.imageSrc = carousel?.imageUrl;
122
+ }
123
+ if (carousel?.mediaType === WHATSAPP_MEDIA_TYPES.VIDEO.toLowerCase()) {
124
+ carousel.videoSrc = carousel?.videoUrl;
125
+ carousel.videoPreviewImg = carousel?.videoPreviewImg;
126
+ }
127
+ return carousel;
128
+ });
129
+ }
130
+ return carouselData;
131
+ };
132
+
117
133
  return {
118
134
  templateHeaderPreview: header ? <CapLabel className="whatsapp-template-list-header-preview">{header}</CapLabel> : '',
119
135
  templateFooterPreview: footer ? <CapLabel className="whatsapp-template-list-footer-preview">{footer}</CapLabel> : '',
@@ -126,7 +142,10 @@ export const getWhatsappContent = (template, isPreview) => {
126
142
  quickReplyData: buttonsData
127
143
  }),
128
144
  ...mediaParams,
129
- carouselData,
145
+ carouselData: getCarouselData(),
146
+ ...(isPreview && carouselData?.length && {
147
+ carouselMediaType: carouselData[0]?.mediaType,
148
+ }),
130
149
  };
131
150
  };
132
151