@capillarytech/creatives-library 8.0.152 → 8.0.153-beta.1

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.152",
4
+ "version": "8.0.153-beta.1",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -33,6 +33,22 @@ function SlideBoxFooter(props) {
33
33
  shouldShowContinueFooter,
34
34
  } = props;
35
35
 
36
+ console.log("SlideBoxFooter", {
37
+ slidBoxContent,
38
+ onSave,
39
+ onEditTemplate,
40
+ onCreateNextStep,
41
+ isFullMode,
42
+ fetchingCmsData,
43
+ isTemplateNameEmpty,
44
+ errorMessages,
45
+ isLiquidValidationError,
46
+ currentTab,
47
+ onTestAndPreview,
48
+ showTestAndPreviewButton,
49
+ shouldShowContinueFooter: shouldShowContinueFooter(),
50
+ shouldShowDoneFooter: shouldShowDoneFooter(),
51
+ });
36
52
  return (
37
53
  <div className='template-footer-width'>
38
54
  {isLiquidValidationError && (<ErrorInfoNote errorMessages={errorMessages} currentTab={currentTab?.toUpperCase()} />)}
@@ -200,12 +200,19 @@ export class Creatives extends React.Component {
200
200
  }
201
201
 
202
202
  onCreateNextStep = () => {
203
+ console.log("onCreateNextStep 1");
203
204
  this.setState((prevState) => {
204
205
  let templateStep = prevState.templateStep + 1;
205
206
  const { emailCreateMode, currentChannel } = prevState;
206
207
  if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
207
208
  templateStep = prevState.templateStep + 2;
208
209
  }
210
+ console.log("onCreateNextStep 2", {
211
+ templateStep,
212
+ currentChannel,
213
+ emailCreateMode,
214
+ prevState,
215
+ });
209
216
  return {
210
217
  templateStep,
211
218
  };
@@ -1353,7 +1360,17 @@ export class Creatives extends React.Component {
1353
1360
  }
1354
1361
  }
1355
1362
 
1356
-
1363
+ console.log("shouldShowDoneFooter", {
1364
+ showDone,
1365
+ channel,
1366
+ currentStep,
1367
+ slidBoxContent,
1368
+ templateStep,
1369
+ currentChannel,
1370
+ templateData,
1371
+ isFullMode,
1372
+ isEmail: channel === constants.EMAIL,
1373
+ });
1357
1374
  return showDone;
1358
1375
  }
1359
1376
 
@@ -1432,7 +1449,19 @@ export class Creatives extends React.Component {
1432
1449
  } else if (currentChannel.toUpperCase() === constants.INAPP) {
1433
1450
  isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1434
1451
  }
1435
-
1452
+ console.log("shouldShowContinueFooter", {
1453
+ isShowContinueFooter,
1454
+ mobilePushCreateMode,
1455
+ weChatTemplateType,
1456
+ inAppCreateMode,
1457
+ currentStep,
1458
+ currentChannel,
1459
+ slidBoxContent,
1460
+ templateStep,
1461
+ emailCreateMode,
1462
+ emailLayout: this.props?.EmailLayout,
1463
+ isEmail: channel === constants.EMAIL,
1464
+ });
1436
1465
  return isShowContinueFooter;
1437
1466
  }
1438
1467
 
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useMemo, useCallback } from 'react';
1
+ import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
2
2
  import isEmpty from 'lodash/isEmpty';
3
3
  import get from 'lodash/get';
4
4
  import find from 'lodash/find';
@@ -66,6 +66,9 @@ const useEmailWrapper = ({
66
66
  query: { module: 'library', type: 'embedded' },
67
67
  });
68
68
 
69
+ // Prevent duplicate uploads from rapid/double onChange events
70
+ const isUploadingRef = useRef(false);
71
+
69
72
  // Cleanup effect
70
73
  useEffect(() => {
71
74
  return () => {
@@ -114,6 +117,11 @@ const useEmailWrapper = ({
114
117
  }, [formatMessage]);
115
118
 
116
119
  const handleFileUpload = useCallback((file = {}) => {
120
+ // Guard against duplicate triggers (e.g., multiple onChange emissions)
121
+ if (isUploadingRef.current || isUploading) {
122
+ return;
123
+ }
124
+
117
125
  if (!isUploading) {
118
126
  // Validate file object
119
127
  if (!file || !file.name) {
@@ -147,11 +155,20 @@ const useEmailWrapper = ({
147
155
  return;
148
156
  }
149
157
 
158
+ // Mark uploading to prevent duplicate dispatches before Redux state updates
159
+ isUploadingRef.current = true;
160
+
150
161
  templatesActions.handleZipUpload(file.originFileObj, () => { // Handle upload success
151
162
  stopTimerGA();
152
163
  setModeContent({ file });
164
+ // Clear local uploading guard before navigating to next step
165
+ isUploadingRef.current = false;
153
166
  showNextStep();
154
- }, handleZipUploadError);
167
+ }, () => {
168
+ // Clear local uploading guard on error as well
169
+ isUploadingRef.current = false;
170
+ handleZipUploadError();
171
+ });
155
172
  } else if (fileExtension === 'html' || fileExtension === 'htm') {
156
173
  // Verify originFileObj exists
157
174
  if (!file.originFileObj) {
@@ -159,12 +176,16 @@ const useEmailWrapper = ({
159
176
  return;
160
177
  }
161
178
 
179
+ // Guard during HTML processing to avoid duplicate reads
180
+ isUploadingRef.current = true;
181
+
162
182
  const reader = new FileReader();
163
183
  reader.onload = () => {
164
184
  const text = reader.result;
165
185
  // Add defensive check for empty or invalid content
166
186
  if (!text || typeof text !== 'string') {
167
187
  handleZipUploadError();
188
+ isUploadingRef.current = false;
168
189
  return;
169
190
  }
170
191
 
@@ -173,9 +194,12 @@ const useEmailWrapper = ({
173
194
 
174
195
  setModeContent({ file });
175
196
  templatesActions.handleHtmlUpload(text);
197
+ // Clear uploading guard after handing off HTML upload
198
+ isUploadingRef.current = false;
176
199
  };
177
200
  reader.onerror = () => {
178
201
  handleZipUploadError();
202
+ isUploadingRef.current = false;
179
203
  };
180
204
  reader.readAsText(file.originFileObj);
181
205
  } else {