@capillarytech/creatives-library 8.0.343-alpha.0 → 8.0.343-alpha.3

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.343-alpha.0",
4
+ "version": "8.0.343-alpha.3",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -698,9 +698,16 @@ export function SlideBoxContent(props) {
698
698
  {(isEditEmailWithId || isEmailEditWithContent) && (
699
699
  (() => {
700
700
  const supportCKEditor = commonUtil.hasSupportCKEditor();
701
- // When supportCKEditor is true: Use Email component (legacy flow with CKEditor).
702
- // When supportCKEditor is false: Always use EmailWrapper (BEE or HTML editor, never CKEditor).
703
- if (supportCKEditor) {
701
+ // BEE templates always use the <Email> component directly (the same
702
+ // path the SUPPORT_CK_EDITOR=true branch uses). EmailWrapper's
703
+ // useEmailWrapper strips templateData from props, so library-mode
704
+ // pencil-edit on a BEE template would never reach startTemplateCreation
705
+ // and getDetails?type=BEE_PLUGIN would never fire. Routing BEE
706
+ // templates through the direct <Email> path — which is already
707
+ // battle-tested for the CKEditor flow — sidesteps that entirely.
708
+ const isBEETemplate = templateData?.base?.is_drag_drop === true
709
+ || templateData?.base?.is_drag_drop === 1;
710
+ if (supportCKEditor || isBEETemplate) {
704
711
  return (
705
712
  <Email
706
713
  key="cretives-container-email-edit"
@@ -776,8 +783,12 @@ export function SlideBoxContent(props) {
776
783
  isTestAndPreviewMode={isTestAndPreviewMode}
777
784
  onHtmlEditorValidationStateChange={onHtmlEditorValidationStateChange}
778
785
  location={{
779
- pathname: `/email/edit/${templateData._id}`,
780
- query: { type: 'embedded', module: 'library', id: templateData._id },
786
+ pathname: `/email/edit/${templateData._id || ''}`,
787
+ query: {
788
+ type: 'embedded',
789
+ module: 'library',
790
+ ...(templateData._id ? { id: templateData._id } : {}),
791
+ },
781
792
  }}
782
793
  params={{ id: templateData._id }}
783
794
  />
@@ -109,7 +109,8 @@ function emailReducer(state = initialState, action) {
109
109
  .set('fetchingCmsData', false)
110
110
  .set('fetchingCmsDataFailed', true);
111
111
  case types.GET_CMS_ACCOUNTS_REQUEST:
112
- return state; // preserve null — "still pending", only update on SUCCESS/FAILURE
112
+ return state
113
+ .set('isBeeEnabled', false); // default to false
113
114
  case types.GET_CMS_ACCOUNTS_SUCCESS:
114
115
  return state
115
116
  .set('isBeeEnabled', action.isBeeEnabled);
@@ -16,15 +16,15 @@ describe('emailReducer', () => {
16
16
  expect(emailReducer(undefined, action)).toMatchSnapshot();
17
17
  });
18
18
 
19
- it.concurrent('it handles GET_CMS_ACCOUNTS_REQUEST action (does not change isBeeEnabled)', () => {
19
+ it.concurrent('it handles GET_CMS_ACCOUNTS_REQUEST action (line 111-113)', () => {
20
20
  const initialState = fromJS({
21
- isBeeEnabled: true, // preserved during request "still pending"
21
+ isBeeEnabled: true, // Start with true to verify it gets set to false
22
22
  });
23
23
  const action = {
24
24
  type: types.GET_CMS_ACCOUNTS_REQUEST,
25
25
  };
26
26
  const result = emailReducer(initialState, action);
27
- expect(result.get('isBeeEnabled')).toBe(true);
27
+ expect(result.get('isBeeEnabled')).toBe(false);
28
28
  });
29
29
 
30
30
  it.concurrent('it handles GET_CMS_ACCOUNTS_SUCCESS action (line 114-116)', () => {
@@ -200,9 +200,7 @@ const useEmailWrapper = ({
200
200
  if (!isEditEmail) {
201
201
  return;
202
202
  }
203
- const explicitId = params?.id || location?.query?.id || location?.params?.id;
204
- const pathnameId = !explicitId && location?.pathname?.match(/\/edit\/([^/]+)/)?.[1];
205
- const hasParamsId = explicitId || (pathnameId && pathnameId !== 'undefined');
203
+ const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
206
204
  const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
207
205
  const hasTemplateDataProp = templateData && !isEmpty(templateData);
208
206
  const isTemplateLoading = Email?.getTemplateDetailsInProgress;
@@ -232,18 +230,13 @@ const useEmailWrapper = ({
232
230
  // New flow: When template details are loaded and it's a BEE template, set it in Templates.BEETemplate
233
231
  // This allows Email component to properly initialize and call getCmsSetting
234
232
  const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
235
- const hasTemplateProp = templateData && !isEmpty(templateData);
236
233
  // Note: We check Email?.BEETemplate as a proxy, but the actual BEETemplate is in Templates reducer
237
234
  // The Email component will detect it via this.props.Templates.BEETemplate
238
235
  const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
239
236
 
240
- // Use Email.templateDetails when available (edit-by-ID flow), otherwise fall back to
241
- // the templateData prop (BEE free template flow — template passed directly by consumer)
242
- const editTemplateSource = hasTemplateDetails ? Email.templateDetails : (hasTemplateProp ? templateData : null);
243
-
244
- if (editTemplateSource && !hasBEETemplate && templatesActions?.setBEETemplate && !beeTemplateSetRef.current) {
237
+ if (hasTemplateDetails && !hasBEETemplate && templatesActions?.setBEETemplate && !beeTemplateSetRef.current) {
245
238
  // Check if it's a BEE template
246
- const editTemplateData = editTemplateSource;
239
+ const editTemplateData = Email.templateDetails;
247
240
  const getIsDragDrop = (data) => {
248
241
  if (!data) return false;
249
242
  const baseDragDrop = get(data, 'versions.base.is_drag_drop', false);
@@ -272,17 +265,13 @@ const useEmailWrapper = ({
272
265
  || activeTabData.id
273
266
  || get(editTemplateData, 'versions.base.drag_drop_id')
274
267
  || get(editTemplateData, 'versions.base.id')
275
- || get(editTemplateData, 'base.drag_drop_id')
276
- || get(editTemplateData, 'base.id')
277
268
  || editTemplateData._id;
278
269
 
279
270
  const isBEESupport = (location?.query?.isBEESupport !== "false") || false;
280
271
  // IMPORTANT: isBEEAppEnable should be consistent across full mode and library mode
281
272
  // It represents whether BEE is enabled for the organization, not the mode
282
273
  // This ensures the same template behaves the same way in both modes
283
- // isDragDrop is always true here — pass true directly rather than relying on
284
- // checkBeeEditorEnabled() which may return false while getCmsAccounts is pending
285
- const isBEEAppEnable = isDragDrop || checkBeeEditorEnabled();
274
+ const isBEEAppEnable = checkBeeEditorEnabled();
286
275
  // Check if we're in edit mode - check multiple sources for id
287
276
  const hasParamsId = params?.id
288
277
  || location?.query?.id
@@ -302,11 +291,11 @@ const useEmailWrapper = ({
302
291
  }
303
292
  }
304
293
 
305
- // Reset ref when all template sources are gone (prevents duplicate calls on re-render)
306
- if (!hasTemplateDetails && !hasTemplateProp && beeTemplateSetRef.current) {
294
+ // Reset ref when template changes (template details cleared)
295
+ if (!hasTemplateDetails && beeTemplateSetRef.current) {
307
296
  beeTemplateSetRef.current = false;
308
297
  }
309
- }, [Email?.templateDetails, Email?.BEETemplate, Email?.getTemplateDetailsInProgress, Email?.fetchingCmsSettings, templatesActions, emailActions, params?.id, location?.query, checkBeeEditorEnabled, isFullMode, templateData]);
298
+ }, [Email?.templateDetails, Email?.BEETemplate, Email?.getTemplateDetailsInProgress, Email?.fetchingCmsSettings, templatesActions, emailActions, params?.id, location?.query, checkBeeEditorEnabled, isFullMode]);
310
299
 
311
300
  const onChange = useCallback((e) => {
312
301
  const { target: { value } } = e;
@@ -719,7 +708,10 @@ const useEmailWrapper = ({
719
708
  } else if (location?.pathname?.includes('/edit/')) {
720
709
  // Extract id from pathname if it's in the format /edit/:id
721
710
  const match = location.pathname.match(/\/edit\/([^/]+)/);
722
- if (match) {
711
+ // Reject sentinel strings that come from unguarded template literals
712
+ // (e.g. `/edit/${maybeUndefined}` → "/edit/undefined"), so they don't
713
+ // get treated as real template ids downstream.
714
+ if (match && match[1] && match[1] !== 'undefined' && match[1] !== 'null') {
723
715
  emailParams.id = match[1];
724
716
  }
725
717
  }