@capillarytech/creatives-library 8.0.160 → 8.0.162

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.160",
4
+ "version": "8.0.162",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -438,64 +438,56 @@ const TestAndPreviewSlidebox = (props) => {
438
438
 
439
439
  // Handle update preview
440
440
  const handleUpdatePreview = async () => {
441
- const currentTabData = formData[currentTab - 1];
442
- const activeTab = currentTabData?.activeTab;
443
- const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
444
-
445
- // For BEE editor, ensure content is saved first
446
- if (isDragDrop && beeInstance) {
447
- // Trigger save to ensure latest content
448
- beeInstance.save();
441
+ try {
442
+ // Store current values to prevent loss during update
443
+ const currentCustomValues = { ...customValues };
444
+
445
+ const currentTabData = formData[currentTab - 1];
446
+ const activeTab = currentTabData?.activeTab;
447
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
449
448
 
450
- // Wait a bit for save to complete and formData to update
451
- await new Promise((resolve) => setTimeout(resolve, 500));
449
+ // For BEE editor, ensure content is saved first
450
+ if (isDragDrop && beeInstance) {
451
+ // Trigger save to ensure latest content
452
+ beeInstance.save();
452
453
 
453
- // Get latest content from formData
454
- const updatedContent = formData[currentTab - 1]?.[activeTab]?.['template-content'];
455
- const payload = {
456
- channel: EMAIL,
457
- messageTitle: formData['template-subject'],
458
- messageBody: updatedContent || getCurrentContent,
459
- resolvedTags: customValues,
460
- userId: selectedCustomer?.customerId,
461
- };
454
+ // Wait a bit for save to complete and formData to update
455
+ await new Promise((resolve) => setTimeout(resolve, 500));
462
456
 
463
- actions.updatePreviewRequested(payload);
464
- return;
465
- }
457
+ // Get latest content from formData
458
+ const updatedContent = formData[currentTab - 1]?.[activeTab]?.['template-content'];
459
+ const payload = {
460
+ channel: EMAIL,
461
+ messageTitle: formData['template-subject'],
462
+ messageBody: updatedContent || getCurrentContent,
463
+ resolvedTags: currentCustomValues, // Use stored values
464
+ userId: selectedCustomer?.customerId,
465
+ };
466
466
 
467
- // For CKEditor, get latest content directly from formData
468
- const templateContent = currentTabData?.[activeTab]?.['template-content'];
469
- if (templateContent) {
470
- // Update preview with latest content
471
- setPreviewDataHtml({
472
- resolvedBody: templateContent,
473
- resolvedTitle: formData['template-subject'] || ''
474
- });
467
+ await actions.updatePreviewRequested(payload);
468
+ return;
469
+ }
475
470
 
476
- // Extract tags with latest content
477
- const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
478
- actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
471
+ // For CKEditor, get latest content directly from formData
472
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
473
+ if (templateContent) {
474
+ // Create payload for CKEditor preview update
475
+ const payload = {
476
+ channel: EMAIL,
477
+ messageTitle: formData['template-subject'],
478
+ messageBody: templateContent,
479
+ resolvedTags: currentCustomValues,
480
+ userId: selectedCustomer?.customerId,
481
+ };
479
482
 
480
- // Update preview with latest content
481
- const payload = {
482
- channel: EMAIL,
483
- messageTitle: formData['template-subject'],
484
- messageBody: templateContent,
485
- resolvedTags: customValues,
486
- userId: selectedCustomer?.customerId,
487
- };
488
- actions.updatePreviewRequested(payload);
489
- } else {
490
- // Fallback to getCurrentContent if no template content
491
- const payload = {
492
- channel: EMAIL,
493
- messageTitle: formData['template-subject'],
494
- messageBody: getCurrentContent,
495
- resolvedTags: customValues,
496
- userId: selectedCustomer?.customerId,
497
- };
498
- actions.updatePreviewRequested(payload);
483
+ // Use the same update preview action for both editors
484
+ await actions.updatePreviewRequested(payload);
485
+ }
486
+ } catch (error) {
487
+ console.error('Error updating preview:', error);
488
+ CapNotification.error({
489
+ message: formatMessage(messages.previewUpdateError),
490
+ });
499
491
  }
500
492
  };
501
493
 
@@ -132,18 +132,27 @@ const previewAndTestReducer = (state = initialState, action) => {
132
132
 
133
133
  // Update Preview
134
134
  case UPDATE_PREVIEW_REQUEST:
135
- return state.set('isUpdatingPreview', true)
136
- .set('updatePreviewError', null);
135
+ return state
136
+ .set('isUpdatingPreview', true)
137
+ .set('updatePreviewError', null)
138
+ // Preserve custom values during update
139
+ .set('lastCustomValues', state.get('customValues'));
137
140
 
138
141
  case UPDATE_PREVIEW_SUCCESS:
139
- return state.set('previewData', action.payload.previewData)
142
+ return state
143
+ .set('previewData', action.payload.previewData)
140
144
  .set('isUpdatingPreview', false)
141
- .set('updatePreviewError', null);
145
+ .set('updatePreviewError', null)
146
+ // Restore custom values after successful update
147
+ .set('customValues', state.get('lastCustomValues') || state.get('customValues'));
142
148
 
143
149
  case UPDATE_PREVIEW_FAILURE:
144
- return state.set('previewData', null)
150
+ return state
151
+ .set('previewData', null)
145
152
  .set('isUpdatingPreview', false)
146
- .set('updatePreviewError', action.payload.error);
153
+ .set('updatePreviewError', action.payload.error)
154
+ // Restore custom values after failure
155
+ .set('customValues', fromJS(action.payload.customValues));
147
156
 
148
157
  // Send Test Email
149
158
  case SEND_TEST_MESSAGE_REQUESTED:
@@ -76,14 +76,35 @@ export function* extractTagsSaga(action) {
76
76
  // Update Preview Saga
77
77
  export function* updatePreviewSaga(action) {
78
78
  try {
79
+ // Store custom values before making the API call
80
+ const customValues = action.payload.resolvedTags;
81
+
79
82
  const response = yield call(Api.updateEmailPreview, action.payload);
80
83
  if (response?.data) {
81
- yield put({ type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: response.data } });
84
+ yield put({
85
+ type: UPDATE_PREVIEW_SUCCESS,
86
+ payload: {
87
+ previewData: response.data,
88
+ customValues, // Pass custom values to be preserved
89
+ },
90
+ });
82
91
  } else {
83
- yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: response.error || 'Failed to update preview' } });
92
+ yield put({
93
+ type: UPDATE_PREVIEW_FAILURE,
94
+ payload: {
95
+ error: response.error || 'Failed to update preview',
96
+ customValues, // Pass custom values even on failure
97
+ },
98
+ });
84
99
  }
85
100
  } catch (error) {
86
- yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: error.message || 'Network error occurred' } });
101
+ yield put({
102
+ type: UPDATE_PREVIEW_FAILURE,
103
+ payload: {
104
+ error: error.message || 'Network error occurred',
105
+ customValues: action.payload.resolvedTags, // Pass custom values on error
106
+ },
107
+ });
87
108
  }
88
109
  }
89
110
 
@@ -105,27 +105,43 @@ describe("previewAndTestReducer", () => {
105
105
  const state = fromJS({
106
106
  isUpdatingPreview: false,
107
107
  updatePreviewError: null,
108
+ customValues: { test: "value" },
108
109
  });
109
110
  const action = { type: UPDATE_PREVIEW_REQUEST };
110
- const expectedResult = state.set("isUpdatingPreview", true).set("updatePreviewError", null);
111
+ const expectedResult = state
112
+ .set("isUpdatingPreview", true)
113
+ .set("updatePreviewError", null)
114
+ .set("lastCustomValues", state.get("customValues"));
111
115
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
112
116
  });
113
117
  it("should handle UPDATE_PREVIEW_SUCCESS action", () => {
118
+ const customValues = fromJS({ test: "value" });
114
119
  const state = fromJS({
115
120
  isUpdatingPreview: false,
116
121
  updatePreviewError: null,
122
+ lastCustomValues: customValues,
117
123
  });
118
- const action = { type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: "test" } };
119
- const expectedResult = state.set("isUpdatingPreview", false).set("updatePreviewError", null).set("previewData", "test");
124
+ const action = { type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: "test", customValues: customValues.toJS() } };
125
+ const expectedResult = state
126
+ .set("isUpdatingPreview", false)
127
+ .set("updatePreviewError", null)
128
+ .set("previewData", "test")
129
+ .set("customValues", customValues);
120
130
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
121
131
  });
122
132
  it("should handle UPDATE_PREVIEW_FAILURE action", () => {
133
+ const customValues = fromJS({ test: "value" });
123
134
  const state = fromJS({
124
135
  isUpdatingPreview: false,
125
136
  updatePreviewError: null,
137
+ lastCustomValues: customValues,
126
138
  });
127
- const action = { type: UPDATE_PREVIEW_FAILURE, payload: { error: "Update preview failed" } };
128
- const expectedResult = state.set("isUpdatingPreview", false).set("updatePreviewError", "Update preview failed").set("previewData", null);
139
+ const action = { type: UPDATE_PREVIEW_FAILURE, payload: { error: "Update preview failed", customValues: customValues.toJS() } };
140
+ const expectedResult = state
141
+ .set("isUpdatingPreview", false)
142
+ .set("updatePreviewError", "Update preview failed")
143
+ .set("previewData", null)
144
+ .set("customValues", fromJS(action.payload.customValues));
129
145
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
130
146
  });
131
147
 
@@ -138,18 +138,21 @@ describe('TestAndPreviewSlidebox Sagas', () => {
138
138
  const mockResponse = {
139
139
  data: 'Test Preview Data',
140
140
  };
141
+ const customValues = { test: 'value' };
141
142
  return expectSaga(sagas.updatePreviewSaga, {
142
143
  payload: {
143
144
  previewData: 'Test Preview Data',
145
+ resolvedTags: customValues,
144
146
  },
145
147
  })
146
148
  .provide([
147
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
149
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
148
150
  ])
149
151
  .put({
150
152
  type: types.UPDATE_PREVIEW_SUCCESS,
151
153
  payload: {
152
154
  previewData: mockResponse.data,
155
+ customValues,
153
156
  },
154
157
  })
155
158
  .run();
@@ -159,18 +162,21 @@ describe('TestAndPreviewSlidebox Sagas', () => {
159
162
  previewData: 'Test Preview Data',
160
163
  error: 'Failed to load preview',
161
164
  };
165
+ const customValues = { test: 'value' };
162
166
  return expectSaga(sagas.updatePreviewSaga, {
163
167
  payload: {
164
168
  previewData: 'Test Preview Data',
169
+ resolvedTags: customValues,
165
170
  },
166
171
  })
167
172
  .provide([
168
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
173
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
169
174
  ])
170
175
  .put({
171
176
  type: types.UPDATE_PREVIEW_FAILURE,
172
177
  payload: {
173
178
  error: 'Failed to load preview',
179
+ customValues,
174
180
  },
175
181
  })
176
182
  .run();
@@ -179,54 +185,63 @@ describe('TestAndPreviewSlidebox Sagas', () => {
179
185
  const mockResponse = {
180
186
  previewData: 'Test Preview Data',
181
187
  };
188
+ const customValues = { test: 'value' };
182
189
  return expectSaga(sagas.updatePreviewSaga, {
183
190
  payload: {
184
191
  previewData: 'Test Preview Data',
192
+ resolvedTags: customValues,
185
193
  },
186
194
  })
187
195
  .provide([
188
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
196
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
189
197
  ])
190
198
  .put({
191
199
  type: types.UPDATE_PREVIEW_FAILURE,
192
200
  payload: {
193
201
  error: 'Failed to update preview',
202
+ customValues,
194
203
  },
195
204
  })
196
205
  .run();
197
206
  });
198
207
  it('should handle error in updatePreviewSaga', () => {
199
208
  const error = new Error('Preview update failed');
209
+ const customValues = { test: 'value' };
200
210
  return expectSaga(sagas.updatePreviewSaga, {
201
211
  payload: {
202
212
  previewData: 'Test Preview Data',
213
+ resolvedTags: customValues,
203
214
  },
204
215
  })
205
216
  .provide([
206
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), throwError(error)],
217
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), throwError(error)],
207
218
  ])
208
219
  .put({
209
220
  type: types.UPDATE_PREVIEW_FAILURE,
210
221
  payload: {
211
222
  error: error.message,
223
+ customValues,
212
224
  },
213
225
  })
214
226
  .run();
215
227
  });
216
228
  it('should handle error in updatePreviewSaga', () => {
217
229
  const error = 'Preview update failed';
230
+ const customValues = { test: 'value' };
218
231
  return expectSaga(sagas.updatePreviewSaga, {
219
232
  payload: {
220
233
  previewData: 'Test Preview Data',
234
+ resolvedTags: customValues,
221
235
  },
222
236
  })
223
237
  .provide([
224
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), throwError(error)],
238
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), throwError(error)],
225
239
  ])
226
240
  .put({
227
241
  type: types.UPDATE_PREVIEW_FAILURE,
228
242
  payload: {
229
243
  error: 'Network error occurred',
244
+ customValues,
230
245
  },
231
246
  })
232
247
  .run();
@@ -80,7 +80,7 @@ export const mediaTypeOptions = ({host, templateCategory}) => {
80
80
  tagColor: CAP_GREEN02,
81
81
  tagTextColor: CAP_GREEN01,
82
82
  },
83
- ...(templateCategory === WHATSAPP_CATEGORIES.marketing && host === HOST_GUPSHUP
83
+ ...(templateCategory === WHATSAPP_CATEGORIES.marketing && (host === HOST_GUPSHUP || host === HOST_KARIX)
84
84
  ? [
85
85
  {
86
86
  key: 'CAROUSEL',
@@ -577,7 +577,7 @@ describe('mediaTypeOptions', () => {
577
577
  ? opt.some((o) => o.key === 'CAROUSEL')
578
578
  : opt.key === 'CAROUSEL'
579
579
  ) || options.flat().some((o) => o.key === 'CAROUSEL');
580
- expect(hasCarousel).toBe(false);
580
+ expect(hasCarousel).toBe(true);
581
581
  });
582
582
 
583
583
  it('should NOT include CAROUSEL when category is NOT MARKETING and host is HOST_GUPSHUP', () => {