@capillarytech/creatives-library 8.0.182 → 8.0.183
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 +1 -1
- package/v2Containers/Cap/reducer.js +0 -3
- package/v2Containers/Cap/sagas.js +0 -13
- package/v2Containers/Cap/selectors.js +1 -2
- package/v2Containers/Cap/tests/saga.test.js +53 -616
- package/v2Containers/Cap/tests/selectors.test.js +2 -440
- package/v2Containers/CreativesContainer/actions.js +1 -9
- package/v2Containers/CreativesContainer/constants.js +0 -1
- package/v2Containers/CreativesContainer/index.js +0 -7
- package/v2Containers/CreativesContainer/reducer.js +0 -6
- package/v2Containers/CreativesContainer/selectors.js +0 -5
- package/v2Containers/MobilePushNew/components/MediaUploaders.js +8 -19
- package/v2Containers/MobilePushNew/index.scss +1 -6
- package/v2Containers/Templates/sagas.js +2 -6
- package/v2Containers/Cap/tests/saga-coverage.test.js +0 -93
- package/v2Containers/CreativesContainer/tests/reducer.test.js +0 -72
- package/v2Containers/CreativesContainer/tests/selectors.test.js +0 -112
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fromJS } from 'immutable';
|
|
2
2
|
|
|
3
|
-
import { makeSelectDemoVideoAndLink
|
|
3
|
+
import { makeSelectDemoVideoAndLink } from 'v2Containers/Cap/selectors';
|
|
4
4
|
|
|
5
5
|
describe('CapSelectors', () => {
|
|
6
6
|
const mockState = fromJS({
|
|
@@ -11,6 +11,7 @@ describe('CapSelectors', () => {
|
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
//not need now :Temp
|
|
15
16
|
// describe('makeSelectLocationState', () => {
|
|
16
17
|
// it.concurrent('should select the route as a plain JS object', () => {
|
|
@@ -49,443 +50,4 @@ describe('CapSelectors', () => {
|
|
|
49
50
|
});
|
|
50
51
|
});
|
|
51
52
|
});
|
|
52
|
-
|
|
53
|
-
describe('setInjectedTags selector', () => {
|
|
54
|
-
// Helper function to safely convert result to plain object
|
|
55
|
-
const toPlainObject = (result) => {
|
|
56
|
-
return result && typeof result.toJS === 'function' ? result.toJS() : result;
|
|
57
|
-
};
|
|
58
|
-
it('should merge all tag types when all are present', () => {
|
|
59
|
-
// Arrange
|
|
60
|
-
const state = fromJS({
|
|
61
|
-
cap: {
|
|
62
|
-
injectedTags: { existing: 'tag1' },
|
|
63
|
-
metaEntities: {
|
|
64
|
-
tags: {
|
|
65
|
-
custom: { customTag: 'customValue' },
|
|
66
|
-
extended: { extendedTag: 'extendedValue' },
|
|
67
|
-
loyaltyTags: { loyaltyTag: 'loyaltyValue' },
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
// Due to destructuring bug in selector: const { tags } = metaEntities; fails with Immutable Maps
|
|
73
|
-
// So tags becomes undefined and only injectedTags is returned
|
|
74
|
-
const expected = {
|
|
75
|
-
existing: 'tag1',
|
|
76
|
-
};
|
|
77
|
-
const selector = setInjectedTags();
|
|
78
|
-
|
|
79
|
-
// Act
|
|
80
|
-
const result = selector(state);
|
|
81
|
-
|
|
82
|
-
// Assert
|
|
83
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should handle empty globalState with default parameter', () => {
|
|
87
|
-
// Arrange
|
|
88
|
-
const state = fromJS({ cap: {} });
|
|
89
|
-
const expected = {};
|
|
90
|
-
const selector = setInjectedTags();
|
|
91
|
-
|
|
92
|
-
// Act
|
|
93
|
-
const result = selector(state);
|
|
94
|
-
|
|
95
|
-
// Assert
|
|
96
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should handle undefined injectedTags', () => {
|
|
100
|
-
// Arrange
|
|
101
|
-
const state = fromJS({
|
|
102
|
-
cap: {
|
|
103
|
-
metaEntities: {
|
|
104
|
-
tags: {
|
|
105
|
-
custom: { customTag: 'customValue' },
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
// Since metaEntities is an Immutable Map, destructuring { tags } = metaEntities returns undefined
|
|
111
|
-
// So tags will be undefined, and customTags will be undefined
|
|
112
|
-
const expected = {};
|
|
113
|
-
const selector = setInjectedTags();
|
|
114
|
-
|
|
115
|
-
// Act
|
|
116
|
-
const result = selector(state);
|
|
117
|
-
|
|
118
|
-
// Assert
|
|
119
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should handle null injectedTags', () => {
|
|
123
|
-
// Arrange
|
|
124
|
-
const state = fromJS({
|
|
125
|
-
cap: {
|
|
126
|
-
injectedTags: null,
|
|
127
|
-
metaEntities: {
|
|
128
|
-
tags: {
|
|
129
|
-
custom: { customTag: 'customValue' },
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
|
-
// Same issue - destructuring doesn't work with Immutable Maps
|
|
135
|
-
const expected = {};
|
|
136
|
-
const selector = setInjectedTags();
|
|
137
|
-
|
|
138
|
-
// Act
|
|
139
|
-
const result = selector(state);
|
|
140
|
-
|
|
141
|
-
// Assert
|
|
142
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should handle undefined metaEntities', () => {
|
|
146
|
-
// Arrange
|
|
147
|
-
const state = fromJS({
|
|
148
|
-
cap: {
|
|
149
|
-
injectedTags: { existing: 'tag1' },
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
const expected = {
|
|
153
|
-
existing: 'tag1',
|
|
154
|
-
};
|
|
155
|
-
const selector = setInjectedTags();
|
|
156
|
-
|
|
157
|
-
// Act
|
|
158
|
-
const result = selector(state);
|
|
159
|
-
|
|
160
|
-
// Assert
|
|
161
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should handle null metaEntities', () => {
|
|
165
|
-
// Arrange
|
|
166
|
-
const state = fromJS({
|
|
167
|
-
cap: {
|
|
168
|
-
injectedTags: { existing: 'tag1' },
|
|
169
|
-
metaEntities: null,
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
const expected = {
|
|
173
|
-
existing: 'tag1',
|
|
174
|
-
};
|
|
175
|
-
const selector = setInjectedTags();
|
|
176
|
-
|
|
177
|
-
// Act
|
|
178
|
-
const result = selector(state);
|
|
179
|
-
|
|
180
|
-
// Assert
|
|
181
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it('should handle undefined tags', () => {
|
|
185
|
-
// Arrange
|
|
186
|
-
const state = fromJS({
|
|
187
|
-
cap: {
|
|
188
|
-
injectedTags: { existing: 'tag1' },
|
|
189
|
-
metaEntities: {},
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
const expected = {
|
|
193
|
-
existing: 'tag1',
|
|
194
|
-
};
|
|
195
|
-
const selector = setInjectedTags();
|
|
196
|
-
|
|
197
|
-
// Act
|
|
198
|
-
const result = selector(state);
|
|
199
|
-
|
|
200
|
-
// Assert
|
|
201
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('should handle null tags', () => {
|
|
205
|
-
// Arrange
|
|
206
|
-
const state = fromJS({
|
|
207
|
-
cap: {
|
|
208
|
-
injectedTags: { existing: 'tag1' },
|
|
209
|
-
metaEntities: {
|
|
210
|
-
tags: null,
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
// Destructuring { tags } = metaEntities will return undefined because metaEntities is Immutable Map
|
|
215
|
-
const expected = {
|
|
216
|
-
existing: 'tag1',
|
|
217
|
-
};
|
|
218
|
-
const selector = setInjectedTags();
|
|
219
|
-
|
|
220
|
-
// Act
|
|
221
|
-
const result = selector(state);
|
|
222
|
-
|
|
223
|
-
// Assert
|
|
224
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should handle undefined custom tags', () => {
|
|
228
|
-
// Arrange
|
|
229
|
-
const state = fromJS({
|
|
230
|
-
cap: {
|
|
231
|
-
injectedTags: { existing: 'tag1' },
|
|
232
|
-
metaEntities: {
|
|
233
|
-
tags: {
|
|
234
|
-
extended: { extendedTag: 'extendedValue' },
|
|
235
|
-
loyaltyTags: { loyaltyTag: 'loyaltyValue' },
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
// Destructuring issue - tags will be undefined
|
|
241
|
-
const expected = {
|
|
242
|
-
existing: 'tag1',
|
|
243
|
-
};
|
|
244
|
-
const selector = setInjectedTags();
|
|
245
|
-
|
|
246
|
-
// Act
|
|
247
|
-
const result = selector(state);
|
|
248
|
-
|
|
249
|
-
// Assert
|
|
250
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it('should handle undefined extended tags', () => {
|
|
254
|
-
// Arrange
|
|
255
|
-
const state = fromJS({
|
|
256
|
-
cap: {
|
|
257
|
-
injectedTags: { existing: 'tag1' },
|
|
258
|
-
metaEntities: {
|
|
259
|
-
tags: {
|
|
260
|
-
custom: { customTag: 'customValue' },
|
|
261
|
-
loyaltyTags: { loyaltyTag: 'loyaltyValue' },
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
// Destructuring issue - tags will be undefined
|
|
267
|
-
const expected = {
|
|
268
|
-
existing: 'tag1',
|
|
269
|
-
};
|
|
270
|
-
const selector = setInjectedTags();
|
|
271
|
-
|
|
272
|
-
// Act
|
|
273
|
-
const result = selector(state);
|
|
274
|
-
|
|
275
|
-
// Assert
|
|
276
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('should handle undefined loyalty tags', () => {
|
|
280
|
-
// Arrange
|
|
281
|
-
const state = fromJS({
|
|
282
|
-
cap: {
|
|
283
|
-
injectedTags: { existing: 'tag1' },
|
|
284
|
-
metaEntities: {
|
|
285
|
-
tags: {
|
|
286
|
-
custom: { customTag: 'customValue' },
|
|
287
|
-
extended: { extendedTag: 'extendedValue' },
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
});
|
|
292
|
-
// Destructuring issue - tags will be undefined
|
|
293
|
-
const expected = {
|
|
294
|
-
existing: 'tag1',
|
|
295
|
-
};
|
|
296
|
-
const selector = setInjectedTags();
|
|
297
|
-
|
|
298
|
-
// Act
|
|
299
|
-
const result = selector(state);
|
|
300
|
-
|
|
301
|
-
// Assert
|
|
302
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
it('should handle empty tag objects', () => {
|
|
306
|
-
// Arrange
|
|
307
|
-
const state = fromJS({
|
|
308
|
-
cap: {
|
|
309
|
-
injectedTags: { existing: 'tag1' },
|
|
310
|
-
metaEntities: {
|
|
311
|
-
tags: {
|
|
312
|
-
custom: {},
|
|
313
|
-
extended: {},
|
|
314
|
-
loyaltyTags: {},
|
|
315
|
-
},
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
});
|
|
319
|
-
// Destructuring issue - tags will be undefined
|
|
320
|
-
const expected = {
|
|
321
|
-
existing: 'tag1',
|
|
322
|
-
};
|
|
323
|
-
const selector = setInjectedTags();
|
|
324
|
-
|
|
325
|
-
// Act
|
|
326
|
-
const result = selector(state);
|
|
327
|
-
|
|
328
|
-
// Assert
|
|
329
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
it('should handle merge with overlapping keys (later values override)', () => {
|
|
333
|
-
// Arrange
|
|
334
|
-
const state = fromJS({
|
|
335
|
-
cap: {
|
|
336
|
-
injectedTags: { shared: 'injected', unique1: 'value1' },
|
|
337
|
-
metaEntities: {
|
|
338
|
-
tags: {
|
|
339
|
-
custom: { shared: 'custom', unique2: 'value2' },
|
|
340
|
-
extended: { shared: 'extended', unique3: 'value3' },
|
|
341
|
-
loyaltyTags: { shared: 'loyalty', unique4: 'value4' },
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
});
|
|
346
|
-
// Destructuring issue - tags will be undefined, so only injectedTags will be returned
|
|
347
|
-
const expected = {
|
|
348
|
-
shared: 'injected',
|
|
349
|
-
unique1: 'value1',
|
|
350
|
-
};
|
|
351
|
-
const selector = setInjectedTags();
|
|
352
|
-
|
|
353
|
-
// Act
|
|
354
|
-
const result = selector(state);
|
|
355
|
-
|
|
356
|
-
// Assert
|
|
357
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it('should handle only injectedTags with no metaEntities', () => {
|
|
361
|
-
// Arrange
|
|
362
|
-
const state = fromJS({
|
|
363
|
-
cap: {
|
|
364
|
-
injectedTags: { onlyInjected: 'value' },
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
const expected = {
|
|
368
|
-
onlyInjected: 'value',
|
|
369
|
-
};
|
|
370
|
-
const selector = setInjectedTags();
|
|
371
|
-
|
|
372
|
-
// Act
|
|
373
|
-
const result = selector(state);
|
|
374
|
-
|
|
375
|
-
// Assert
|
|
376
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('should handle only custom tags with no injectedTags', () => {
|
|
380
|
-
// Arrange
|
|
381
|
-
const state = fromJS({
|
|
382
|
-
cap: {
|
|
383
|
-
metaEntities: {
|
|
384
|
-
tags: {
|
|
385
|
-
custom: { onlyCustom: 'value' },
|
|
386
|
-
},
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
});
|
|
390
|
-
// Destructuring issue - tags will be undefined
|
|
391
|
-
const expected = {};
|
|
392
|
-
const selector = setInjectedTags();
|
|
393
|
-
|
|
394
|
-
// Act
|
|
395
|
-
const result = selector(state);
|
|
396
|
-
|
|
397
|
-
// Assert
|
|
398
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
it('should handle only extended tags with no injectedTags', () => {
|
|
402
|
-
// Arrange
|
|
403
|
-
const state = fromJS({
|
|
404
|
-
cap: {
|
|
405
|
-
metaEntities: {
|
|
406
|
-
tags: {
|
|
407
|
-
extended: { onlyExtended: 'value' },
|
|
408
|
-
},
|
|
409
|
-
},
|
|
410
|
-
},
|
|
411
|
-
});
|
|
412
|
-
// Destructuring issue - tags will be undefined
|
|
413
|
-
const expected = {};
|
|
414
|
-
const selector = setInjectedTags();
|
|
415
|
-
|
|
416
|
-
// Act
|
|
417
|
-
const result = selector(state);
|
|
418
|
-
|
|
419
|
-
// Assert
|
|
420
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
it('should handle only loyalty tags with no injectedTags', () => {
|
|
424
|
-
// Arrange
|
|
425
|
-
const state = fromJS({
|
|
426
|
-
cap: {
|
|
427
|
-
metaEntities: {
|
|
428
|
-
tags: {
|
|
429
|
-
loyaltyTags: { onlyLoyalty: 'value' },
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
});
|
|
434
|
-
// Destructuring issue - tags will be undefined
|
|
435
|
-
const expected = {};
|
|
436
|
-
const selector = setInjectedTags();
|
|
437
|
-
|
|
438
|
-
// Act
|
|
439
|
-
const result = selector(state);
|
|
440
|
-
|
|
441
|
-
// Assert
|
|
442
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
it('should handle completely empty state', () => {
|
|
446
|
-
// Arrange
|
|
447
|
-
const state = fromJS({ cap: {} });
|
|
448
|
-
const expected = {};
|
|
449
|
-
const selector = setInjectedTags();
|
|
450
|
-
|
|
451
|
-
// Act
|
|
452
|
-
const result = selector(state);
|
|
453
|
-
|
|
454
|
-
// Assert
|
|
455
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
it('should handle nested object values in tags', () => {
|
|
459
|
-
// Arrange
|
|
460
|
-
const state = fromJS({
|
|
461
|
-
cap: {
|
|
462
|
-
injectedTags: {
|
|
463
|
-
nested: { level1: { level2: 'deep' } },
|
|
464
|
-
simple: 'value',
|
|
465
|
-
},
|
|
466
|
-
metaEntities: {
|
|
467
|
-
tags: {
|
|
468
|
-
custom: {
|
|
469
|
-
customNested: { customLevel1: 'customDeep' },
|
|
470
|
-
customSimple: 'customValue',
|
|
471
|
-
},
|
|
472
|
-
},
|
|
473
|
-
},
|
|
474
|
-
},
|
|
475
|
-
});
|
|
476
|
-
// Destructuring issue - tags will be undefined
|
|
477
|
-
const expected = {
|
|
478
|
-
nested: { level1: { level2: 'deep' } },
|
|
479
|
-
simple: 'value',
|
|
480
|
-
};
|
|
481
|
-
const selector = setInjectedTags();
|
|
482
|
-
|
|
483
|
-
// Act
|
|
484
|
-
const result = selector(state);
|
|
485
|
-
|
|
486
|
-
// Assert
|
|
487
|
-
expect(toPlainObject(result)).toEqual(expected);
|
|
488
|
-
});
|
|
489
|
-
});
|
|
490
53
|
});
|
|
491
|
-
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
DEFAULT_ACTION,
|
|
9
9
|
HIDE_CONTAINER_LOADER,
|
|
10
10
|
SHOW_CONTANER_LOADER,
|
|
11
|
-
STORE_LOYALTY_TAG_PROPS,
|
|
12
11
|
} from './constants';
|
|
13
12
|
|
|
14
13
|
export function defaultAction() {
|
|
@@ -25,11 +24,4 @@ export function hideCreativesContanerLoader() {
|
|
|
25
24
|
return {
|
|
26
25
|
type: HIDE_CONTAINER_LOADER,
|
|
27
26
|
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function storeLoyaltyTagProps(props) {
|
|
31
|
-
return {
|
|
32
|
-
type: STORE_LOYALTY_TAG_PROPS,
|
|
33
|
-
props,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
27
|
+
}
|
|
@@ -29,7 +29,6 @@ export const LOYALTY_SUPPORTED_ACTION = "SEND_COMMUNICATION_ACTION";
|
|
|
29
29
|
|
|
30
30
|
export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
|
|
31
31
|
export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
|
|
32
|
-
export const STORE_LOYALTY_TAG_PROPS = "app/CreativesContainer/STORE_LOYALTY_TAG_PROPS";
|
|
33
32
|
|
|
34
33
|
export const WHATSAPP_HELP_DOC_LINK = "https://docs.capillarytech.com/docs/create-whatsapp-template";
|
|
35
34
|
|
|
@@ -125,12 +125,6 @@ export class Creatives extends React.Component {
|
|
|
125
125
|
if (!this.props?.isFullMode) {
|
|
126
126
|
this.props?.templateActions.getCdnTransformationConfig();
|
|
127
127
|
}
|
|
128
|
-
|
|
129
|
-
// Store loyalty tag props if loyaltyTagFetchingDependencies is provided
|
|
130
|
-
const { loyaltyTagFetchingDependencies } = this.props;
|
|
131
|
-
if (loyaltyTagFetchingDependencies) {
|
|
132
|
-
this.props.actions.storeLoyaltyTagProps({ ...loyaltyTagFetchingDependencies });
|
|
133
|
-
}
|
|
134
128
|
}
|
|
135
129
|
|
|
136
130
|
onEnterTemplateName = () => {
|
|
@@ -1695,7 +1689,6 @@ Creatives.propTypes = {
|
|
|
1695
1689
|
orgUnitId: PropTypes.number,
|
|
1696
1690
|
hostName: PropTypes.string,
|
|
1697
1691
|
eventContextTags: PropTypes.array,
|
|
1698
|
-
loyaltyTagFetchingDependencies: PropTypes.object,
|
|
1699
1692
|
intl: PropTypes.shape({
|
|
1700
1693
|
formatMessage: PropTypes.func,
|
|
1701
1694
|
}),
|
|
@@ -9,15 +9,11 @@ import {
|
|
|
9
9
|
DEFAULT_ACTION,
|
|
10
10
|
SHOW_CONTANER_LOADER,
|
|
11
11
|
HIDE_CONTAINER_LOADER,
|
|
12
|
-
STORE_LOYALTY_TAG_PROPS,
|
|
13
12
|
} from './constants';
|
|
14
13
|
|
|
15
14
|
const initialState = fromJS({containerLoader: true});
|
|
16
15
|
|
|
17
16
|
function creativesContainerReducer(state = initialState, action) {
|
|
18
|
-
if (!action || !action.type) {
|
|
19
|
-
return state;
|
|
20
|
-
}
|
|
21
17
|
switch (action.type) {
|
|
22
18
|
case DEFAULT_ACTION:
|
|
23
19
|
return state;
|
|
@@ -25,8 +21,6 @@ function creativesContainerReducer(state = initialState, action) {
|
|
|
25
21
|
return state.set('containerLoader', true);
|
|
26
22
|
case HIDE_CONTAINER_LOADER:
|
|
27
23
|
return state.set('containerLoader', false);
|
|
28
|
-
case STORE_LOYALTY_TAG_PROPS:
|
|
29
|
-
return state.set('loyaltyTagProps', action.props);
|
|
30
24
|
default:
|
|
31
25
|
return state;
|
|
32
26
|
}
|
|
@@ -22,14 +22,9 @@ const isLoading = () => createSelector(
|
|
|
22
22
|
makeSelectCreativesContainer(),
|
|
23
23
|
(substate) => substate?.containerLoader
|
|
24
24
|
);
|
|
25
|
-
const loyaltyTagProps = () => createSelector(
|
|
26
|
-
makeSelectCreativesContainer(),
|
|
27
|
-
(substate) => substate?.loyaltyTagProps
|
|
28
|
-
);
|
|
29
25
|
|
|
30
26
|
export default makeSelectCreativesContainer;
|
|
31
27
|
export {
|
|
32
28
|
selectCreativesContainerDomain,
|
|
33
29
|
isLoading,
|
|
34
|
-
loyaltyTagProps,
|
|
35
30
|
};
|
|
@@ -149,22 +149,6 @@ const MediaUploaders = ({
|
|
|
149
149
|
)));
|
|
150
150
|
}, [getCurrentCarouselData, setCurrentCarouselData]);
|
|
151
151
|
|
|
152
|
-
// Create carousel button tag select callback at component level to avoid hooks violation
|
|
153
|
-
const createCarouselButtonTagSelectCallback = useCallback((cardIndex) => {
|
|
154
|
-
return (value) => {
|
|
155
|
-
const currentData = getCurrentCarouselData();
|
|
156
|
-
const card = currentData[cardIndex];
|
|
157
|
-
const button = card?.buttons?.[0];
|
|
158
|
-
if (button) {
|
|
159
|
-
const newUrl = `${button?.externalLinkValue}{{${value}}}`;
|
|
160
|
-
// Update carousel card directly using updateCarouselCard
|
|
161
|
-
const updatedButtons = [...card?.buttons];
|
|
162
|
-
updatedButtons[0] = { ...updatedButtons[0], externalLinkValue: newUrl };
|
|
163
|
-
updateCarouselCard(cardIndex, { buttons: updatedButtons });
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
}, [getCurrentCarouselData, updateCarouselCard]);
|
|
167
|
-
|
|
168
152
|
// Clear previous media data when switching media types
|
|
169
153
|
useEffect(() => {
|
|
170
154
|
// Clear carousel data when switching to non-carousel media types
|
|
@@ -585,8 +569,13 @@ const MediaUploaders = ({
|
|
|
585
569
|
|
|
586
570
|
const button = card?.buttons[0]; // We're handling only one button for now
|
|
587
571
|
|
|
588
|
-
|
|
589
|
-
|
|
572
|
+
const onButtonTagSelect = useCallback(
|
|
573
|
+
(value) => {
|
|
574
|
+
const newUrl = `${button?.externalLinkValue}{{${value}}}`;
|
|
575
|
+
handleCarouselExternalLinkChange(cardIndex, newUrl);
|
|
576
|
+
},
|
|
577
|
+
[handleCarouselExternalLinkChange, button?.externalLinkValue]
|
|
578
|
+
);
|
|
590
579
|
|
|
591
580
|
return (
|
|
592
581
|
<>
|
|
@@ -658,7 +647,7 @@ const MediaUploaders = ({
|
|
|
658
647
|
)}
|
|
659
648
|
{button?.linkType === EXTERNAL_LINK && (
|
|
660
649
|
<CapColumn span={14}>
|
|
661
|
-
<CapRow
|
|
650
|
+
<CapRow>
|
|
662
651
|
<CapHeading type="h4" className="buttons-heading">
|
|
663
652
|
{formatMessage(messages.externalLink)}
|
|
664
653
|
</CapHeading>
|
|
@@ -148,15 +148,10 @@
|
|
|
148
148
|
margin-bottom: $CAP_SPACE_16;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
.buttons-heading-container {
|
|
152
|
-
display: flex;
|
|
153
|
-
justify-content: space-between;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
151
|
.buttons-heading {
|
|
157
152
|
margin-bottom: $CAP_SPACE_12;
|
|
158
153
|
margin-top: $CAP_SPACE_12;
|
|
159
|
-
margin-right:
|
|
154
|
+
margin-right: 48%;
|
|
160
155
|
}
|
|
161
156
|
|
|
162
157
|
.helper-text {
|
|
@@ -7,8 +7,7 @@ import * as Api from '../../services/api';
|
|
|
7
7
|
import * as types from './constants';
|
|
8
8
|
import { saveCdnConfigs, removeAllCdnLocalStorageItems } from '../../utils/cdnTransformation';
|
|
9
9
|
import { COPY_OF } from '../../constants/unified';
|
|
10
|
-
|
|
11
|
-
import { getTemplateInfoById } from '../Zalo/saga';
|
|
10
|
+
// Removed Zalo imports - handled by Zalo component's own saga
|
|
12
11
|
import { watchCreateTemplate } from '../MobilePushNew/sagas';
|
|
13
12
|
// Individual exports for testing
|
|
14
13
|
export function* getAllTemplates(channel, queryParams) {
|
|
@@ -227,9 +226,6 @@ export function* watchGetCdnTransformationConfig() {
|
|
|
227
226
|
);
|
|
228
227
|
}
|
|
229
228
|
|
|
230
|
-
export function* watchForGetTemplateInfoById() {
|
|
231
|
-
yield takeLatest(ZALO_TEMPLATE_INFO_REQUEST, getTemplateInfoById);
|
|
232
|
-
}
|
|
233
229
|
|
|
234
230
|
// All sagas to be loaded
|
|
235
231
|
export default [
|
|
@@ -255,7 +251,7 @@ export function* v2TemplateSaga() {
|
|
|
255
251
|
watchGetCdnTransformationConfig(),
|
|
256
252
|
watchFetchWeCrmAccounts(),
|
|
257
253
|
watchGetSenderDetails(),
|
|
258
|
-
watchForGetTemplateInfoById()
|
|
254
|
+
// Removed watchForGetTemplateInfoById() - this is handled by Zalo component's own saga
|
|
259
255
|
]);
|
|
260
256
|
}
|
|
261
257
|
|