@capillarytech/creatives-library 8.0.159-alpha.0 → 8.0.159-alpha.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.159-alpha.0",
4
+ "version": "8.0.159-alpha.1",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -79,6 +79,7 @@
79
79
  }
80
80
  .email-subject-desktop {
81
81
  text-align: left;
82
+ margin-left: 6%;
82
83
  margin-bottom: 8px;
83
84
  }
84
85
  .tablet-message-container-v2 {
@@ -65,6 +65,7 @@ $classPrefix: email-preview-v2;
65
65
  }
66
66
  .email-subject-desktop {
67
67
  text-align: left;
68
+ margin-left: 6%;
68
69
  margin-bottom: 8px;
69
70
  }
70
71
  .tablet-message-container {
@@ -235,9 +235,15 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
235
235
  ( !this.state.usingTabContainer || (this.state.usingTabContainer && nextProps.tabKey !== ''))
236
236
  && !_.isEqual(nextProps.formData, this.state.formData) &&
237
237
  !_.isEqual(nextProps.formData, this.props.formData)) {
238
- this.setState({formData: nextProps.formData, tabKey: nextProps.tabKey}, () => {
239
- this.validateForm();
240
- });
238
+ // Don't run validation if we're in Test & Preview mode
239
+ if (!nextProps.isTestAndPreviewMode) {
240
+ this.setState({formData: nextProps.formData, tabKey: nextProps.tabKey}, () => {
241
+ this.validateForm();
242
+ });
243
+ } else {
244
+ // Just update formData without validation
245
+ this.setState({formData: nextProps.formData, tabKey: nextProps.tabKey});
246
+ }
241
247
  //this.resetTabKeys(nextProps.formData, nextProps.tabCount);
242
248
  } else if ((_.isEmpty(this.props.formData) || !this.props.formData) && _.isEmpty(this.state.formData)) {
243
249
  this.initialiseForm(nextProps.schema, true);
@@ -265,10 +271,16 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
265
271
  this.resetTabKeys(nextProps.formData, nextProps.tabCount, false, true);
266
272
  }
267
273
  if (type === 'embedded' || ( this.props.schema.channel && this.props.schema.channel.toUpperCase() === 'EMAIL')) {
268
- this.validateForm();
274
+ // Don't run validation if we're in Test & Preview mode
275
+ if (!nextProps.isTestAndPreviewMode) {
276
+ this.validateForm();
277
+ }
269
278
  }
270
279
  if ((this.props.schema && this.props.schema.channel && this.props.schema.channel.toUpperCase() === 'MOBILEPUSH')) {
271
- this.validateForm();
280
+ // Don't run validation if we're in Test & Preview mode
281
+ if (!nextProps.isTestAndPreviewMode) {
282
+ this.validateForm();
283
+ }
272
284
  }
273
285
  });
274
286
  }
@@ -286,7 +298,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
286
298
  }
287
299
 
288
300
  this.initialiseForm(nextProps.schema, false, resetTabKeys);
289
- this.validateForm();
301
+ // Don't run validation if we're in Test & Preview mode
302
+ if (!nextProps.isTestAndPreviewMode) {
303
+ this.validateForm();
304
+ }
290
305
  }
291
306
  });
292
307
  }
@@ -299,10 +314,16 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
299
314
  }
300
315
 
301
316
  if (!_.isEmpty(nextProps.injectedTags) && !_.isEqual(nextProps.injectedTags, this.props.injectedTags)) {
302
- this.validateForm(nextProps.tags, nextProps.injectedTags);
317
+ // Don't run validation if we're in Test & Preview mode
318
+ if (!nextProps.isTestAndPreviewMode) {
319
+ this.validateForm(nextProps.tags, nextProps.injectedTags);
320
+ }
303
321
  }
304
322
  if (!_.isEmpty(nextProps.tags) && !_.isEqual(nextProps.tags, this.props.tags)) {
305
- this.validateForm(nextProps.tags, nextProps.injectedTags);
323
+ // Don't run validation if we're in Test & Preview mode
324
+ if (!nextProps.isTestAndPreviewMode) {
325
+ this.validateForm(nextProps.tags, nextProps.injectedTags);
326
+ }
306
327
  }
307
328
  if (!_.isEqual(nextProps.showModal, this.props.showModal)) {
308
329
  this.setState({showModal: nextProps.showModal});
@@ -3917,55 +3938,59 @@ FormBuilder.defaultProps = {
3917
3938
  userLocale: localStorage.getItem('jlocale') || 'en',
3918
3939
  showLiquidErrorInFooter: () => {},
3919
3940
  metaDataStatus: "",
3941
+ isTestAndPreviewMode: false, // Default to false to maintain existing behavior
3920
3942
  };
3921
3943
 
3922
3944
  FormBuilder.propTypes = {
3923
3945
  schema: PropTypes.object.isRequired,
3924
- onSubmit: PropTypes.func,
3925
- formData: PropTypes.object,
3926
- onChange: PropTypes.func,
3927
- isEdit: PropTypes.bool,
3928
- usingTabContainer: PropTypes.bool,
3929
- parent: PropTypes.object,
3930
- iframeParent: PropTypes.object,
3931
- location: PropTypes.object,
3932
- tags: PropTypes.array,
3933
- injectedTags: PropTypes.object,
3934
- onFormValidityChange: PropTypes.func,
3935
- checkValidation: PropTypes.bool,
3936
- onContextChange: PropTypes.func,
3937
- tabCount: PropTypes.number,
3938
- isSchemaChanged: PropTypes.bool,
3939
- modal: PropTypes.object,
3940
- isNewVersionFlow: PropTypes.bool,
3941
- baseLanguage: PropTypes.string,
3942
- supportedLanguages: PropTypes.array,
3943
- router: PropTypes.object,
3944
- currentTab: PropTypes.number,
3945
- showModal: PropTypes.bool,
3946
- handleCancelModal: PropTypes.func,
3947
- cmsTemplates: PropTypes.array,
3948
- getCmsTemplatesInProgress: PropTypes.bool,
3949
- showEdmEmailTemplates: PropTypes.bool,
3950
- toggleEdmEmailTemplateSelection: PropTypes.func,
3951
- handleEdmDefaultTemplateSelection: PropTypes.func,
3952
- userLocale: PropTypes.string,
3953
- setModalContent: PropTypes.func,
3954
- addLanguageType: PropTypes.string,
3955
- getValidationData: PropTypes.func,
3956
- startValidation: PropTypes.bool,
3957
- // saveForm: PropTypes.bool,
3958
- stopValidation: PropTypes.func,
3959
- handleDelete: PropTypes.func,
3960
- intl: intlShape.isRequired,
3961
- selectedOfferDetails: PropTypes.array,
3962
- setDrawerVisibility: PropTypes.bool,
3963
- capDrawerContent: PropTypes.array,
3964
- isFullMode: PropTypes.bool,
3965
- currentOrgDetails: PropTypes.object,
3966
- liquidExtractionInProgress: PropTypes.bool,
3967
- showLiquidErrorInFooter: PropTypes.func,
3968
- channel: PropTypes.string,
3946
+ onSubmit: PropTypes.func.isRequired,
3947
+ onChange: PropTypes.func.isRequired,
3948
+ currentTab: PropTypes.number.isRequired,
3949
+ parent: PropTypes.object.isRequired,
3950
+ formData: PropTypes.object.isRequired,
3951
+ location: PropTypes.object.isRequired,
3952
+ tabKey: PropTypes.string.isRequired,
3953
+ tags: PropTypes.array.isRequired,
3954
+ tagModule: PropTypes.string.isRequired,
3955
+ injectedTags: PropTypes.object.isRequired,
3956
+ onFormValidityChange: PropTypes.func.isRequired,
3957
+ handleCancelModal: PropTypes.func.isRequired,
3958
+ usingTabContainer: PropTypes.bool.isRequired,
3959
+ checkValidation: PropTypes.bool.isRequired,
3960
+ onContextChange: PropTypes.func.isRequired,
3961
+ tabCount: PropTypes.number.isRequired,
3962
+ isNewVersionFlow: PropTypes.bool.isRequired,
3963
+ modal: PropTypes.object.isRequired,
3964
+ showModal: PropTypes.bool.isRequired,
3965
+ isEdit: PropTypes.bool.isRequired,
3966
+ iframeParent: PropTypes.object.isRequired,
3967
+ router: PropTypes.object.isRequired,
3968
+ baseLanguage: PropTypes.string.isRequired,
3969
+ supportedLanguages: PropTypes.array.isRequired,
3970
+ isSchemaChanged: PropTypes.bool.isRequired,
3971
+ cmsTemplates: PropTypes.array.isRequired,
3972
+ getCmsTemplatesInProgress: PropTypes.bool.isRequired,
3973
+ showEdmEmailTemplates: PropTypes.bool.isRequired,
3974
+ toggleEdmEmailTemplateSelection: PropTypes.func.isRequired,
3975
+ handleEdmDefaultTemplateSelection: PropTypes.func.isRequired,
3976
+ setModalContent: PropTypes.func.isRequired,
3977
+ addLanguageType: PropTypes.string.isRequired,
3978
+ startValidation: PropTypes.bool.isRequired,
3979
+ getValidationData: PropTypes.func.isRequired,
3980
+ saveForm: PropTypes.bool.isRequired,
3981
+ stopValidation: PropTypes.func.isRequired,
3982
+ selectedOfferDetails: PropTypes.object.isRequired,
3983
+ saveBeeInstance: PropTypes.func.isRequired,
3984
+ saveBeeData: PropTypes.func.isRequired,
3985
+ uuid: PropTypes.string.isRequired,
3986
+ type: PropTypes.string.isRequired,
3987
+ isEmailLoading: PropTypes.bool.isRequired,
3988
+ moduleType: PropTypes.string.isRequired,
3989
+ showLiquidErrorInFooter: PropTypes.bool.isRequired,
3990
+ eventContextTags: PropTypes.array.isRequired,
3991
+ forwardedTags: PropTypes.object.isRequired,
3992
+ isLoyaltyModule: PropTypes.bool.isRequired,
3993
+ isTestAndPreviewMode: PropTypes.bool, // Add new prop type
3969
3994
  };
3970
3995
 
3971
3996
  const mapStateToProps = createStructuredSelector({
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import PropTypes from 'prop-types';
8
- import React, { useState, useEffect, useMemo } from 'react';
8
+ import React, { useState, useEffect, useMemo, useRef } from 'react';
9
9
  import { convert } from "html-to-text";
10
10
  import { createStructuredSelector } from 'reselect';
11
11
  import { connect } from 'react-redux';
@@ -75,6 +75,7 @@ const TestAndPreviewSlidebox = (props) => {
75
75
  prefilledValues,
76
76
  isSendingTestMessage,
77
77
  beeInstance,
78
+ currentTab = 1, // Add currentTab prop with default value
78
79
  } = props;
79
80
 
80
81
  // State management
@@ -87,33 +88,169 @@ const TestAndPreviewSlidebox = (props) => {
87
88
  const [previewDevice, setPreviewDevice] = useState('desktop');
88
89
  const [previewDataHtml, setPreviewDataHtml] = useState(previewData || '');
89
90
  const [selectedTestEntities, setSelectedTestEntities] = useState([]);
91
+ const [beeContent, setBeeContent] = useState(''); // Track BEE editor content separately
92
+ const previousBeeContentRef = useRef(''); // Track previous BEE content to prevent unnecessary updates
90
93
 
91
94
  const isUpdatePreviewDisabled = useMemo(() => (
92
95
  requiredTags.some((tag) => !customValues[tag.fullPath])
93
96
  ), [requiredTags, customValues]);
94
97
 
98
+ // Get the current content based on editor type
99
+ const getCurrentContent = useMemo(() => {
100
+ const currentTabData = formData[currentTab - 1];
101
+ const activeTab = currentTabData?.activeTab;
102
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
103
+
104
+ console.log('🔍 getCurrentContent computed:', {
105
+ beeInstance: !!beeInstance,
106
+ isDragDrop,
107
+ beeContent: beeContent || 'EMPTY',
108
+ content: content || 'EMPTY',
109
+ templateContent: currentTabData?.[activeTab]?.[`template-content`] || 'EMPTY',
110
+ result: isDragDrop && beeContent ? beeContent : content
111
+ });
112
+
113
+ if (isDragDrop && beeContent) {
114
+ return beeContent; // Use BEE content if available
115
+ }
116
+ return content; // Fall back to content prop
117
+ }, [formData, currentTab, beeContent, content, beeInstance]);
118
+
95
119
  useEffect(() => {
96
120
  // Only save BEE content if we're actually using BEE editor
97
- const currentTabData = formData[formData.currentTab - 1];
121
+ const currentTabData = formData[currentTab - 1];
98
122
  const activeTab = currentTabData?.activeTab;
99
123
  const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
100
124
 
101
125
  if (show && beeInstance && isDragDrop) {
102
- beeInstance.save();
126
+ // Check if we already have content in formData
127
+ const existingContent = currentTabData?.[activeTab]?.[`template-content`];
128
+ if (existingContent && existingContent.trim() !== '') {
129
+ // We already have content, update local state only if it's different
130
+ if (existingContent !== previousBeeContentRef.current) {
131
+ previousBeeContentRef.current = existingContent;
132
+ setBeeContent(existingContent);
133
+ setPreviewDataHtml({
134
+ resolvedBody: existingContent,
135
+ resolvedTitle: formData['template-subject'] || ''
136
+ });
137
+ }
138
+ } else {
139
+ // No content yet, trigger save
140
+ beeInstance.save();
141
+ }
103
142
  }
104
- }, [show, beeInstance, formData]);
143
+ }, [show, beeInstance, currentTab]);
105
144
 
106
145
  useEffect(() => {
107
146
  if (show) {
147
+ // For BEE editor, ensure content is saved and synced first
148
+ const currentTabData = formData[currentTab - 1];
149
+ const activeTab = currentTabData?.activeTab;
150
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
151
+
152
+ console.log('🔍 Tag extraction debug:', {
153
+ show,
154
+ beeInstance: !!beeInstance,
155
+ isDragDrop,
156
+ currentTab,
157
+ activeTab,
158
+ currentTabData: !!currentTabData,
159
+ templateContent: currentTabData?.[activeTab]?.[`template-content`] || 'EMPTY',
160
+ contentProp: content || 'EMPTY',
161
+ getCurrentContent: getCurrentContent || 'EMPTY',
162
+ beeContentState: beeContent || 'EMPTY'
163
+ });
164
+
165
+ if (beeInstance && isDragDrop) {
166
+ console.log('🔍 Using BEE editor path for tag extraction');
167
+
168
+ // For BEE editor, trigger save first to ensure latest content is captured
169
+ console.log('🔍 Triggering BEE save to capture latest content...');
170
+ beeInstance.save();
171
+
172
+ // Get content from formData (which should have the latest BEE content)
173
+ const currentTabData = formData[currentTab - 1];
174
+ const activeTab = currentTabData?.activeTab;
175
+ const templateContent = currentTabData?.[activeTab]?.[`template-content`];
176
+
177
+ console.log('🔍 BEE content sources:', {
178
+ templateContent: templateContent || 'EMPTY',
179
+ beeContent: beeContent || 'EMPTY',
180
+ content: content || 'EMPTY'
181
+ });
182
+
183
+ // Use template content from formData if available, otherwise fall back to other sources
184
+ const beeContentToUse = templateContent || beeContent || content;
185
+
186
+ if (beeContentToUse && beeContentToUse.trim() !== '') {
187
+ console.log('🔍 Using BEE content for tag extraction:', beeContentToUse.substring(0, 100) + '...');
188
+ const payloadContent = convert(beeContentToUse, GLOBAL_CONVERT_OPTIONS);
189
+ console.log('🔍 Converted BEE content for tag extraction:', payloadContent || 'EMPTY');
190
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
191
+ } else {
192
+ console.log('🔍 No BEE content available in any source');
193
+ // If no content available, wait a bit for the save to complete and try again
194
+ setTimeout(() => {
195
+ const updatedTemplateContent = formData[currentTab - 1]?.[activeTab]?.[`template-content`];
196
+ if (updatedTemplateContent && updatedTemplateContent.trim() !== '') {
197
+ console.log('🔍 BEE content now available after save:', updatedTemplateContent.substring(0, 100) + '...');
198
+ const payloadContent = convert(updatedTemplateContent, GLOBAL_CONVERT_OPTIONS);
199
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
200
+ } else {
201
+ console.log('🔍 Still no BEE content, using empty content for tag extraction');
202
+ actions.extractTagsRequested(formData['template-subject'] || '', '');
203
+ }
204
+ }, 1000); // Wait 1 second for save to complete
205
+ }
206
+ } else {
207
+ console.log('🔍 Using non-BEE editor path for tag extraction');
208
+ console.log('🔍 Non-BEE content sources:', {
209
+ getCurrentContent: getCurrentContent || 'EMPTY',
210
+ contentProp: content || 'EMPTY'
211
+ });
212
+ // For non-BEE editor, use content prop directly
213
+ const payloadContent = convert(
214
+ getCurrentContent,
215
+ GLOBAL_CONVERT_OPTIONS
216
+ );
217
+ console.log('🔍 Converted content for tag extraction:', payloadContent || 'EMPTY');
218
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
219
+ }
220
+
108
221
  actions.fetchTestCustomersRequested();
109
222
  actions.fetchTestGroupsRequested();
110
- const payloadContent = convert(
111
- content,
112
- GLOBAL_CONVERT_OPTIONS
113
- );
114
- actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
115
223
  }
116
- }, [show, content, formData]);
224
+ }, [show, beeInstance, currentTab]);
225
+
226
+ // Single useEffect to handle BEE content updates without causing loops
227
+ useEffect(() => {
228
+ const currentTabData = formData[currentTab - 1];
229
+ const activeTab = currentTabData?.activeTab;
230
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
231
+
232
+ if (isDragDrop && currentTabData?.[activeTab]?.[`template-content`]) {
233
+ const newBeeContent = currentTabData[activeTab][`template-content`];
234
+ if (newBeeContent && newBeeContent.trim() !== '' && newBeeContent !== previousBeeContentRef.current) {
235
+ // Only update if content actually changed to prevent loops
236
+ previousBeeContentRef.current = newBeeContent;
237
+ setBeeContent(newBeeContent);
238
+ setPreviewDataHtml({
239
+ resolvedBody: newBeeContent,
240
+ resolvedTitle: formData['template-subject'] || ''
241
+ });
242
+ }
243
+ }
244
+ }, [formData, currentTab]);
245
+
246
+ // Cleanup effect to reset ref when slidebox closes
247
+ useEffect(() => {
248
+ if (!show) {
249
+ previousBeeContentRef.current = '';
250
+ setBeeContent('');
251
+ setPreviewDataHtml('');
252
+ }
253
+ }, [show]);
117
254
 
118
255
  useEffect(() => {
119
256
  if (previewData) {
@@ -288,7 +425,7 @@ const TestAndPreviewSlidebox = (props) => {
288
425
  // Handle update preview
289
426
  const handleUpdatePreview = async () => {
290
427
  // For BEE editor, ensure content is saved first
291
- const currentTabData = formData[formData.currentTab - 1];
428
+ const currentTabData = formData[currentTab - 1];
292
429
  const activeTab = currentTabData?.activeTab;
293
430
 
294
431
  // Get latest content from BEE editor if needed
@@ -304,7 +441,7 @@ const TestAndPreviewSlidebox = (props) => {
304
441
  const payload = {
305
442
  channel: EMAIL,
306
443
  messageTitle: formData['template-subject'],
307
- messageBody: htmlFile || content,
444
+ messageBody: htmlFile || getCurrentContent,
308
445
  resolvedTags: customValues,
309
446
  userId: selectedCustomer?.customerId,
310
447
  };
@@ -314,11 +451,11 @@ const TestAndPreviewSlidebox = (props) => {
314
451
  return;
315
452
  }
316
453
 
317
- // Use content from formData for non-BEE editor
454
+ // Use current content for non-BEE editor
318
455
  const payload = {
319
456
  channel: EMAIL,
320
457
  messageTitle: formData['template-subject'],
321
- messageBody: content,
458
+ messageBody: getCurrentContent,
322
459
  resolvedTags: customValues,
323
460
  userId: selectedCustomer?.customerId,
324
461
  };
@@ -350,7 +487,7 @@ const TestAndPreviewSlidebox = (props) => {
350
487
  ...INITIAL_PAYLOAD,
351
488
  emailMessageContent: {
352
489
  channel: EMAIL,
353
- messageBody: previewData?.resolvedBody || content,
490
+ messageBody: previewData?.resolvedBody || getCurrentContent,
354
491
  messageSubject: previewData?.resolvedTitle || formData['template-subject'],
355
492
  },
356
493
  }, messageMetaConfigId, (response) => {
@@ -442,7 +579,7 @@ const TestAndPreviewSlidebox = (props) => {
442
579
  formData={formData}
443
580
  isUpdatingPreview={isUpdatingPreview}
444
581
  previewDataHtml={previewDataHtml}
445
- content={content}
582
+ content={getCurrentContent}
446
583
  formatMessage={formatMessage}
447
584
  PreviewChrome={PreviewChrome}
448
585
  />
@@ -582,6 +719,7 @@ TestAndPreviewSlidebox.propTypes = {
582
719
  prefilledValues: PropTypes.object,
583
720
  isSendingTestMessage: PropTypes.bool.isRequired,
584
721
  beeInstance: PropTypes.object.isRequired,
722
+ currentTab: PropTypes.number,
585
723
  };
586
724
 
587
725
  TestAndPreviewSlidebox.defaultProps = {
@@ -589,6 +727,7 @@ TestAndPreviewSlidebox.defaultProps = {
589
727
  currentChannel: EMAIL,
590
728
  messageMetaConfigId: null,
591
729
  prefilledValues: {},
730
+ currentTab: 1,
592
731
  };
593
732
 
594
733
  // Redux connection
@@ -163,7 +163,9 @@ export function SlideBoxContent(props) {
163
163
  showTestAndPreviewSlidebox,
164
164
  handleTestAndPreview,
165
165
  handleCloseTestAndPreview,
166
+ isTestAndPreviewMode,
166
167
  } = props;
168
+ console.log('📥 SlideBoxContent received isTestAndPreviewMode:', isTestAndPreviewMode);
167
169
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
168
170
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
169
171
  const creativesLocationProps = {
@@ -594,7 +596,7 @@ export function SlideBoxContent(props) {
594
596
  />
595
597
  )}
596
598
 
597
- {isEmailCreate && (
599
+ {isEmailCreate && (
598
600
  <EmailWrapper
599
601
  key="creatives-email-wrapper"
600
602
  date={new Date().getMilliseconds()}
@@ -626,7 +628,8 @@ export function SlideBoxContent(props) {
626
628
  isLoyaltyModule={isLoyaltyModule}
627
629
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
628
630
  handleTestAndPreview={handleTestAndPreview}
629
- handleCloseTestAndPreview={handleCloseTestAndPreview}
631
+ handleCloseTestAndPreview={handleCloseTestAndPreview}
632
+ isTestAndPreviewMode={isTestAndPreviewMode}
630
633
  />
631
634
  )}
632
635
  {(isEditEmailWithId || isEmailEditWithContent) && (
@@ -660,6 +663,10 @@ export function SlideBoxContent(props) {
660
663
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
661
664
  handleTestAndPreview={handleTestAndPreview}
662
665
  handleCloseTestAndPreview={handleCloseTestAndPreview}
666
+ isTestAndPreviewMode={(() => {
667
+ console.log('📤 SlideBoxContent passing isTestAndPreviewMode:', isTestAndPreviewMode);
668
+ return isTestAndPreviewMode;
669
+ })()}
663
670
  />
664
671
  )}
665
672
  {isEditMPush && (
@@ -1055,6 +1062,7 @@ SlideBoxContent.propTypes = {
1055
1062
  hostName: PropTypes.string,
1056
1063
  showTestAndPreviewSlidebox: PropTypes.bool,
1057
1064
  handleTestAndPreview: PropTypes.func,
1058
- handleCloseTestAndPreview: PropTypes.func
1065
+ handleCloseTestAndPreview: PropTypes.func,
1066
+ isTestAndPreviewMode: PropTypes.bool
1059
1067
  };
1060
1068
  export default SlideBoxContent;
@@ -103,6 +103,7 @@ export class Creatives extends React.Component {
103
103
  activeFormBuilderTab: constants.ANDROID,
104
104
  // NEW: Test and Preview feature state
105
105
  showTestAndPreviewSlidebox: false,
106
+ isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
106
107
  };
107
108
  this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
108
109
  this.creativesTemplateSteps = {
@@ -877,7 +878,7 @@ export class Creatives extends React.Component {
877
878
  const { Templates, templateData: templateDataProps } = this.props;
878
879
  const selectedWhatsappAccount = Templates?.selectedWhatsappAccount;
879
880
  const { accountDetails: selectedAccountDetails, accountId: selectedAccountId } = templateDataProps || {};
880
- const accountDetails = (selectedWhatsappAccount ? selectedWhatsappAccount : selectedAccountDetails);
881
+ const accountDetails = (selectedWhatsappAccount || selectedAccountDetails);
881
882
  const accountId = selectedAccountId || (selectedWhatsappAccount?.id || '');
882
883
  const { versions } = template.value;
883
884
  const {
@@ -917,13 +918,12 @@ export class Creatives extends React.Component {
917
918
  //to send {{unsubscribe}} to backend inside varMapped
918
919
  const unsubscribeRegex = /Click {{unsubscribe}} to unsubscribe/g;
919
920
  if (
920
- languages[0].content?.match(unsubscribeRegex)?.length > 0 &&
921
- Object.keys(varMapped)?.every(
921
+ languages[0].content?.match(unsubscribeRegex)?.length > 0
922
+ && Object.keys(varMapped)?.every(
922
923
  (key) => !key?.includes("_unsubscribe")
923
924
  )
924
925
  ) {
925
- varMapped[`{{${Object.keys(varMapped).length + 1}}}_unsubscribe`] =
926
- "{{unsubscribe}}";
926
+ varMapped[`{{${Object.keys(varMapped).length + 1}}}_unsubscribe`] = "{{unsubscribe}}";
927
927
  }
928
928
  const whatsappMedia = {
929
929
  header,
@@ -1255,14 +1255,26 @@ export class Creatives extends React.Component {
1255
1255
  this.setState({ isDiscardMessage: true });
1256
1256
  }
1257
1257
 
1258
+
1259
+
1258
1260
  // NEW: Handler for Test and Preview button
1259
1261
  handleTestAndPreview = () => {
1260
- this.setState({ showTestAndPreviewSlidebox: true });
1262
+ console.log('🔓 CreativesContainer handleTestAndPreview called');
1263
+ console.log('🔓 Setting isTestAndPreviewMode to true');
1264
+ this.setState({
1265
+ showTestAndPreviewSlidebox: true,
1266
+ isTestAndPreviewMode: true, // Set flag to prevent validation
1267
+ });
1261
1268
  }
1262
1269
 
1263
1270
  // NEW: Handler to close Test and Preview slidebox
1264
1271
  handleCloseTestAndPreview = () => {
1265
- this.setState({ showTestAndPreviewSlidebox: false });
1272
+ console.log('🔒 CreativesContainer handleCloseTestAndPreview called');
1273
+ console.log('🔒 Setting isTestAndPreviewMode to false');
1274
+ this.setState({
1275
+ showTestAndPreviewSlidebox: false,
1276
+ isTestAndPreviewMode: false, // Reset flag when closing
1277
+ });
1266
1278
  }
1267
1279
 
1268
1280
  shouldShowFooter = () => {
@@ -1300,8 +1312,8 @@ export class Creatives extends React.Component {
1300
1312
  }
1301
1313
  if (channel === constants.MOBILE_PUSH
1302
1314
  && ((slidBoxContent === 'createTemplate' && !isEmpty(mobilePushCreateMode))
1303
- || (slidBoxContent === 'editTemplate' && (currentStep === 'modeSelection' || isFullMode))) &&
1304
- templateNameExists) {
1315
+ || (slidBoxContent === 'editTemplate' && (currentStep === 'modeSelection' || isFullMode)))
1316
+ && templateNameExists) {
1305
1317
  showFooter = true;
1306
1318
  }
1307
1319
 
@@ -1312,8 +1324,8 @@ export class Creatives extends React.Component {
1312
1324
  }
1313
1325
 
1314
1326
  if (showFooter) {
1315
- if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent') ||
1316
- ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
1327
+ if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
1328
+ || ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
1317
1329
  showFooter = showFooter && !this.state.isLoadingContent;
1318
1330
  } else if (slidBoxContent === "editTemplate"
1319
1331
  && ([constants.SMS, constants.WECHAT, constants.EMAIL].includes(channel)
@@ -1378,7 +1390,7 @@ export class Creatives extends React.Component {
1378
1390
  onBlur={() => { this.setState({ isEditName: false }, () => { this.showTemplateName({ formData, onFormDataChange }); }); }}
1379
1391
  onChange={(ev) => {
1380
1392
  const { value } = ev.currentTarget;
1381
- const isEmptyTemplateName = value.trim() ? false : true;
1393
+ const isEmptyTemplateName = !value.trim();
1382
1394
 
1383
1395
  const newFormData = { ...formData, 'template-name': value, 'isTemplateNameEdited': true };
1384
1396
  this.setState({ isTemplateNameEmpty: isEmptyTemplateName });
@@ -1405,7 +1417,6 @@ export class Creatives extends React.Component {
1405
1417
  }
1406
1418
 
1407
1419
  showLiquidErrorInFooter = (errorMessagesFromFormBuilder, currentFormBuilderTab) => {
1408
-
1409
1420
  this.setState({
1410
1421
  isLiquidValidationError: !isEmpty(get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, [])) || !isEmpty(get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, [])),
1411
1422
  liquidErrorMessage: errorMessagesFromFormBuilder,
@@ -1476,6 +1487,7 @@ export class Creatives extends React.Component {
1476
1487
  liquidErrorMessage,
1477
1488
  activeFormBuilderTab,
1478
1489
  showTestAndPreviewSlidebox,
1490
+ isTestAndPreviewMode,
1479
1491
  } = this.state;
1480
1492
  const {
1481
1493
  isFullMode,
@@ -1498,8 +1510,7 @@ export class Creatives extends React.Component {
1498
1510
  isLoyaltyModule,
1499
1511
  loyaltyMetaData = {},
1500
1512
  } = this.props;
1501
- const mapTemplateCreate =
1502
- slidBoxContent === "createTemplate"
1513
+ const mapTemplateCreate = slidBoxContent === "createTemplate"
1503
1514
  && weChatTemplateType === MAP_TEMPLATE
1504
1515
  && templateStep !== "modeSelection";
1505
1516
  const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
@@ -1606,6 +1617,10 @@ export class Creatives extends React.Component {
1606
1617
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1607
1618
  handleTestAndPreview={this.handleTestAndPreview}
1608
1619
  handleCloseTestAndPreview={this.handleCloseTestAndPreview}
1620
+ isTestAndPreviewMode={(() => {
1621
+ console.log('📤 CreativesContainer passing isTestAndPreviewMode:', this.state.isTestAndPreviewMode);
1622
+ return this.state.isTestAndPreviewMode;
1623
+ })()}
1609
1624
  />
1610
1625
  )}
1611
1626
  footer={this.shouldShowFooter() ? (
@@ -17,6 +17,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click rcs
17
17
  handleCloseTestAndPreview={[Function]}
18
18
  handleTestAndPreview={[Function]}
19
19
  hostName=""
20
+ isTestAndPreviewMode={false}
20
21
  loyaltyMetaData={
21
22
  Object {
22
23
  "actionName": "SEND_COMMUNICATION_ACTION",
@@ -102,6 +103,7 @@ exports[`Test SlideBoxContent container campaign message, add creative click wha
102
103
  handleCloseTestAndPreview={[Function]}
103
104
  handleTestAndPreview={[Function]}
104
105
  hostName=""
106
+ isTestAndPreviewMode={false}
105
107
  loyaltyMetaData={
106
108
  Object {
107
109
  "actionName": "SEND_COMMUNICATION_ACTION",
@@ -187,6 +189,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
187
189
  handleCloseTestAndPreview={[Function]}
188
190
  handleTestAndPreview={[Function]}
189
191
  hostName=""
192
+ isTestAndPreviewMode={false}
190
193
  loyaltyMetaData={
191
194
  Object {
192
195
  "actionName": "SEND_COMMUNICATION_ACTION",
@@ -284,6 +287,7 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
284
287
  handleCloseTestAndPreview={[Function]}
285
288
  handleTestAndPreview={[Function]}
286
289
  hostName=""
290
+ isTestAndPreviewMode={false}
287
291
  loyaltyMetaData={
288
292
  Object {
289
293
  "actionName": "SEND_COMMUNICATION_ACTION",
@@ -381,6 +385,7 @@ exports[`Test SlideBoxContent container it should clear the url, on channel chan
381
385
  handleCloseTestAndPreview={[Function]}
382
386
  handleTestAndPreview={[Function]}
383
387
  hostName=""
388
+ isTestAndPreviewMode={false}
384
389
  loyaltyMetaData={
385
390
  Object {
386
391
  "actionName": "SEND_COMMUNICATION_ACTION",
@@ -89,6 +89,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
89
89
  addLanguageType: '',
90
90
  startValidation: false,
91
91
  saveForm: false,
92
+ showTestAndPreviewSlidebox: false,
93
+ isTestAndPreviewMode: false, // Add flag to prevent validation during Test & Preview
92
94
  };
93
95
 
94
96
  this.isTagLoaded = false;
@@ -239,6 +241,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
239
241
  }
240
242
 
241
243
  componentWillReceiveProps(nextProps) {
244
+ console.log('🔄 componentWillReceiveProps called - isTestAndPreviewMode:', this.state.isTestAndPreviewMode);
245
+ console.log('📥 Email received isTestAndPreviewMode prop:', nextProps.isTestAndPreviewMode);
246
+
242
247
  // if (this.props.location.query.type === 'embedded') {
243
248
  // this.showNext();
244
249
  // }
@@ -246,7 +251,13 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
246
251
  if (isFullMode && isGetFormData && !_.isEqual(isGetFormData, this.props.isGetFormData) && !this.state.isDragDrop) {
247
252
  //only for ck editor
248
253
  //when create button is clicked in full mode
254
+ // Don't start validation if we're in Test & Preview mode
255
+ if (!nextProps.isTestAndPreviewMode) {
256
+ console.log('✅ componentWillReceiveProps calling startValidation - isTestAndPreviewMode:', nextProps.isTestAndPreviewMode);
249
257
  this.startValidation(true);
258
+ } else {
259
+ console.log('🚫 componentWillReceiveProps blocked startValidation - Test & Preview mode active');
260
+ }
250
261
  }
251
262
  if (this.state.languageDataSet && nextProps.Templates.selectedEmailLayout && nextProps.Templates.selectedEmailLayout !== '' && !_.isEqual(this.props.Templates.selectedEmailLayout, nextProps.Templates.selectedEmailLayout )) {
252
263
  this.setNewLanguageContent(nextProps.Templates.selectedEmailLayout);
@@ -801,6 +812,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
801
812
  }
802
813
 
803
814
  getFormData = (e, value) => {
815
+ // Don't run validation if we're in Test & Preview mode
816
+ if (this.props.isTestAndPreviewMode) {
817
+ console.log('🚫 getFormData blocked - Test & Preview mode active');
818
+ return;
819
+ }
820
+
821
+ console.log('✅ getFormData called - isTestAndPreviewMode:', this.props.isTestAndPreviewMode);
822
+
804
823
  this.setState({getFormDataValue: value, gettingFormData: true}, () => {
805
824
  this.saveValidationData();
806
825
  });
@@ -1017,6 +1036,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1017
1036
  });
1018
1037
  }
1019
1038
  startValidation = (shouldSave) => {
1039
+ // Don't start validation if we're in Test & Preview mode
1040
+ if (this.props.isTestAndPreviewMode) {
1041
+ console.log('🚫 startValidation blocked - Test & Preview mode active');
1042
+ return;
1043
+ }
1044
+
1045
+ console.log('✅ startValidation called - shouldSave:', shouldSave, 'isTestAndPreviewMode:', this.props.isTestAndPreviewMode);
1046
+
1020
1047
  if (!this.state.startValidation && shouldSave) {
1021
1048
  this.setState({startValidation: true});
1022
1049
  }
@@ -1025,6 +1052,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1025
1052
  this.setState({startValidation: false}, this.props.onValidationFail);
1026
1053
  }
1027
1054
  saveValidationData = () => {
1055
+ // Don't run validation if we're in Test & Preview mode
1056
+ if (this.props.isTestAndPreviewMode) {
1057
+ console.log('🚫 saveValidationData blocked - Test & Preview mode active');
1058
+ return;
1059
+ }
1060
+
1061
+ console.log('✅ saveValidationData called - isTestAndPreviewMode:', this.props.isTestAndPreviewMode);
1062
+
1028
1063
  let saveCount = 0;
1029
1064
  const isBeeEnable = this.checkBeeEditorAllowedForLibrary();
1030
1065
  this.setState({saveEdmDataMode: 'validation', saveCount: 0, cmsDataCount: 0}, () => {
@@ -2107,7 +2142,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2107
2142
  const isEdmSupport = (this.props.location.query.isEdmSupport !== "false") || false;
2108
2143
 
2109
2144
  //const data = {"base":{"subject":"deded","html_content":"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html> <head> \t<title>Scheduled Report</title> \t<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\"/> \t<style type=\"text/css\">.container-main p{line-height: 1.6;}@media screen and (max-width: 480px){a.brand{font-size: 35px;}}@media screen and (max-width: 480px){.container-main a{text-align: center;}a.brand{text-align: center;}}a.brand img{vertical-align: middle; padding: 0 8px 0 0; width: 250px;}@media screen and (max-width: 480px){a.brand img{width: 220px !important;}}@media screen and (max-width: 480px){.container-content{padding: 15px 20px; font-size: 12px !important;} .email-footer{font-size: 12px !important;}}.container-content table{border-collapse: collapse;}.container-content table tr td p{margin: 5px;}.container-content table tr td p span{font-weight: bold; padding: 0 3px 0 0;}@media screen and (max-width: 480px){a.btn-view-reports{margin: 25px auto 10px;}}a.btn-view-reports:hover{background: grey; color: #fff;}.email-footer p{text-align: center; font-size: 12px; color: grey;}.email-footer p a{color: blue; cursor: pointer;}.email-footer p a:hover{color: grey;} \t</style> </head> <body><center>\n\t\t\t\t\t\t\t\t\t\tIf you have difficulties viewing this mail, click\n\t\t\t\t\t\t\t\t\t\t<a href=\"https://nightly.capillary.in/business_controller/campaigns/emails/links/view.php?utrack={{user_id_b64}}&mtrack={{outbox_id_b64}}\" style = \"text-decoration: underline;color: #369;\" target=\"_blank\">here</a><br/>\n\t\t\t\t\t\t\t\t\t</center> <table class=\"container-main\" style=\"background:#eeeeee; color:#000000; font-family:'Open Sans',sans-serif; font-size:16px; font-weight:400; margin:0 auto; max-width:978px; padding:15px; width:100%\"> \t<tbody> \t\t<tr> \t\t\t<td> \t\t\t<table class=\"email-header\" style=\"background:#ffffff; margin:0 0 5px; padding:17px 0; width:100%\"> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td style=\"width:100%\"><a class=\"brand\" href=\"#\" style=\"display: table; margin: 0 auto; text-decoration: none; font-size: 37px; color: grey;\"><CapImage alt=\"Capillary Technologies\" src=\"https://s3.amazonaws.com/fileservice.in/intouch_creative_assets/60221e2020ba572f6787.png\" /> </a></td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<div class=\"container-content\" style=\"background:#ffffff; padding:20px 35px\"> \t\t\t<p>Hi Ashish Karan,</p> \t\t\t<p>You&#39;ve received a new scheduled report. {{unsubscribe}}</p> \t\t\t<table> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Org Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>autotest1</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Scheduled Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>Schedule Test</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Time Period: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>1st Jan, 2017 to 24th Sep, 2017</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Report Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>redDart Report</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<p style=\"font-size:15px; margin-top:25px\">By clicking &quot;View Report&quot; you will be redirected to Capillary Analytics to view the automated report.</p> \t\t\t<a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91?snapshot=59c8bce750f4e75ec8b0d24c\" style=\"background: #009e0f; text-align: center; color: #fff; font-size: 16px; padding: 10px 25px; cursor: pointer; text-decoration: none; display: block; width: 120px; margin: 25px auto 15px;\" target=\"_blank\">View Report</a></div> \t\t\t<div class=\"email-footer\"> \t\t\t<p style=\"color:grey; font-size:12px; text-align:center\">You&#39;ve received this mail because you subscribed to Schedule Test schedule of redDart Report. <a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91/schedule/59c8bce750f4e75ec8b0d24c/unsubscribeSchedule\" style=\"color: blue; cursor: pointer;\" target=\"_blank\">Unsubscribe</a></p> \t\t\t<p><a href=\"http://capillarytech.com/privacy-policy/\" target=\"_blank\">Privacy Policy</a> | <a href=\"http://capillarytech.com/about-us/\" target=\"_blank\">About Capillary</a></p> \t\t\t</div> \t\t\t</td> \t\t</tr> \t</tbody> </table> </body> </html> ","is_drag_drop":false,"drag_drop_id":null},"secondary_templates":[{"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":false,"drag_drop_id":null,"scope":null,"tag":null,"is_default":null,"html_content":"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html> <head> \t<title>Scheduled Report</title> \t<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\"/> \t<style type=\"text/css\">.container-main p{line-height: 1.6;}@media screen and (max-width: 480px){a.brand{font-size: 35px;}}@media screen and (max-width: 480px){.container-main a{text-align: center;}a.brand{text-align: center;}}a.brand img{vertical-align: middle; padding: 0 8px 0 0; width: 250px;}@media screen and (max-width: 480px){a.brand img{width: 220px !important;}}@media screen and (max-width: 480px){.container-content{padding: 15px 20px; font-size: 12px !important;} .email-footer{font-size: 12px !important;}}.container-content table{border-collapse: collapse;}.container-content table tr td p{margin: 5px;}.container-content table tr td p span{font-weight: bold; padding: 0 3px 0 0;}@media screen and (max-width: 480px){a.btn-view-reports{margin: 25px auto 10px;}}a.btn-view-reports:hover{background: grey; color: #fff;}.email-footer p{text-align: center; font-size: 12px; color: grey;}.email-footer p a{color: blue; cursor: pointer;}.email-footer p a:hover{color: grey;} \t</style> </head> <body><center>\n\t\t\t\t\t\t\t\t\t\tIf you have difficulties viewing this mail, click\n\t\t\t\t\t\t\t\t\t\t<a href=\"https://nightly.capillary.in/business_controller/campaigns/emails/links/view.php?utrack={{user_id_b64}}&mtrack={{outbox_id_b64}}\" style = \"text-decoration: underline;color: #369;\" target=\"_blank\">here</a><br/>\n\t\t\t\t\t\t\t\t\t</center> <table class=\"container-main\" style=\"background:#eeeeee; color:#000000; font-family:'Open Sans',sans-serif; font-size:16px; font-weight:400; margin:0 auto; max-width:978px; padding:15px; width:100%\"> \t<tbody> \t\t<tr> \t\t\t<td> \t\t\t<table class=\"email-header\" style=\"background:#ffffff; margin:0 0 5px; padding:17px 0; width:100%\"> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td style=\"width:100%\"><a class=\"brand\" href=\"#\" style=\"display: table; margin: 0 auto; text-decoration: none; font-size: 37px; color: grey;\"><CapImage alt=\"Capillary Technologies\" src=\"https://s3.amazonaws.com/fileservice.in/intouch_creative_assets/60221e2020ba572f6787.png\" /> </a></td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<div class=\"container-content\" style=\"background:#ffffff; padding:20px 35px\"> \t\t\t<p>Hi Ashish Karan,</p> \t\t\t<p>You&#39;ve received a new scheduled report. {{unsubscribe}}</p> \t\t\t<table> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Org Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>autotest1</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Scheduled Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>Schedule Test</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Time Period: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>1st Jan, 2017 to 24th Sep, 2017</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Report Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>redDart Report</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<p style=\"font-size:15px; margin-top:25px\">By clicking &quot;View Report&quot; you will be redirected to Capillary Analytics to view the automated report.</p> \t\t\t<a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91?snapshot=59c8bce750f4e75ec8b0d24c\" style=\"background: #009e0f; text-align: center; color: #fff; font-size: 16px; padding: 10px 25px; cursor: pointer; text-decoration: none; display: block; width: 120px; margin: 25px auto 15px;\" target=\"_blank\">View Report</a></div> \t\t\t<div class=\"email-footer\"> \t\t\t<p style=\"color:grey; font-size:12px; text-align:center\">You&#39;ve received this mail because you subscribed to Schedule Test schedule of redDart Report. <a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91/schedule/59c8bce750f4e75ec8b0d24c/unsubscribeSchedule\" style=\"color: blue; cursor: pointer;\" target=\"_blank\">Unsubscribe</a></p> \t\t\t<p><a href=\"http://capillarytech.com/privacy-policy/\" target=\"_blank\">Privacy Policy</a> | <a href=\"http://capillarytech.com/about-us/\" target=\"_blank\">About Capillary</a></p> \t\t\t</div> \t\t\t</td> \t\t</tr> \t</tbody> </table> </body> </html> ","secondary_template_id":"9500","is_base_template":1,"language_name":"English","language":"English","lang_id":"69"}],"edit":true,"tags":[]};
2110
- // const data = {edit: true, "base":{"subject":"testsubject","html_content":"<html> <head> \t<meta charset=\"utf-8\" /> \t<title>Aster Secure</title> \t<style type=\"text/css\">#outlook a { padding: 0; } body { width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;} .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } #backgroundTable { margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; } img { outline: none; text-decoration: none; border: none; -ms-interpolation-mode: bicubic; } a img { border: none; } .image_fix { display: block; } p { margin: 0px 0px !important; } table td { border-collapse: collapse; } table { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } table[class=full] { width: 100%; clear: both; } table[class=spacetable] { height: 176px; } table[class=spacetable1] { height: 431px; } table[class=spacetable2] { height: 50px; } table[class=spacetable3] { height: 55px; } \t @media only screen and (min-width: 320px) and (max-width: 540px) { a[href^=\"tel\"], a[href^=\"sms\"] { text-decoration: none; color: #ffffff; pointer-events: none; cursor: default; } .mobile_link a[href^=\"tel\"], .mobile_link a[href^=\"sms\"] { text-decoration: default; color: #ffffff !important; pointer-events: auto; cursor: default; } img[class=logo] { width: 132px!important; } img[class=shop] { width:53px!important; text-align: center!important; } table[class=innerlayer] { width: 300px !important; text-align: center; } img[class=spot] { width: 65px!important; } img[class=banner] { width: 290px !important; text-align: center; } img[class=banner1] { width: 229px!important; } img[class=click] { width:55px!important; } img[class=border] { width: 290px!important; } td[class=txtfont] { font-size:11px!important; height:50px!important; line-height: 15px!important; } \t span[class=txtfont] { font-size:9px!important; height:98px!important; line-height:23px!important; } \t td[class=txtfont1] { font-size:11px!important; height:40px!important; line-height: 14px!important; } img[class=left] { width:195px!important; } img[class=right] { width:46px!important; } \t \t td[class=txtfont3] { font-size:8px!important;} \ttd[class=txtfont2] { font-size:6px!important; line-height:9px!important; } td[class=txtbold] { font-size: 21px!important; } img[class=gap] { width:92px!important; } img[class=gap1] { width: 20px!important; } table[class=social] { width: 99% !important; } img[class=fb] { width:20px!important; } img[class=in] { width:21px!important; } img[class=tw] { width:20px!important; } img[class=pin] { width:41px!important; } \t img[class=and] { width:81px!important; } img[class=my] { width: 44px!important; } \t img[class=you] { width:21px!important; } img[class=store] { width:65px!important; } \t \t img[class=snap] { width:24px!important; } td[class=textlen] { height:52px!important; } \ttd[class=tdlen] \t{ \theight:35px!important;font-size: 10px !important; \t} \t\t\timg[class=a] { width: 42px!important; } \t\t\timg[class=b] { width: 22px!important; } \t\t\timg[class=c] { width: 72px!important; } \t\t\timg[class=d] { width: 50px!important; } \t\t\timg[class=e] { width: 56px!important; } \t\t\timg[class=f] { width: 56px!important; } \t\t\t} \t</style> </head> <body><center>\n\t\t\t\t\t\t\t\t\t\tIf you have difficulties viewing this mail, click\n\t\t\t\t\t\t\t\t\t\t<a href=\"https://nightly.capillary.in/business_controller/campaigns/emails/links/view.php?utrack={{user_id_b64}}&mtrack={{outbox_id_b64}}\" style = \"text-decoration: underline;color: #369;\" target=\"_blank\">here</a><br/>\n\t\t\t\t\t\t\t\t\t</center> <table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\"> \t<tbody> \t\t<tr> \t\t\t<td> \t\t\t<table align=\"center\" bgcolor=\"#fff\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\"> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">Shop at Aster Pharmacy this month and You could be the next lucky winner!</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><a href=\"#\" style=\"pointer-events:none;\"><CapImage class=\"banner\" src=\"https://s3-eu-west-1.amazonaws.com/fs.capillary.eu/intouch_creative_assets/890bdffee3b2322d8ec7.jpg\" style=\"border:none; display:block\" /></a></td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">To remove your email address from our mailing list , please click on {{unsubscribe}}</td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t</td> \t\t</tr> \t</tbody> </table> </body> </html> ","is_drag_drop":0,"drag_drop_id":null},"secondary_templates":[{"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":false,"drag_drop_id":null,"scope":null,"tag":null,"is_default":null,"html_content":"<html>\r\n<head>\r\n\t<meta charset=\"utf-8\" />\r\n\t<title>Aster Secure</title>\r\n\t<style type=\"text/css\">#outlook a { padding: 0; } body { width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;} .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } #backgroundTable { margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; } img { outline: none; text-decoration: none; border: none; -ms-interpolation-mode: bicubic; } a img { border: none; } .image_fix { display: block; } p { margin: 0px 0px !important; } table td { border-collapse: collapse; } table { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } table[class=full] { width: 100%; clear: both; } table[class=spacetable] { height: 176px; } table[class=spacetable1] { height: 431px; } table[class=spacetable2] { height: 50px; } table[class=spacetable3] { height: 55px; } \t @media only screen and (min-width: 320px) and (max-width: 540px) { a[href^=\"tel\"], a[href^=\"sms\"] { text-decoration: none; color: #ffffff; pointer-events: none; cursor: default; } .mobile_link a[href^=\"tel\"], .mobile_link a[href^=\"sms\"] { text-decoration: default; color: #ffffff !important; pointer-events: auto; cursor: default; } img[class=logo] { width: 132px!important; } img[class=shop] { width:53px!important; text-align: center!important; } table[class=innerlayer] { width: 300px !important; text-align: center; } img[class=spot] { width: 65px!important; } img[class=banner] { width: 290px !important; text-align: center; } img[class=banner1] { width: 229px!important; } img[class=click] { width:55px!important; } img[class=border] { width: 290px!important; } td[class=txtfont] { font-size:11px!important; height:50px!important; line-height: 15px!important; } \t span[class=txtfont] { font-size:9px!important; height:98px!important; line-height:23px!important; } \t td[class=txtfont1] { font-size:11px!important; height:40px!important; line-height: 14px!important; } img[class=left] { width:195px!important; } img[class=right] { width:46px!important; } \t \t td[class=txtfont3] { font-size:8px!important;} \ttd[class=txtfont2] { font-size:6px!important; line-height:9px!important; } td[class=txtbold] { font-size: 21px!important; } img[class=gap] { width:92px!important; } img[class=gap1] { width: 20px!important; } table[class=social] { width: 99% !important; } img[class=fb] { width:20px!important; } img[class=in] { width:21px!important; } img[class=tw] { width:20px!important; } img[class=pin] { width:41px!important; } \t img[class=and] { width:81px!important; } img[class=my] { width: 44px!important; } \t img[class=you] { width:21px!important; } img[class=store] { width:65px!important; } \t \t img[class=snap] { width:24px!important; } td[class=textlen] { height:52px!important; } \ttd[class=tdlen] \t{ \theight:35px!important;font-size: 10px !important; \t} \t\t\timg[class=a] { width: 42px!important; } \t\t\timg[class=b] { width: 22px!important; } \t\t\timg[class=c] { width: 72px!important; } \t\t\timg[class=d] { width: 50px!important; } \t\t\timg[class=e] { width: 56px!important; } \t\t\timg[class=f] { width: 56px!important; } \t\t\t}\r\n\t</style>\r\n</head>\r\n<body>\r\n<table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\">\r\n\t<tbody>\r\n\t\t<tr>\r\n\t\t\t<td>\r\n\t\t\t<table align=\"center\" bgcolor=\"#fff\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">Shop at Aster Pharmacy this month and You could be the next lucky winner!</td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td><a href=\"#\" style=\"pointer-events:none;\"><CapImage class=\"banner\" src=\"https://s3-eu-west-1.amazonaws.com/fs.capillary.eu/intouch_creative_assets/890bdffee3b2322d8ec7.jpg\" style=\"border:none; display:block\" /></a></td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">To remove your email address from our mailing list , please click on {{unsubscribe}}</td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t\t</td>\r\n\t\t</tr>\r\n\t</tbody>\r\n</table>\r\n</body>\r\n</html>\r\n","secondary_template_id":"9584","is_base_template":1,"language_name":"English","language":"English","lang_id":"69"}, {"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":false,"drag_drop_id":null,"scope":null,"tag":null,"is_default":null,"html_content":"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html> <head> \t<title>Scheduled Report</title> \t<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\"/> \t<style type=\"text/css\">.container-main p{line-height: 1.6;}@media screen and (max-width: 480px){a.brand{font-size: 35px;}}@media screen and (max-width: 480px){.container-main a{text-align: center;}a.brand{text-align: center;}}a.brand img{vertical-align: middle; padding: 0 8px 0 0; width: 250px;}@media screen and (max-width: 480px){a.brand img{width: 220px !important;}}@media screen and (max-width: 480px){.container-content{padding: 15px 20px; font-size: 12px !important;} .email-footer{font-size: 12px !important;}}.container-content table{border-collapse: collapse;}.container-content table tr td p{margin: 5px;}.container-content table tr td p span{font-weight: bold; padding: 0 3px 0 0;}@media screen and (max-width: 480px){a.btn-view-reports{margin: 25px auto 10px;}}a.btn-view-reports:hover{background: grey; color: #fff;}.email-footer p{text-align: center; font-size: 12px; color: grey;}.email-footer p a{color: blue; cursor: pointer;}.email-footer p a:hover{color: grey;} \t</style> </head> <body><center>\n\t\t\t\t\t\t\t\t\t\tIf you have difficulties viewing this mail, click\n\t\t\t\t\t\t\t\t\t\t<a href=\"https://nightly.capillary.in/business_controller/campaigns/emails/links/view.php?utrack={{user_id_b64}}&mtrack={{outbox_id_b64}}\" style = \"text-decoration: underline;color: #369;\" target=\"_blank\">here</a><br/>\n\t\t\t\t\t\t\t\t\t</center> <table class=\"container-main\" style=\"background:#eeeeee; color:#000000; font-family:'Open Sans',sans-serif; font-size:16px; font-weight:400; margin:0 auto; max-width:978px; padding:15px; width:100%\"> \t<tbody> \t\t<tr> \t\t\t<td> \t\t\t<table class=\"email-header\" style=\"background:#ffffff; margin:0 0 5px; padding:17px 0; width:100%\"> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td style=\"width:100%\"><a class=\"brand\" href=\"#\" style=\"display: table; margin: 0 auto; text-decoration: none; font-size: 37px; color: grey;\"><CapImage alt=\"Capillary Technologies\" src=\"https://s3.amazonaws.com/fileservice.in/intouch_creative_assets/60221e2020ba572f6787.png\" /> </a></td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<div class=\"container-content\" style=\"background:#ffffff; padding:20px 35px\"> \t\t\t<p>Hi Ashish Karan,</p> \t\t\t<p>You&#39;ve received a new scheduled report. {{unsubscribe}}</p> \t\t\t<table> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Org Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>autotest1</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Scheduled Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>Schedule Test</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Time Period: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>1st Jan, 2017 to 24th Sep, 2017</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><strong>Report Name: </strong></td> \t\t\t\t\t\t<td> \t\t\t\t\t\t<p>redDart Report</p> \t\t\t\t\t\t</td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t<p style=\"font-size:15px; margin-top:25px\">By clicking &quot;View Report&quot; you will be redirected to Capillary Analytics to view the automated report.</p> \t\t\t<a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91?snapshot=59c8bce750f4e75ec8b0d24c\" style=\"background: #009e0f; text-align: center; color: #fff; font-size: 16px; padding: 10px 25px; cursor: pointer; text-decoration: none; display: block; width: 120px; margin: 25px auto 15px;\" target=\"_blank\">View Report</a></div> \t\t\t<div class=\"email-footer\"> \t\t\t<p style=\"color:grey; font-size:12px; text-align:center\">You&#39;ve received this mail because you subscribed to Schedule Test schedule of redDart Report. <a href=\"https://nightly.capillary.in/analytics/v2/report/59c37820e626a10df78c8d91/schedule/59c8bce750f4e75ec8b0d24c/unsubscribeSchedule\" style=\"color: blue; cursor: pointer;\" target=\"_blank\">Unsubscribe</a></p> \t\t\t<p><a href=\"http://capillarytech.com/privacy-policy/\" target=\"_blank\">Privacy Policy</a> | <a href=\"http://capillarytech.com/about-us/\" target=\"_blank\">About Capillary</a></p> \t\t\t</div> \t\t\t</td> \t\t</tr> \t</tbody> </table> </body> </html> ","secondary_template_id":"9500","is_base_template":false,"language_name":"Hindi","language":"Hindi","lang_id":"151"},{"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":1,"drag_drop_id":"55acf47048a85bbf7681a35a","scope":null,"tag":null,"is_default":null,"html_content":"","secondary_template_id":"9500","is_base_template":0,"language_name":"Japanese","language":"Japanese","lang_id":"100"}]};
2145
+ // const data = {edit: true, "base":{"subject":"testsubject","html_content":"<html> <head> \t<meta charset=\"utf-8\" /> \t<title>Aster Secure</title> \t<style type=\"text/css\">#outlook a { padding: 0; } body { width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;} .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } #backgroundTable { margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; } img { outline: none; text-decoration: none; border: none; -ms-interpolation-mode: bicubic; } a img { border: none; } .image_fix { display: block; } p { margin: 0px 0px !important; } table td { border-collapse: collapse; } table { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } table[class=full] { width: 100%; clear: both; } table[class=spacetable] { height: 176px; } table[class=spacetable1] { height: 431px; } table[class=spacetable2] { height: 50px; } table[class=spacetable3] { height: 55px; } \t @media only screen and (min-width: 320px) and (max-width: 540px) { a[href^=\"tel\"], a[href^=\"sms\"] { text-decoration: none; color: #ffffff; pointer-events: none; cursor: default; } .mobile_link a[href^=\"tel\"], .mobile_link a[href^=\"sms\"] { text-decoration: default; color: #ffffff !important; pointer-events: auto; cursor: default; } img[class=logo] { width: 132px!important; } img[class=shop] { width:53px!important; text-align: center!important; } table[class=innerlayer] { width: 300px !important; text-align: center; } img[class=spot] { width: 65px!important; } img[class=banner] { width: 290px !important; text-align: center; } img[class=banner1] { width: 229px!important; } img[class=click] { width:55px!important; } img[class=border] { width: 290px!important; } td[class=txtfont] { font-size:11px!important; height:50px!important; line-height: 15px!important; } \t span[class=txtfont] { font-size:9px!important; height:98px!important; line-height:23px!important; } \t td[class=txtfont1] { font-size:11px!important; height:40px!important; line-height: 14px!important; } img[class=left] { width:195px!important; } img[class=right] { width:46px!important; } \t \t td[class=txtfont3] { font-size:8px!important;} \ttd[class=txtfont2] { font-size:6px!important; line-height:9px!important; } td[class=txtbold] { font-size: 21px!important; } img[class=gap] { width:92px!important; } img[class=gap1] { width: 20px!important; } table[class=social] { width: 99% !important; } img[class=fb] { width:20px!important; } img[class=in] { width:21px!important; } img[class=tw] { width:20px!important; } img[class=pin] { width:41px!important; } \t img[class=and] { width:81px!important; } img[class=my] { width: 44px!important; } \t img[class=you] { width:21px!important; } img[class=store] { width:65px!important; } \t \t img[class=snap] { width:24px!important; } td[class=textlen] { height:52px!important; } \ttd[class=tdlen] \t{ \theight:35px!important;font-size: 10px !important; \t} \t\t\timg[class=a] { width: 42px!important; } \t\t\timg[class=b] { width: 22px!important; } \t\t\timg[class=c] { width: 72px!important; } \t\t\timg[class=d] { width: 50px!important; } \t\t\timg[class=e] { width: 56px!important; } \t\t\timg[class=f] { width: 56px!important; } \t\t\t} \t</style> </head> <body><center>\n\t\t\t\t\t\t\t\t\t\tIf you have difficulties viewing this mail, click\n\t\t\t\t\t\t\t\t\t\t<a href=\"https://nightly.capillary.in/business_controller/campaigns/emails/links/view.php?utrack={{user_id_b64}}&mtrack={{outbox_id_b64}}\" style = \"text-decoration: underline;color: #369;\" target=\"_blank\">here</a><br/>\n\t\t\t\t\t\t\t\t\t</center> <table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\"> \t<tbody> \t\t<tr> \t\t\t<td> \t\t\t<table align=\"center\" bgcolor=\"#fff\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\"> \t\t\t\t<tbody> \t\t\t\t\t<tr> \t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">Shop at Aster Pharmacy this month and You could be the next lucky winner!</td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td><a href=\"#\" style=\"pointer-events:none;\"><CapImage class=\"banner\" src=\"https://s3-eu-west-1.amazonaws.com/fs.capillary.eu/intouch_creative_assets/890bdffee3b2322d8ec7.jpg\" style=\"border:none; display:block\" /></a></td> \t\t\t\t\t</tr> \t\t\t\t\t<tr> \t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">To remove your email address from our mailing list , please click on {{unsubscribe}}</td> \t\t\t\t\t</tr> \t\t\t\t</tbody> \t\t\t</table> \t\t\t</td> \t\t</tr> \t</tbody> </table> </body> </html> ","is_drag_drop":0,"drag_drop_id":null},"secondary_templates":[{"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":false,"drag_drop_id":null,"scope":null,"tag":null,"is_default":null,"html_content":"<html>\r\n<head>\r\n\t<meta charset=\"utf-8\" />\r\n\t<title>Aster Secure</title>\r\n\t<style type=\"text/css\">#outlook a { padding: 0; } body { width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;} .ExternalClass { width: 100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } #backgroundTable { margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; } img { outline: none; text-decoration: none; border: none; -ms-interpolation-mode: bicubic; } a img { border: none; } .image_fix { display: block; } p { margin: 0px 0px !important; } table td { border-collapse: collapse; } table { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; } table[class=full] { width: 100%; clear: both; } table[class=spacetable] { height: 176px; } table[class=spacetable1] { height: 431px; } table[class=spacetable2] { height: 50px; } table[class=spacetable3] { height: 55px; } \t @media only screen and (min-width: 320px) and (max-width: 540px) { a[href^=\"tel\"], a[href^=\"sms\"] { text-decoration: none; color: #ffffff; pointer-events: none; cursor: default; } .mobile_link a[href^=\"tel\"], .mobile_link a[href^=\"sms\"] { text-decoration: default; color: #ffffff !important; pointer-events: auto; cursor: default; } img[class=logo] { width: 132px!important; } img[class=shop] { width:53px!important; text-align: center!important; } table[class=innerlayer] { width: 300px !important; text-align: center; } img[class=spot] { width: 65px!important; } img[class=banner] { width: 290px !important; text-align: center; } img[class=banner1] { width: 229px!important; } img[class=click] { width:55px!important; } img[class=border] { width: 290px!important; } td[class=txtfont] { font-size:11px!important; height:50px!important; line-height: 15px!important; } \t span[class=txtfont] { font-size:9px!important; height:98px!important; line-height:23px!important; } \t td[class=txtfont1] { font-size:11px!important; height:40px!important; line-height: 14px!important; } img[class=left] { width:195px!important; } img[class=right] { width:46px!important; } \t \t td[class=txtfont3] { font-size:8px!important;} \ttd[class=txtfont2] { font-size:6px!important; line-height:9px!important; } td[class=txtbold] { font-size: 21px!important; } img[class=gap] { width:92px!important; } img[class=gap1] { width: 20px!important; } table[class=social] { width: 99% !important; } img[class=fb] { width:20px!important; } img[class=in] { width:21px!important; } img[class=tw] { width:20px!important; } img[class=pin] { width:41px!important; } \t img[class=and] { width:81px!important; } img[class=my] { width: 44px!important; } \t img[class=you] { width:21px!important; } img[class=store] { width:65px!important; } \t \t img[class=snap] { width:24px!important; } td[class=textlen] { height:52px!important; } \ttd[class=tdlen] \t{ \theight:35px!important;font-size: 10px !important; \t} \t\t\timg[class=a] { width: 42px!important; } \t\t\timg[class=b] { width: 22px!important; } \t\t\timg[class=c] { width: 72px!important; } \t\t\timg[class=d] { width: 50px!important; } \t\t\timg[class=e] { width: 56px!important; } \t\t\timg[class=f] { width: 56px!important; } \t\t\t}\r\n\t</style>\r\n</head>\r\n<body>\r\n<table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\">\r\n\t<tbody>\r\n\t\t<tr>\r\n\t\t\t<td>\r\n\t\t\t<table align=\"center\" bgcolor=\"#fff\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"outerlayer\" style=\"width:650px\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">Shop at Aster Pharmacy this month and You could be the next lucky winner!</td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td><a href=\"#\" style=\"pointer-events:none;\"><CapImage class=\"banner\" src=\"https://s3-eu-west-1.amazonaws.com/fs.capillary.eu/intouch_creative_assets/890bdffee3b2322d8ec7.jpg\" style=\"border:none; display:block\" /></a></td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t\t<tr>\r\n\t\t\t\t\t\t<td class=\"txtfont2\" height=\"40\" style=\"font-family: Verdana, Geneva, sans-serif; text-align:center; font-size:11px; color:gray; line-height:13px;\" width=\"600\">To remove your email address from our mailing list , please click on {{unsubscribe}}</td>\r\n\t\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t\t</td>\r\n\t\t</tr>\r\n\t</tbody>\r\n</table>\r\n</body>\r\n</html>\r\n","secondary_template_id":"9584","is_base_template":1,"language_name":"English","language":"English","lang_id":"69"}, {"is_preview_generated":null,"preview_url":null,"is_favourite":null,"is_drag_drop":1,"drag_drop_id":"55acf47048a85bbf7681a35a","scope":null,"tag":null,"is_default":null,"html_content":"","secondary_template_id":"9500","is_base_template":0,"language_name":"Japanese","language":"Japanese","lang_id":"100"}]};
2111
2146
 
2112
2147
  if (data && data.edit) {
2113
2148
  // const formData = {'0': {}};
@@ -2678,7 +2713,24 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2678
2713
  formData[0][selectedLanguages[0]]['template-content'];
2679
2714
  const previewSubject = formData['template-subject'];
2680
2715
  const testOrPreviewProps = {channel: EMAIL, content: previewContent, subject: previewSubject};
2681
- const { onPreviewContentClicked, onTestContentClicked } = this.props;
2716
+
2717
+ // Call our handler instead of the props methods to set the flag
2718
+ const handleClick = () => {
2719
+ console.log('🖱️ Button clicked - action:', action);
2720
+ if (action === 'TEST') {
2721
+ console.log('🔓 TEST button clicked - calling handleTestAndPreview');
2722
+ // For test action, open our Test & Preview slidebox
2723
+ this.handleTestAndPreview();
2724
+ } else {
2725
+ console.log('👁️ PREVIEW button clicked - calling onPreviewContentClicked');
2726
+ // For preview action, call the original method
2727
+ const { onPreviewContentClicked } = this.props;
2728
+ if (onPreviewContentClicked) {
2729
+ onPreviewContentClicked(testOrPreviewProps);
2730
+ }
2731
+ }
2732
+ };
2733
+
2682
2734
  return (
2683
2735
  <CapButton
2684
2736
  style={{
@@ -2687,7 +2739,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2687
2739
  padding: '0 6px',
2688
2740
  }}
2689
2741
  type="flat"
2690
- onClick={() => action === 'PREVIEW' ? onPreviewContentClicked(testOrPreviewProps) : onTestContentClicked(testOrPreviewProps)}
2742
+ onClick={handleClick}
2691
2743
  >
2692
2744
  <CapIcon type={action === 'PREVIEW' ? "eye" : "lab"}/>
2693
2745
  {action === 'PREVIEW' ? <FormattedMessage {...messages.preview} /> : <FormattedMessage {...messages.testMessage} />}
@@ -2715,10 +2767,12 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2715
2767
  content: html // Keep latest content in state
2716
2768
  };
2717
2769
  }, () => {
2718
- // Always trigger validation to ensure content is saved
2770
+ // Only trigger validation if we're not in Test & Preview mode
2771
+ if (!this.props.isTestAndPreviewMode) {
2719
2772
  this.setState({
2720
2773
  startValidation: true
2721
2774
  });
2775
+ }
2722
2776
  });
2723
2777
  }
2724
2778
 
@@ -2741,6 +2795,11 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2741
2795
  }
2742
2796
  const { showImageSelectionBox = false } = this.state;
2743
2797
  const showTestAndPreview = !showImageSelectionBox && getDefaultTags === 'outbound';
2798
+ console.log('🔍 showTestAndPreview conditions:', {
2799
+ showImageSelectionBox,
2800
+ getDefaultTags,
2801
+ showTestAndPreview
2802
+ });
2744
2803
  return (
2745
2804
  <div className="email-container">
2746
2805
  <CapSpin spinning={isLoading}>
@@ -2804,6 +2863,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2804
2863
  eventContextTags={this.props?.eventContextTags}
2805
2864
  forwardedTags={this.props?.forwardedTags}
2806
2865
  isLoyaltyModule={this.props?.isLoyaltyModule}
2866
+ isTestAndPreviewMode={this.state.isTestAndPreviewMode} // Add flag to prevent validation
2807
2867
  /> : ''}
2808
2868
  </Col>
2809
2869
  </Row>
@@ -2833,10 +2893,37 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2833
2893
  beeInstance={this.beeInstance}
2834
2894
  content={testAndPreviewContent}
2835
2895
  currentChannel={EMAIL}
2896
+ currentTab={this.state.currentTab}
2836
2897
  />
2837
2898
  </div>
2838
2899
  );
2839
2900
  }
2901
+
2902
+ handleCloseTestAndPreview = () => {
2903
+ console.log('🔒 Closing Test & Preview - setting isTestAndPreviewMode to false');
2904
+ this.setState({
2905
+ showTestAndPreviewSlidebox: false,
2906
+ isTestAndPreviewMode: false // Reset flag when closing
2907
+ });
2908
+ }
2909
+
2910
+ handleTestAndPreview = () => {
2911
+ console.log('🔓 handleTestAndPreview called - current isTestAndPreviewMode:', this.state.isTestAndPreviewMode);
2912
+ console.log('🔓 Setting isTestAndPreviewMode to true and opening slidebox');
2913
+ this.setState({
2914
+ showTestAndPreviewSlidebox: true,
2915
+ isTestAndPreviewMode: true // Set flag to prevent validation
2916
+ }, () => {
2917
+ console.log('🔓 State updated - new isTestAndPreviewMode:', this.state.isTestAndPreviewMode);
2918
+ });
2919
+ }
2920
+
2921
+ componentDidUpdate(prevProps, prevState) {
2922
+ // Debug flag changes
2923
+ if (prevState.isTestAndPreviewMode !== this.state.isTestAndPreviewMode) {
2924
+ console.log('🔄 isTestAndPreviewMode changed from', prevState.isTestAndPreviewMode, 'to', this.state.isTestAndPreviewMode);
2925
+ }
2926
+ }
2840
2927
  }
2841
2928
 
2842
2929
  Email.propTypes = {
@@ -55,6 +55,7 @@ const useEmailWrapper = ({
55
55
  showTestAndPreviewSlidebox,
56
56
  handleTestAndPreview,
57
57
  handleCloseTestAndPreview,
58
+ isTestAndPreviewMode,
58
59
  }) => {
59
60
  // State management
60
61
  const [templateName, setTemplateName] = useState('');
@@ -299,6 +300,7 @@ const useEmailWrapper = ({
299
300
  showTestAndPreviewSlidebox,
300
301
  handleTestAndPreview,
301
302
  handleCloseTestAndPreview,
303
+ isTestAndPreviewMode,
302
304
  }), [
303
305
  setIsLoadingContent,
304
306
  routeParams,
@@ -322,6 +324,7 @@ const useEmailWrapper = ({
322
324
  showTestAndPreviewSlidebox,
323
325
  handleTestAndPreview,
324
326
  handleCloseTestAndPreview,
327
+ isTestAndPreviewMode,
325
328
  ]);
326
329
 
327
330
  // Prepare props for CmsTemplatesComponent
@@ -61,6 +61,7 @@ const EmailWrapper = (props) => {
61
61
  showTestAndPreviewSlidebox,
62
62
  handleTestAndPreview,
63
63
  handleCloseTestAndPreview,
64
+ isTestAndPreviewMode,
64
65
  } = props;
65
66
 
66
67
  // Pass destructured props to the custom hook
@@ -113,6 +114,7 @@ const EmailWrapper = (props) => {
113
114
  showTestAndPreviewSlidebox,
114
115
  handleTestAndPreview,
115
116
  handleCloseTestAndPreview,
117
+ isTestAndPreviewMode,
116
118
  });
117
119
 
118
120
  // Render using the presentation component with data from the hook
@@ -174,6 +176,10 @@ EmailWrapper.propTypes = {
174
176
  onPreviewContentClicked: PropTypes.func,
175
177
  onTestContentClicked: PropTypes.func,
176
178
  editor: PropTypes.object,
179
+ showTestAndPreviewSlidebox: PropTypes.bool,
180
+ handleTestAndPreview: PropTypes.func,
181
+ handleCloseTestAndPreview: PropTypes.func,
182
+ isTestAndPreviewMode: PropTypes.bool,
177
183
  };
178
184
 
179
185
  const mapStateToProps = createStructuredSelector({