@capillarytech/creatives-library 8.0.288 → 8.0.290-alpha.0

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.
Files changed (52) hide show
  1. package/constants/unified.js +0 -1
  2. package/initialState.js +0 -2
  3. package/package.json +1 -1
  4. package/utils/common.js +5 -8
  5. package/utils/commonUtils.js +4 -85
  6. package/utils/tagValidations.js +84 -222
  7. package/utils/tests/commonUtil.test.js +461 -118
  8. package/utils/tests/tagValidations.test.js +280 -358
  9. package/v2Components/ErrorInfoNote/index.js +2 -5
  10. package/v2Components/FormBuilder/index.js +78 -161
  11. package/v2Components/FormBuilder/messages.js +0 -8
  12. package/v2Components/HtmlEditor/HTMLEditor.js +0 -5
  13. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -1
  14. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +0 -15
  15. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +1 -2
  16. package/v2Containers/Cap/mockData.js +0 -14
  17. package/v2Containers/Cap/reducer.js +3 -55
  18. package/v2Containers/Cap/tests/reducer.test.js +0 -102
  19. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -1
  20. package/v2Containers/CreativesContainer/index.js +19 -6
  21. package/v2Containers/Email/index.js +1 -5
  22. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +10 -62
  23. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +12 -115
  24. package/v2Containers/FTP/index.js +2 -51
  25. package/v2Containers/FTP/messages.js +0 -4
  26. package/v2Containers/InApp/index.js +1 -96
  27. package/v2Containers/InApp/tests/index.test.js +17 -6
  28. package/v2Containers/InappAdvance/index.js +2 -103
  29. package/v2Containers/Line/Container/Text/index.js +0 -1
  30. package/v2Containers/MobilePush/Create/index.js +6 -16
  31. package/v2Containers/MobilePush/Edit/index.js +6 -16
  32. package/v2Containers/MobilePushNew/index.js +2 -33
  33. package/v2Containers/Rcs/index.js +12 -37
  34. package/v2Containers/Sms/Create/index.js +31 -3
  35. package/v2Containers/Sms/Create/messages.js +4 -0
  36. package/v2Containers/Sms/Edit/index.js +29 -3
  37. package/v2Containers/Sms/commonMethods.js +6 -6
  38. package/v2Containers/SmsTrai/Edit/index.js +6 -47
  39. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  40. package/v2Containers/Templates/reducer.js +3 -1
  41. package/v2Containers/Templates/tests/reducer.test.js +12 -0
  42. package/v2Containers/Viber/index.js +0 -1
  43. package/v2Containers/WebPush/Create/components/BrandIconSection.test.js +264 -0
  44. package/v2Containers/WebPush/Create/components/__snapshots__/BrandIconSection.test.js.snap +187 -0
  45. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -3
  46. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  47. package/v2Containers/WebPush/Create/index.js +2 -2
  48. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +269 -0
  49. package/v2Containers/WebPush/Create/utils/validation.js +17 -2
  50. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -24
  51. package/v2Containers/Whatsapp/index.js +9 -17
  52. package/v2Containers/Zalo/index.js +3 -11
@@ -2,11 +2,9 @@ export const expectedStateGetLiquidTagsRequest = {
2
2
  fetchingLiquidTags: true,
3
3
  fetchingSchema: true,
4
4
  fetchingSchemaError: "",
5
- liquidTags: [],
6
5
  messages: [],
7
6
  metaEntities: {
8
7
  layouts: [],
9
- tagLookupMap: {},
10
8
  tags: [],
11
9
  },
12
10
  orgID: "",
@@ -17,11 +15,9 @@ export const expectedStateGetLiquidTagsFailure = {
17
15
  fetchingLiquidTags: false,
18
16
  fetchingSchema: true,
19
17
  fetchingSchemaError: "",
20
- liquidTags: [],
21
18
  messages: [],
22
19
  metaEntities: {
23
20
  layouts: [],
24
- tagLookupMap: {},
25
21
  tags: [],
26
22
  },
27
23
  orgID: "",
@@ -32,11 +28,9 @@ export const expectedStateGetLiquidTagsSuccess = {
32
28
  fetchingLiquidTags: false,
33
29
  fetchingSchema: true,
34
30
  fetchingSchemaError: "",
35
- liquidTags: [],
36
31
  messages: [],
37
32
  metaEntities: {
38
33
  layouts: [],
39
- tagLookupMap: {},
40
34
  tags: [],
41
35
  },
42
36
  orgID: "",
@@ -47,11 +41,9 @@ export const expectedStateGetSchemaForEntitySuccessTAG = {
47
41
  fetchingLiquidTags: false,
48
42
  fetchingSchema: false,
49
43
  fetchingSchemaError: false,
50
- liquidTags: [],
51
44
  messages: [],
52
45
  metaEntities: {
53
46
  layouts: undefined,
54
- tagLookupMap: { undefined: { definition: {} } },
55
47
  tags: { standard: { random: "32" } },
56
48
  },
57
49
  orgID: "",
@@ -62,11 +54,9 @@ export const expectedStateGetSchemaForEntitySuccess = {
62
54
  fetchingLiquidTags: false,
63
55
  fetchingSchema: false,
64
56
  fetchingSchemaError: false,
65
- liquidTags: [],
66
57
  messages: [],
67
58
  metaEntities: {
68
59
  layouts: undefined,
69
- tagLookupMap: undefined,
70
60
  tags: undefined,
71
61
  },
72
62
  orgID: "",
@@ -78,13 +68,9 @@ export const expectedForwardedTags = {
78
68
  fetchingSchema: false,
79
69
  fetchingSchemaError: '',
80
70
  injectedTags: undefined,
81
- liquidTags: [],
82
71
  messages: [],
83
72
  metaEntities: {
84
73
  layouts: [],
85
- tagLookupMap: {
86
-
87
- },
88
74
  tags: [],
89
75
  },
90
76
  orgID: "",
@@ -1,13 +1,11 @@
1
1
  /**
2
2
  * Created by vivek on 22/5/17.
3
3
  */
4
- import { fromJS, Map as ImmutableMap } from 'immutable';
4
+ import { fromJS } from 'immutable';
5
5
  import _ from 'lodash';
6
6
  import * as types from './constants';
7
7
  import initialState from '../../initialState';
8
8
  import { FAILURE } from '../App/constants';
9
- import { TAG } from '../Whatsapp/constants';
10
- import { getTagMapValue, getForwardedMapValues, getLoyaltyTagsMapValue } from '../../utils/tagValidations';
11
9
 
12
10
  function capReducer(state = fromJS(initialState.cap), action) {
13
11
  switch (action.type) {
@@ -98,39 +96,6 @@ function capReducer(state = fromJS(initialState.cap), action) {
98
96
  return state
99
97
  .set('fetchingLiquidTags', false);
100
98
  case types.GET_SCHEMA_FOR_ENTITY_SUCCESS: {
101
- //Process standard tags
102
- const standardTagMapInitial = _.keyBy(
103
- action?.data?.metaEntities?.standard,
104
- item => item?.definition?.value
105
- );
106
- // Mapping only the `definition` object instead of the entire item, to reduce space used
107
- const standardTagMap = _.mapValues(standardTagMapInitial, item => ({
108
- definition: item?.definition ?? {},
109
- }));
110
-
111
- // Process custom tags
112
- const customSubtags = getTagMapValue(action?.data?.metaEntities?.custom)
113
- // Process extended tags
114
- const extendedSubtags = getTagMapValue(action?.data?.metaEntities?.extended);
115
-
116
- const loyaltySubTagsData = getLoyaltyTagsMapValue(action?.data?.metaEntities?.loyaltyTags);
117
-
118
- const getExistingTagLookupMap = (state) => {
119
- if (!state || !state.get) return {};
120
- const tagLookupMap = state.getIn(['metaEntities', 'tagLookupMap']);
121
- return state.get('metaEntities') && ImmutableMap.isMap(tagLookupMap)
122
- ? tagLookupMap.toJS()
123
- : {};
124
- };
125
-
126
- // Combine all maps
127
- const combinedTagMap = {
128
- ...standardTagMap,
129
- ...customSubtags,
130
- ...extendedSubtags,
131
- ...loyaltySubTagsData,
132
- ...getExistingTagLookupMap(state),
133
- };
134
99
  const stateMeta = state.get("metaEntities");
135
100
  return state
136
101
  .set('fetchingSchema', false)
@@ -138,7 +103,6 @@ function capReducer(state = fromJS(initialState.cap), action) {
138
103
  .set('metaEntities', {
139
104
  layouts: action.data && action.entityType === 'LAYOUT' ? action.data.metaEntities : stateMeta?.layouts,
140
105
  tags: action.data && action.entityType === 'TAG' ? action.data.metaEntities : stateMeta?.tags,
141
- tagLookupMap: action?.data && action?.entityType === TAG ? combinedTagMap : stateMeta?.tagLookupMap,
142
106
  })
143
107
  .set('fetchingSchemaError', false);
144
108
  }
@@ -146,7 +110,6 @@ function capReducer(state = fromJS(initialState.cap), action) {
146
110
  return state.set('metaEntities', {
147
111
  layouts: [],
148
112
  tags: [],
149
- tagLookupMap: {},
150
113
  });
151
114
  // eslint-disable-next-line no-case-declarations
152
115
  case types.HIDE_TAGS:
@@ -154,23 +117,8 @@ function capReducer(state = fromJS(initialState.cap), action) {
154
117
  metaEntities.tags.standard = _.filter(state.get('metaEntities').tags.standard, (tag) => action.tagList.indexOf(tag.definition.value) === -1);
155
118
  metaEntities.tags.custom = _.filter(state.get('metaEntities').tags.custom, (tag) => action.tagList.indexOf(tag.name) === -1);
156
119
  return state.setIn(['metaEntities'], metaEntities);
157
- case types.SET_INJECTED_TAGS:
158
-
159
- // Deep clone the tagLookupMap to avoid direct mutations
160
- let updatedMetaEntitiesTagLookUp = _.cloneDeep(state.getIn(['metaEntities', 'tagLookupMap']));
161
- const formattedInjectedTags = getForwardedMapValues(action?.injectedTags);
162
- // Merge the injectedTags with the existing tagLookupMap
163
- updatedMetaEntitiesTagLookUp = {
164
- ...formattedInjectedTags || {},
165
- ...updatedMetaEntitiesTagLookUp || {},
166
- };
167
- return state.set("injectedTags", action.injectedTags).setIn(
168
- ["metaEntities"],
169
- fromJS({
170
- ...state.get("metaEntities"),
171
- tagLookupMap: updatedMetaEntitiesTagLookUp
172
- })
173
- );
120
+ case types.SET_INJECTED_TAGS:
121
+ return state.set("injectedTags", action.injectedTags);
174
122
  case types.GET_TOPBAR_MENU_DATA_REQUEST:
175
123
  return state.set('topbarMenuData', fromJS({ status: 'request' }));
176
124
  case types.GET_TOPBAR_MENU_DATA_SUCCESS:
@@ -21,7 +21,6 @@ import {
21
21
  expectedStateGetSchemaForEntitySuccessTAG,
22
22
  expectedStateGetSchemaForEntitySuccess,
23
23
  } from '../mockData';
24
- import { TAG } from '../../Whatsapp/constants';
25
24
  import { loadItem } from '../../../services/localStorageApi';
26
25
 
27
26
 
@@ -118,104 +117,3 @@ describe('should handle GET_SUPPORT_VIDEOS_CONFIG', () => {
118
117
  expect(reducer(mockedInitialState, action).toJS())?.fetchingSchema?.toEqual(true);
119
118
  });
120
119
  });
121
-
122
- describe('GET_SCHEMA_FOR_ENTITY_SUCCESS handler', () => {
123
- it.concurrent('should handle existing tagLookupMap correctly when metaEntities and tagLookupMap exist', () => {
124
- const initialStateTest = fromJS({
125
- token: loadItem('token') || '',
126
- orgID: loadItem('orgID') || '',
127
- messages: [],
128
- metaEntities: {
129
- tags: [{ id: 1, name: 'tag1' }],
130
- layouts: ['layout1', 'layout2'],
131
- tagLookupMap: {
132
- existingTag: { definition: { value: 'existing' } },
133
- anotherTag: { definition: { value: 'another' } },
134
- },
135
- standard: [],
136
- },
137
- liquidTags: [],
138
- fetchingLiquidTags: false,
139
- fetchingSchema: false,
140
- fetchingSchemaError: '',
141
- });
142
-
143
- let action = {
144
- type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
145
- entityType: TAG,
146
- data: {
147
- metaEntities: {
148
- standard: [],
149
- custom: [],
150
- extended: [],
151
- },
152
- },
153
- };
154
-
155
- let newState = reducer(initialStateTest, action);
156
- let metaEntities = newState.get('metaEntities');
157
-
158
- expect(metaEntities).toEqual(expect.objectContaining({
159
- tagLookupMap: expect.objectContaining({
160
- existingTag: expect.objectContaining({
161
- definition: expect.objectContaining({
162
- value: 'existing',
163
- }),
164
- }),
165
- }),
166
- }));
167
-
168
- action = {
169
- type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
170
- entityType: 'LAYOUT',
171
- data: {
172
- metaEntities: {
173
- layouts: ['layout1', 'layout2'],
174
- standard: [],
175
- },
176
- },
177
- };
178
- newState = reducer(initialStateTest, action);
179
- metaEntities = newState.get('metaEntities');
180
- expect(metaEntities).toEqual(expect.objectContaining({
181
- layouts: expect.objectContaining({
182
- layouts: expect.arrayContaining(['layout1', 'layout2']),
183
- }),
184
- }));
185
- });
186
-
187
- it.concurrent('should handle non-existent tagLookupMap by returning empty object', () => {
188
- const initialStateTest = fromJS({
189
- token: loadItem('token') || '',
190
- orgID: loadItem('orgID') || '',
191
- messages: [],
192
- metaEntities: {
193
- tagLookupMap: {},
194
- },
195
- liquidTags: [],
196
- fetchingLiquidTags: false,
197
- fetchingSchema: false,
198
- fetchingSchemaError: '',
199
- });
200
-
201
- const action = {
202
- type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
203
- entityType: TAG,
204
- data: {
205
- metaEntities: {
206
- standard: [],
207
- custom: [],
208
- extended: [],
209
- },
210
- },
211
- };
212
-
213
- const newState = reducer(initialStateTest, action);
214
- const metaEntities = newState.get('metaEntities');
215
-
216
- // Updated assertions to handle plain object
217
- expect(metaEntities).toBeDefined();
218
- expect(metaEntities.tagLookupMap).toBeDefined();
219
- expect(metaEntities.tagLookupMap).toEqual({});
220
- });
221
- });
@@ -53,6 +53,7 @@ function SlideBoxFooter(props) {
53
53
  // Only apply validation state checks for EMAIL channel in HTML Editor mode (not BEE/DragDrop)
54
54
  // For other channels, BEE editor, or when htmlEditorValidationState is not provided, don't disable based on validation
55
55
  const isEmailChannel = currentChannel?.toUpperCase() === 'EMAIL';
56
+ const isSmsChannel = currentChannel?.toUpperCase() === 'SMS';
56
57
  const isEditMode = slidBoxContent === 'editTemplate';
57
58
 
58
59
  // Use selectedEmailCreateMode for accurate mode detection in create mode (emailCreateMode is mapped for backwards compatibility)
@@ -129,8 +130,9 @@ function SlideBoxFooter(props) {
129
130
  const isBEEEditorModeInCreate = !isHTMLEditorMode && !isEditMode;
130
131
  const isBEEEditorMode = isBEEEditorModeInEdit || isBEEEditorModeInCreate;
131
132
  const hasBEEEditorErrors = isEmailChannel && isBEEEditorMode && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
133
+ const hasSmsValidationErrors = isSmsChannel && hasStandardErrors;
132
134
 
133
- const shouldShowErrorInfoNote = hasBEEEditorErrors || isSupportCKEditor;
135
+ const shouldShowErrorInfoNote = hasBEEEditorErrors || hasSmsValidationErrors || isSupportCKEditor;
134
136
 
135
137
  // Check for personalization tokens in title/message when anonymous user tries to save
136
138
  const hasPersonalizationTokens = () => {
@@ -132,7 +132,6 @@ export class Creatives extends React.Component {
132
132
  },
133
133
  hasPersonalizationTokenError: false, // Track personalization token errors in form
134
134
  };
135
- this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
136
135
  this.creativesTemplateSteps = {
137
136
  1: 'modeSelection',
138
137
  2: 'templateSelection', // only for email in current flows wil be used for mpush, line and wechat as well.
@@ -256,12 +255,23 @@ export class Creatives extends React.Component {
256
255
  };
257
256
 
258
257
  onShowTemplates = () => {
259
- this.setState({ slidBoxContent: 'templates', showSlideBox: true, isGetFormData: false });
258
+ this.setState({
259
+ slidBoxContent: 'templates',
260
+ showSlideBox: true,
261
+ isGetFormData: false,
262
+ liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
263
+ isLiquidValidationError: false,
264
+ });
260
265
  this.resetStep();
261
266
  };
262
267
 
263
268
  onChannelChange = (channel) => {
264
- this.setState({ currentChannel: channel, templateData: null });
269
+ this.setState({
270
+ currentChannel: channel,
271
+ templateData: null,
272
+ liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
273
+ isLiquidValidationError: false,
274
+ });
265
275
  }
266
276
 
267
277
  onCreateNextStep = () => {
@@ -1469,11 +1479,12 @@ export class Creatives extends React.Component {
1469
1479
  }
1470
1480
 
1471
1481
  getFormData = (template) => {
1482
+ // Always reset isGetFormData so the child does not re-send form data on every re-render
1483
+ // (e.g. when user fixes validation error by typing, we must not auto-close the slidebox)
1484
+ this.setState({ isGetFormData: false });
1472
1485
  if (template.validity) {
1473
1486
  this.setState(
1474
- {
1475
- isGetFormData: false,
1476
- },
1487
+ {},
1477
1488
  () => {
1478
1489
  const templateData = this.state.templateData ? this.state.templateData : template; //select existing or create new content
1479
1490
  const channel = templateData.type;
@@ -1557,6 +1568,8 @@ export class Creatives extends React.Component {
1557
1568
  ...prevState,
1558
1569
  templateData: undefined,
1559
1570
  showSlideBox: false,
1571
+ liquidErrorMessage: { STANDARD_ERROR_MSG: [], LIQUID_ERROR_MSG: [] },
1572
+ isLiquidValidationError: false,
1560
1573
  }), () => this.props.handleCloseCreatives(reloadTemplates));
1561
1574
  };
1562
1575
 
@@ -26,7 +26,7 @@ import * as globalActions from '../Cap/actions';
26
26
  import './_email.scss';
27
27
  import {getMessageObject} from '../../utils/messageUtils';
28
28
  import EmailPreview from '../../v2Components/EmailPreview';
29
- import { getDecodedFileName, hasLiquidSupportFeature, hasSupportCKEditor } from '../../utils/common';
29
+ import { getDecodedFileName, hasSupportCKEditor } from '../../utils/common';
30
30
  import Pagination from '../../v2Components/Pagination';
31
31
  import * as creativesContainerActions from '../CreativesContainer/actions';
32
32
  import withCreatives from '../../hoc/withCreatives';
@@ -170,7 +170,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
170
170
  deleteLanguage: this.deleteLanguage,
171
171
  },
172
172
  };
173
- this.liquidFlow = hasLiquidSupportFeature();
174
173
  }
175
174
  componentWillMount() {
176
175
  const formData = this.initFormData(this.props, true); //_.cloneDeep(this.state.formData);
@@ -255,7 +254,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
255
254
  layout: 'EMAIL',
256
255
  type: 'LAYOUT',
257
256
  version: 'v2',
258
- liquidFlow:this.liquidFlow,
259
257
  };
260
258
  this.props.globalActions.fetchSchemaForEntity(query);
261
259
  window.addEventListener("message", this.handleFrameTasks);
@@ -347,7 +345,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
347
345
  type: 'TAG',
348
346
  context: this.props.location.query.type === 'embedded' ? this.props.location.query.module : 'default',
349
347
  embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
350
- liquidFlow:this.liquidFlow
351
348
  };
352
349
  if (this.props.getDefaultTags) {
353
350
  query.context = this.props.getDefaultTags;
@@ -2373,7 +2370,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2373
2370
  type: 'TAG',
2374
2371
  context: (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
2375
2372
  embedded: 'full',
2376
- liquidFlow:this.liquidFlow
2377
2373
  };
2378
2374
  this.props.globalActions.fetchSchemaForEntity(query);
2379
2375
  }
@@ -15,7 +15,7 @@ import HTMLEditor from '../../../v2Components/HtmlEditor';
15
15
  import CapTagListWithInput from '../../../v2Components/CapTagListWithInput';
16
16
  import formBuilderMessages from '../../../v2Components/FormBuilder/messages';
17
17
  import { validateLiquidTemplateContent } from '../../../utils/commonUtils';
18
- import { hasLiquidSupportFeature, isEmailUnsubscribeTagMandatory } from '../../../utils/common';
18
+ import { isEmailUnsubscribeTagOptional } from '../../../utils/common';
19
19
  import history from '../../../utils/history';
20
20
  import messages from '../messages';
21
21
  import emailMessages from '../../Email/messages';
@@ -108,13 +108,10 @@ const EmailHTMLEditor = (props) => {
108
108
  standardErrors: [],
109
109
  });
110
110
 
111
- // Merge tag validation errors (unsupported/missing) into apiValidationErrors so they show in ValidationErrorDisplay
111
+ // Merge tag validation errors (missing) into apiValidationErrors so they show in ValidationErrorDisplay
112
112
  const mergedApiValidationErrors = useMemo(() => {
113
113
  const tagMessages = [];
114
- if (tagValidationError?.unsupportedTags?.length) {
115
- tagMessages.push(`Unsupported tags are: ${tagValidationError.unsupportedTags.join(', ')}`);
116
- }
117
- if (tagValidationError?.missingTags?.length && !isEmailUnsubscribeTagMandatory()) {
114
+ if (tagValidationError?.missingTags?.length && !isEmailUnsubscribeTagOptional()) {
118
115
  tagMessages.push(`Missing tags are: ${tagValidationError.missingTags.join(', ')}`);
119
116
  }
120
117
  if (tagMessages.length === 0) {
@@ -190,9 +187,6 @@ const EmailHTMLEditor = (props) => {
190
187
  },
191
188
  }), [htmlContent, subject, currentOrgDetails]);
192
189
 
193
- // Check if liquid support is enabled
194
- const isLiquidEnabled = hasLiquidSupportFeature();
195
-
196
190
  // Detect edit mode: when isEditEmail is false (create flow), never treat as edit or fetch template details
197
191
  const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
198
192
  const currentTemplateId = isEditEmail
@@ -493,10 +487,8 @@ const EmailHTMLEditor = (props) => {
493
487
  const validationResult = validateTags({
494
488
  content,
495
489
  tagsParam: tags,
496
- injectedTagsParams: injectedTags,
497
490
  location,
498
491
  tagModule: getDefaultTags,
499
- eventContextTags,
500
492
  isFullMode,
501
493
  });
502
494
 
@@ -650,7 +642,7 @@ const EmailHTMLEditor = (props) => {
650
642
  // IMPORTANT: Clear API validation errors FIRST before checking for validation errors
651
643
  // This ensures that old API errors don't block the save when user fixes content and clicks Update again
652
644
  // We'll re-validate with fresh API call anyway
653
- if (isLiquidEnabled && getLiquidTags) {
645
+ if (getLiquidTags) {
654
646
  setApiValidationErrors({
655
647
  liquidErrors: [],
656
648
  standardErrors: [],
@@ -712,7 +704,7 @@ const EmailHTMLEditor = (props) => {
712
704
  // When EMAIL_UNSUBSCRIBE_TAG_MANDATORY is false: validate and require unsubscribe tag.
713
705
  // Run for both library and full mode so liquid-enabled orgs also get the error (notification + ValidationErrorDisplay).
714
706
  const isModuleTypeOutbound = (moduleType || '').toUpperCase() === OUTBOUND;
715
- if (!isEmailUnsubscribeTagMandatory() && isModuleTypeOutbound) {
707
+ if (!isEmailUnsubscribeTagOptional() && isModuleTypeOutbound) {
716
708
  const unsubscribeRegex = /{{unsubscribe(\(#[a-zA-Z\d]{6}\))?}}/g; // eslint-disable-line no-useless-escape
717
709
  const hasUnsubscribeTag = unsubscribeRegex.test(htmlContent);
718
710
 
@@ -744,52 +736,17 @@ const EmailHTMLEditor = (props) => {
744
736
  const validationResult = validateTags({
745
737
  content: htmlContent,
746
738
  tagsParam: tags,
747
- injectedTagsParams: injectedTags,
748
739
  location,
749
740
  tagModule: getDefaultTags,
750
- eventContextTags,
751
741
  isFullMode,
752
742
  });
753
743
 
754
- const hasUnsupportedTags = validationResult?.unsupportedTags?.length > 0;
755
- if (!validationResult?.valid || (hasUnsupportedTags && !isFullMode)) {
744
+ if (!validationResult?.valid) {
756
745
  setTagValidationError(validationResult);
757
- // IMPORTANT: For non-liquid orgs, block save (like CK/BEE editor)
758
- // For liquid orgs, continue (extractTags API will validate)
759
- if (!isLiquidEnabled) {
760
- // Show notification popup like CK/BEE editor
761
- const baseLanguage = get(currentOrgDetails, 'basic_details.base_language', 'en');
762
-
763
- const contentNotValidMsg = intl.formatMessage(formBuilderMessages.contentNotValidLanguage);
764
- let errorMessage = `${contentNotValidMsg} ${baseLanguage}`;
765
-
766
- if (hasUnsupportedTags) {
767
- const unsupportedTagsMsg = intl.formatMessage(formBuilderMessages.unsupportedTags);
768
- errorMessage += `\n${unsupportedTagsMsg} ${validationResult?.unsupportedTags?.join(', ')}`;
769
- }
770
- if (validationResult?.missingTags?.length > 0) {
771
- const missingTagsMsg = intl.formatMessage(formBuilderMessages.missingTags);
772
- errorMessage += `\n${missingTagsMsg} ${validationResult?.missingTags?.join(', ')}`;
773
- }
774
-
775
- const type = 'error';
776
- CapNotification[type]({
777
- message: `${type.toUpperCase()} ! ! ! `,
778
- description: errorMessage,
779
- duration: 5,
780
- });
781
-
782
- // Reset parent state so next click is detected as a change
783
- if (onValidationFail) {
784
- onValidationFail();
785
- }
786
- // Block save for non-liquid orgs
787
- return;
788
- }
789
- // For liquid orgs, just show warning and continue
746
+ // For liquid orgs, show warning and continue (extractTags API will validate)
790
747
  }
791
748
  // Clear tag errors if valid
792
- if (tagValidationError && validationResult?.valid && !hasUnsupportedTags) {
749
+ if (tagValidationError && validationResult?.valid) {
793
750
  setTagValidationError(null);
794
751
  }
795
752
  }
@@ -956,8 +913,8 @@ const EmailHTMLEditor = (props) => {
956
913
  }
957
914
  };
958
915
 
959
- // If liquid enabled, validate first using extractTags API
960
- if (isLiquidEnabled && getLiquidTags) {
916
+ // Validate first using extractTags API
917
+ if (getLiquidTags) {
961
918
  // Note: API validation errors are already cleared at the start of handleSave
962
919
  // This ensures fresh validation on every save attempt
963
920
 
@@ -998,10 +955,6 @@ const EmailHTMLEditor = (props) => {
998
955
  messages: formBuilderMessages,
999
956
  onError,
1000
957
  onSuccess,
1001
- tagLookupMap: metaEntities?.tagLookupMap,
1002
- eventContextTags,
1003
- isLiquidFlow: true,
1004
- forwardedTags: forwardedTags || {},
1005
958
  });
1006
959
  } else {
1007
960
  performSave();
@@ -1013,7 +966,6 @@ const EmailHTMLEditor = (props) => {
1013
966
  injectedTags,
1014
967
  location,
1015
968
  getDefaultTags,
1016
- eventContextTags,
1017
969
  formatMessage,
1018
970
  subjectError,
1019
971
  isFullMode,
@@ -1025,11 +977,8 @@ const EmailHTMLEditor = (props) => {
1025
977
  emailActions,
1026
978
  getFormdata,
1027
979
  isGetFormData,
1028
- isLiquidEnabled,
1029
980
  getLiquidTags,
1030
981
  showLiquidErrorInFooter,
1031
- metaEntities,
1032
- forwardedTags,
1033
982
  globalActions,
1034
983
  intl,
1035
984
  extractedTemplateName,
@@ -1175,7 +1124,6 @@ const EmailHTMLEditor = (props) => {
1175
1124
  userLocale={intl.locale || 'en'}
1176
1125
  moduleFilterEnabled={location?.query?.type !== EMBEDDED}
1177
1126
  onTagContextChange={handleOnTagsContextChange}
1178
- isLiquidEnabled={isLiquidEnabled}
1179
1127
  isFullMode={isFullMode}
1180
1128
  onErrorAcknowledged={handleErrorAcknowledged}
1181
1129
  onValidationChange={handleValidationChange}