@capillarytech/creatives-library 8.0.283 → 8.0.284

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.283",
4
+ "version": "8.0.284",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -55,19 +55,26 @@ export const CapWhatsappCarouselButton = (props) => {
55
55
  const invalidVarRegex = /{{(.*?)}}/g;
56
56
 
57
57
  const handleButtonType = ({ target: { value } }, buttonIndex) => {
58
- const cloneCarouselData = cloneDeep(carouselData);
59
58
  const dataMap = {
60
59
  [PHONE_NUMBER]: INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
61
60
  [URL]: INITIAL_CAROUSEL_URL_DATA,
62
61
  [QUICK_REPLY]: INITIAL_CAROUSEL_QUICK_REPLY_DATA,
63
62
  };
63
+ const initialData = dataMap[value];
64
+ const newButtonData = initialData ? cloneDeep(initialData) : {};
64
65
 
65
- const updatedCarouselData = cloneCarouselData.map((carousel) => {
66
- carousel.buttons[buttonIndex] = dataMap[value] || {};
67
- return carousel;
68
- });
69
-
70
- setCarouselData(updatedCarouselData);
66
+ setCarouselData(
67
+ carouselData.map((item, index) =>
68
+ index === carouselIndex
69
+ ? {
70
+ ...item,
71
+ buttons: item.buttons.map((btn, i) =>
72
+ i === buttonIndex ? newButtonData : btn
73
+ ),
74
+ }
75
+ : item
76
+ )
77
+ );
71
78
  };
72
79
 
73
80
  const onValueChange = (buttonIndex, fields = []) => {
@@ -148,17 +155,28 @@ export const CapWhatsappCarouselButton = (props) => {
148
155
  };
149
156
 
150
157
  const handleDeleteButton = (buttonIndex) => {
151
- setCarouselData((prevData) => prevData.map((carousel) => ({
152
- ...carousel,
153
- buttons: carousel.buttons.filter((_, index) => index !== buttonIndex),
154
- })));
158
+ setCarouselData((prevData) =>
159
+ prevData.map((carousel, index) =>
160
+ index === carouselIndex
161
+ ? {
162
+ ...carousel,
163
+ buttons: carousel.buttons.filter((_, i) => i !== buttonIndex),
164
+ }
165
+ : carousel
166
+ )
167
+ );
155
168
  };
156
169
 
157
170
  const addCarouselButton = () => {
158
171
  setCarouselData(
159
- carouselData.map((item, index) => index === carouselIndex
160
- ? { ...item, buttons: [...buttonData, INITIAL_CAROUSEL_PHONE_NUMBER_DATA] }
161
- : item)
172
+ carouselData.map((item, index) =>
173
+ index === carouselIndex
174
+ ? {
175
+ ...item,
176
+ buttons: [...buttonData, cloneDeep(INITIAL_CAROUSEL_PHONE_NUMBER_DATA)],
177
+ }
178
+ : item
179
+ )
162
180
  );
163
181
  };
164
182
 
@@ -3,9 +3,10 @@ import { injectIntl } from 'react-intl';
3
3
  import '@testing-library/jest-dom';
4
4
  import { render, screen, fireEvent } from '../../../utils/test-utils';
5
5
  import { CapWhatsappCarouselButton } from '../index';
6
- import {
6
+ import {
7
7
  INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
8
- INITIAL_CAROUSEL_URL_DATA
8
+ INITIAL_CAROUSEL_URL_DATA,
9
+ URL,
9
10
  } from '../constant';
10
11
  import { HOST_TWILIO } from "../../../v2Containers/Whatsapp/constants";
11
12
 
@@ -234,4 +235,121 @@ describe('CapWhatsappCarouselButton', () => {
234
235
  })
235
236
  ]));
236
237
  });
238
+
239
+ describe('carousel-scoped updates (only current card is updated)', () => {
240
+ it('handleButtonType only updates the carousel at carouselIndex', () => {
241
+ const card0 = {
242
+ bodyText: '',
243
+ buttons: [{ ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA, text: 'Card 0' }],
244
+ };
245
+ const card1 = {
246
+ bodyText: '',
247
+ buttons: [{ ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA, text: 'Card 1' }],
248
+ };
249
+ const carouselData = [card0, card1];
250
+
251
+ initializeComponent(carouselData, false, HOST_TWILIO, 0);
252
+
253
+ const radios = screen.getAllByRole('radio');
254
+ const urlRadio = radios.find((r) => r.value === URL) || radios[1];
255
+ if (urlRadio) fireEvent.click(urlRadio);
256
+
257
+ expect(setCarouselData).toHaveBeenCalledWith(expect.any(Array));
258
+ const updated = setCarouselData.mock.calls[0][0];
259
+ expect(updated).toHaveLength(2);
260
+ expect(updated[0].buttons[0]).toMatchObject(INITIAL_CAROUSEL_URL_DATA);
261
+ expect(updated[1]).toEqual(card1);
262
+ });
263
+
264
+ it('handleDeleteButton only removes button from the carousel at carouselIndex', () => {
265
+ const card0 = {
266
+ bodyText: '',
267
+ buttons: [
268
+ { ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA, text: 'A', isSaved: true },
269
+ { ...INITIAL_CAROUSEL_URL_DATA, text: 'B', isSaved: true },
270
+ ],
271
+ };
272
+ const card1 = {
273
+ bodyText: '',
274
+ buttons: [
275
+ { ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA, text: 'C', isSaved: true },
276
+ { ...INITIAL_CAROUSEL_URL_DATA, text: 'D', isSaved: true },
277
+ ],
278
+ };
279
+ const carouselData = [card0, card1];
280
+
281
+ const { container } = initializeComponent(carouselData, false, HOST_TWILIO, 0);
282
+
283
+ const deleteIconBtns = container.querySelectorAll('.whatsapp-carousel-delete-icon-btn');
284
+ expect(deleteIconBtns.length).toBeGreaterThanOrEqual(2);
285
+ fireEvent.click(deleteIconBtns[1]);
286
+
287
+ expect(setCarouselData).toHaveBeenCalledTimes(1);
288
+ const setter = setCarouselData.mock.calls[0][0];
289
+ expect(typeof setter).toBe('function');
290
+ const result = setter(carouselData);
291
+ expect(result[0].buttons).toHaveLength(1);
292
+ expect(result[0].buttons[0].text).toBe('A');
293
+ expect(result[1].buttons).toHaveLength(2);
294
+ expect(result[1].buttons[0].text).toBe('C');
295
+ expect(result[1].buttons[1].text).toBe('D');
296
+ });
297
+
298
+ it('addCarouselButton only adds button to the carousel at carouselIndex', () => {
299
+ const card0 = {
300
+ bodyText: '',
301
+ buttons: [{
302
+ ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
303
+ text: 'Call us',
304
+ phone_number: '9112345678',
305
+ isSaved: true,
306
+ }],
307
+ };
308
+ const card1 = {
309
+ bodyText: '',
310
+ buttons: [{ ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA, text: 'Other' }],
311
+ };
312
+ const carouselData = [card0, card1];
313
+
314
+ initializeComponent(carouselData, false, HOST_TWILIO, 0);
315
+
316
+ const addButton = screen.getByRole('button', { name: /add button/i });
317
+ fireEvent.click(addButton);
318
+
319
+ expect(setCarouselData).toHaveBeenCalledWith(expect.any(Array));
320
+ const updated = setCarouselData.mock.calls[0][0];
321
+ expect(updated).toHaveLength(2);
322
+ expect(updated[0].buttons).toHaveLength(2);
323
+ expect(updated[0].buttons[0].text).toBe('Call us');
324
+ expect(updated[0].buttons[1]).toMatchObject(INITIAL_CAROUSEL_PHONE_NUMBER_DATA);
325
+ expect(updated[0].buttons[1]).not.toBe(INITIAL_CAROUSEL_PHONE_NUMBER_DATA);
326
+ expect(updated[1]).toEqual(card1);
327
+ });
328
+
329
+ it('addCarouselButton adds a new button object (clone) so state is not shared', () => {
330
+ const carouselData = [{
331
+ bodyText: '',
332
+ buttons: [{
333
+ ...INITIAL_CAROUSEL_PHONE_NUMBER_DATA,
334
+ text: 'Saved',
335
+ isSaved: true,
336
+ }],
337
+ }];
338
+
339
+ initializeComponent(carouselData, false, HOST_TWILIO, 0);
340
+
341
+ const addButton = screen.getByRole('button', { name: /add button/i });
342
+ fireEvent.click(addButton);
343
+
344
+ const updated = setCarouselData.mock.calls[0][0];
345
+ const addedButton = updated[0].buttons[1];
346
+ expect(addedButton).toMatchObject({
347
+ buttonType: 'PHONE_NUMBER',
348
+ text: '',
349
+ phone_number: '',
350
+ isSaved: false,
351
+ });
352
+ expect(addedButton).not.toBe(INITIAL_CAROUSEL_PHONE_NUMBER_DATA);
353
+ });
354
+ });
237
355
  });
@@ -2055,11 +2055,11 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2055
2055
  const buttonArray = firstCarouselButtonData.map((button) => {
2056
2056
  switch (button?.buttonType) {
2057
2057
  case PHONE_NUMBER:
2058
- return INITIAL_CAROUSEL_PHONE_NUMBER_DATA;
2058
+ return cloneDeep(INITIAL_CAROUSEL_PHONE_NUMBER_DATA);
2059
2059
  case QUICK_REPLY:
2060
- return INITIAL_CAROUSEL_QUICK_REPLY_DATA;
2060
+ return cloneDeep(INITIAL_CAROUSEL_QUICK_REPLY_DATA);
2061
2061
  default:
2062
- return INITIAL_CAROUSEL_URL_DATA;
2062
+ return cloneDeep(INITIAL_CAROUSEL_URL_DATA);
2063
2063
  }
2064
2064
  });
2065
2065
  const newCard = cloneDeep(CAROUSEL_INITIAL_DATA[0]);