@useinsider/guido 3.18.1 → 3.18.2-beta.320e07f

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 (48) hide show
  1. package/dist/components/Guido.vue.js +3 -3
  2. package/dist/components/Guido.vue2.js +30 -30
  3. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -11
  4. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +76 -57
  5. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +23 -37
  6. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +20 -18
  7. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
  8. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +47 -0
  9. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +34 -34
  10. package/dist/composables/useCustomInterfaceAppearance.js +56 -46
  11. package/dist/composables/useHtmlValidator.js +87 -82
  12. package/dist/composables/useHttp.js +24 -22
  13. package/dist/composables/useRecommendation.js +40 -35
  14. package/dist/composables/useStripo.js +30 -30
  15. package/dist/enums/extensions/recommendationBlock.js +38 -31
  16. package/dist/extensions/Blocks/Recommendation/block.js +43 -39
  17. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +21 -20
  18. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +55 -44
  19. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +84 -52
  20. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
  21. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +190 -90
  22. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +26 -16
  23. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +24 -0
  24. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +21 -12
  25. package/dist/guido.css +1 -1
  26. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +29 -28
  27. package/dist/package.json.js +1 -1
  28. package/dist/services/templateLibraryApi.js +17 -14
  29. package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
  30. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  31. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  32. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  33. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +7 -1
  34. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +9 -0
  35. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +7 -2
  36. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +87 -0
  37. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +14 -0
  38. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +4 -0
  39. package/dist/src/stores/onboarding.d.ts +377 -0
  40. package/dist/src/utils/genericUtil.d.ts +6 -0
  41. package/dist/src/utils/liquidDynamicContent.d.ts +20 -0
  42. package/dist/static/styles/components/recommendation-strategy.css.js +34 -4
  43. package/dist/static/styles/components/skeleton.css.js +23 -0
  44. package/dist/stores/onboarding.js +41 -36
  45. package/dist/utils/genericUtil.js +63 -54
  46. package/dist/utils/liquidDynamicContent.js +15 -0
  47. package/dist/utils/templatePreparation.js +61 -59
  48. package/package.json +7 -7
@@ -21,7 +21,7 @@ ${s.map((o) => ` - ${o}`).join(`
21
21
  * This validation runs only once per class type and results are cached.
22
22
  */
23
23
  validateImplementation(t, r) {
24
- var y;
24
+ var P;
25
25
  const s = [], o = r.name, W = Object.getPrototypeOf(this);
26
26
  t.forEach((u) => {
27
27
  if (typeof this[u] != "function") {
@@ -29,7 +29,7 @@ ${s.map((o) => ` - ${o}`).join(`
29
29
  return;
30
30
  }
31
31
  W[u] === r.prototype[u] && s.push(`Method ${u}() must be implemented (currently using base class error-throwing implementation)`);
32
- }), d.validatedClasses.add(r), s.length > 0 ? (d.validationErrors.set(r, s), console.error(`[${o} Validation] ${o} validation failed:`, s)) : typeof process < "u" && ((y = process.env) == null ? void 0 : y.NODE_ENV) === "development" && console.log(`[${o} Validation] ✅ ${o} validated successfully`);
32
+ }), d.validatedClasses.add(r), s.length > 0 ? (d.validationErrors.set(r, s), console.error(`[${o} Validation] ${o} validation failed:`, s)) : typeof process < "u" && ((P = process.env) == null ? void 0 : P.NODE_ENV) === "development" && console.log(`[${o} Validation] ✅ ${o} validated successfully`);
33
33
  }
34
34
  /**
35
35
  * Lifecycle method for cleaning up resources (e.g., removing DOM artifacts from document.body).
@@ -41,9 +41,9 @@ ${s.map((o) => ` - ${o}`).join(`
41
41
  };
42
42
  v.validatedClasses = /* @__PURE__ */ new Set();
43
43
  v.validationErrors = /* @__PURE__ */ new Map();
44
- var i = v, z = /* @__PURE__ */ ((e) => (e.BLOCK = "BLOCK", e.CONTAINER = "CONTAINER", e.STRUCTURE = "STRUCTURE", e.STRIPE = "STRIPE", e))(z || {}), P = class T extends i {
44
+ var i = v, z = /* @__PURE__ */ ((e) => (e.BLOCK = "BLOCK", e.CONTAINER = "CONTAINER", e.STRUCTURE = "STRUCTURE", e.STRIPE = "STRIPE", e))(z || {}), y = class c extends i {
45
45
  constructor() {
46
- super(T.REQUIRED_METHODS, T);
46
+ super(c.REQUIRED_METHODS, c);
47
47
  }
48
48
  /**
49
49
  * Determines if the block should be available for use in the editor.
@@ -221,10 +221,10 @@ var i = v, z = /* @__PURE__ */ ((e) => (e.BLOCK = "BLOCK", e.CONTAINER = "CONTAI
221
221
  throw new Error("Method getDescription() must be implemented by the subclass");
222
222
  }
223
223
  };
224
- P.REQUIRED_METHODS = ["getId", "getTemplate", "getIcon", "getName", "getDescription"];
225
- var qe = P, Z = class c extends i {
224
+ y.REQUIRED_METHODS = ["getId", "getTemplate", "getIcon", "getName", "getDescription"];
225
+ var qe = y, Z = class T extends i {
226
226
  constructor() {
227
- super(c.REQUIRED_METHODS, c);
227
+ super(T.REQUIRED_METHODS, T);
228
228
  }
229
229
  /**
230
230
  * @deprecated - use {@link getPreviewInnerHtml} instead
@@ -339,12 +339,12 @@ var j = {
339
339
  height: "height"
340
340
  }, Je = {
341
341
  BLOCK_IMAGE: j
342
- }, U = "esd-block-button", w = "esd-block-text", K = "esd-block-image", J = "esd-structure", ee = "esd-block-video", te = "esd-block-social", re = "esd-block-banner", ae = "esd-block-timer", ne = "esd-block-menu", se = "esd-block-html", ie = "esd-block-spacer", le = "esd-container-frame", Ee = "esd-stripe", oe = "esd-amp-form", I = ((e) => (e.BUTTON = `.${U}`, e.TEXT = `.${w}`, e.IMAGE = `.${K}`, e.STRUCTURE = `.${J}`, e.VIDEO = `.${ee}`, e.SOCIAL = `.${te}`, e.BANNER = `.${re}`, e.TIMER = `.${ae}`, e.MENU = `.${ne}`, e.HTML = `.${se}`, e.SPACER = `.${ie}`, e.CONTAINER = `.${le}`, e.STRIPE = `.${Ee}`, e.FORM = `.${oe}`, e))(I || {}), de = /* @__PURE__ */ ((e) => (e.BLOCK_IMAGE = "BLOCK_IMAGE", e.BLOCK_TEXT = "BLOCK_TEXT", e.BLOCK_BUTTON = "BLOCK_BUTTON", e.BLOCK_SPACER = "BLOCK_SPACER", e.BLOCK_VIDEO = "BLOCK_VIDEO", e.BLOCK_SOCIAL = "BLOCK_SOCIAL", e.BLOCK_BANNER = "BLOCK_BANNER", e.BLOCK_TIMER = "BLOCK_TIMER", e.BLOCK_MENU = "BLOCK_MENU", e.BLOCK_MENU_ITEM = "BLOCK_MENU_ITEM", e.BLOCK_HTML = "BLOCK_HTML", e.BLOCK_AMP_CAROUSEL = "BLOCK_AMP_CAROUSEL", e.BLOCK_AMP_ACCORDION = "BLOCK_AMP_ACCORDION", e.BLOCK_AMP_FORM = "BLOCK_AMP_FORM", e.CONTAINER = "CONTAINER", e.FORM_CONTAINER = "FORM_CONTAINER", e.STRUCTURE = "STRUCTURE", e.STRIPE = "STRIPE", e.EMPTY_CONTAINER = "EMPTY_CONTAINER", e.CUSTOM_BLOCK_LINK = "CUSTOM_BLOCK_LINK", e.CUSTOM_BLOCK_IMAGE = "CUSTOM_BLOCK_IMAGE", e.CUSTOM_BLOCK_TEXT = "CUSTOM_BLOCK_TEXT", e))(de || {}), F = /* @__PURE__ */ ((e) => (e.ANCHOR_LINK_CONTAINER = "anchorLinkFormContainer", e.APPLY_CONDITION = "applyCondition", e.APPLY_CONDITION_SWITCHER = "applyConditionSwitcher", e.BACKGROUND_COLOR = "backgroundColor", e.BACKGROUND_IMAGE = "generalImageContainer", e.TEXT_COLOR = "textColor", e.TEXT_STYLE = "textStyle", e.TEXT_SIZE = "textSize", e.TEXT_LINE_SPACING = "textLineSpacing", e.TEXT_ALIGN = "textAlign", e.FIXED_HEIGHT_SWITCHER = "fixedHeightSwitcherForm", e.HIDDEN_NODE = "hiddenNode", e.SMART_BLOCK = "smartBlock", e.SYNCHRONIZED_MODULE = "synchronizedModuleForm", e.FONT_FAMILY = "generalFontFamilyForm", e.BLOCK_INTERNAL_INDENTS = "generalBlockInternalIndents", e.STRUCTURE_INTERNAL_INDENTS = "generalStructureInternalIndents", e))(F || {}), H = /* @__PURE__ */ ((e) => (e.ADJUST_TO_WIDTH = "adjustToWidth", e.ALIGNMENT = "buttonAlignment", e.BORDER = "buttonBorder", e.BORDER_RADIUS = "buttonBorderRadius", e.COLOR = "buttonColor", e.BUTTON_BLOCK_BACKGROUND_COLOR = "buttonBlockBackgroundColor", e.EXTERNAL_INDENTS = "buttonExternalIndents", e.FIXED_HEIGHT = "buttonFixedHeightForm", e.FONT_COLOR = "buttonFontColor", e.FONT_FAMILY = "buttonFontFamily", e.FONT_SIZE = "buttonFontSize", e.FONT_WEIGHT = "buttonFontWeight", e.ICON = "buttonIconContainer", e.ICON_ALIGN = "buttonIconAlign", e.ICON_INDENT = "buttonIconIndent", e.ICON_WIDTH = "buttonIconWidth", e.IMAGE = "buttonImageForm", e.INTERNAL_INDENTS = "buttonInternalIndents", e.LINK = "buttonLink", e.MIME_TYPE = "buttonMimeTypeForm", e.SWITCHER_HOVERED_STYLES = "buttonSwitcherHoveredStylesForm", e.TEXT = "buttonText", e.TEXT_STYLE_AND_COLOR = "buttonTextStyleAndColorForm", e.HOVERED_BORDER_COLOR = "hoveredStyleBorderButtonForm", e.HOVERED_COLOR = "hoveredButtonColorForm", e.HOVERED_TEXT_COLOR = "hoveredButtonTextColorForm", e))(H || {}), k = /* @__PURE__ */ ((e) => (e.HIDDEN_NODE = "hiddenNodeText", e.PARAGRAPH_STYLE = "paragraphStyleForm", e.ALIGN = "textAlignmentForm", e.ANCHOR_CONTAINER = "textAnchorForm", e.FONT_BACKGROUND_COLOR = "textBlockFontBackgroundColor", e.TEXT_BLOCK_BACKGROUND_COLOR = "textBlockBackgroundColor", e.FONT_COLOR = "textBlockFontColor", e.TEXT_BLOCK_FONT_FAMILY = "textBlockFontFamily", e.FONT_FAMILY = "textFontFamily", e.FONT_SIZE = "textBlockFontSize", e.FONT_WEIGHT = "textBlockFontWeight", e.DIRECTION = "textBlockDirectionForm", e.INSERT_FORM = "textBlockInsertForm", e.LINK_DATA = "textBlockLinkDataForm", e.FORMAT = "textBlockTextFormatForm", e.FIXED_HEIGHT = "textFixedHeightForm", e.INTERNAL_INDENTS = "textInternalIndents", e.LINE_HEIGHT = "textLineHeightForm", e.MIME_TYPE = "textMimeTypeForm", e.NO_LINE_WRAPS = "textNoLineWrapsForm", e))(k || {}), p = /* @__PURE__ */ ((e) => (e.ALT_TEXT = "altText", e.LINK = "blockLink", e.ALIGNMENT = "imageAlignment", e.ANCHOR_LINK_CONTAINER = "imageAnchorLinkContainerForm", e.BORDER_RADIUS = "imageBorderRadiusForm", e.IMAGE = "imageImageForm", e.EXTERNAL_INDENTS = "imageExternalIndents", e.MIME_TYPE = "imageMimeTypeForm", e.RESPONSIVE = "imageResponsive", e.ROLLOVER_IMAGE = "imageRolloverImageForm", e.ROLLOVER_SWITCHER = "imageRolloverSwitcherForm", e.SIZE = "imageSizeContainer", e))(p || {}), ue = /* @__PURE__ */ ((e) => (e.BACKGROUND_COLOR = "containerBackgroundColorForm", e.BORDER_FORM = "containerBorderForm", e.BORDER_RADIUS = "containerBorderRadiusForm", e.EXTERNAL_INDENTS = "containerExternalIndentsForm", e.IMAGE_CONTAINER = "containerImageContainerForm", e.MIME_TYPE = "containerMimeTypeForm", e.DISPLAY_CONDITIONS = "displayConditions", e.HIDDEN_NODE = "containerHiddenNodeForm", e))(ue || {}), n = {
342
+ }, U = "esd-block-button", w = "esd-block-text", K = "esd-block-image", J = "esd-structure", ee = "esd-block-video", te = "esd-block-social", re = "esd-block-banner", ae = "esd-block-timer", ne = "esd-block-menu", se = "esd-block-html", ie = "esd-block-spacer", le = "esd-container-frame", Ee = "esd-stripe", oe = "esd-amp-form", I = ((e) => (e.BUTTON = `.${U}`, e.TEXT = `.${w}`, e.IMAGE = `.${K}`, e.STRUCTURE = `.${J}`, e.VIDEO = `.${ee}`, e.SOCIAL = `.${te}`, e.BANNER = `.${re}`, e.TIMER = `.${ae}`, e.MENU = `.${ne}`, e.HTML = `.${se}`, e.SPACER = `.${ie}`, e.CONTAINER = `.${le}`, e.STRIPE = `.${Ee}`, e.FORM = `.${oe}`, e))(I || {}), de = /* @__PURE__ */ ((e) => (e.BLOCK_IMAGE = "BLOCK_IMAGE", e.BLOCK_TEXT = "BLOCK_TEXT", e.BLOCK_BUTTON = "BLOCK_BUTTON", e.BLOCK_SPACER = "BLOCK_SPACER", e.BLOCK_VIDEO = "BLOCK_VIDEO", e.BLOCK_SOCIAL = "BLOCK_SOCIAL", e.BLOCK_BANNER = "BLOCK_BANNER", e.BLOCK_TIMER = "BLOCK_TIMER", e.BLOCK_MENU = "BLOCK_MENU", e.BLOCK_MENU_ITEM = "BLOCK_MENU_ITEM", e.BLOCK_HTML = "BLOCK_HTML", e.BLOCK_AMP_CAROUSEL = "BLOCK_AMP_CAROUSEL", e.BLOCK_AMP_ACCORDION = "BLOCK_AMP_ACCORDION", e.BLOCK_AMP_FORM = "BLOCK_AMP_FORM", e.CONTAINER = "CONTAINER", e.FORM_CONTAINER = "FORM_CONTAINER", e.STRUCTURE = "STRUCTURE", e.STRIPE = "STRIPE", e.EMPTY_CONTAINER = "EMPTY_CONTAINER", e.CUSTOM_BLOCK_LINK = "CUSTOM_BLOCK_LINK", e.CUSTOM_BLOCK_IMAGE = "CUSTOM_BLOCK_IMAGE", e.CUSTOM_BLOCK_TEXT = "CUSTOM_BLOCK_TEXT", e))(de || {}), F = /* @__PURE__ */ ((e) => (e.ANCHOR_LINK_CONTAINER = "anchorLinkFormContainer", e.APPLY_CONDITION = "applyCondition", e.APPLY_CONDITION_SWITCHER = "applyConditionSwitcher", e.BACKGROUND_COLOR = "backgroundColor", e.BACKGROUND_IMAGE = "generalImageContainer", e.TEXT_COLOR = "textColor", e.TEXT_STYLE = "textStyle", e.TEXT_SIZE = "textSize", e.TEXT_LINE_SPACING = "textLineSpacing", e.TEXT_ALIGN = "textAlign", e.FIXED_HEIGHT_SWITCHER = "fixedHeightSwitcherForm", e.HIDDEN_NODE = "hiddenNode", e.SMART_BLOCK = "smartBlock", e.SYNCHRONIZED_MODULE = "synchronizedModuleForm", e.FONT_FAMILY = "generalFontFamilyForm", e.BLOCK_INTERNAL_INDENTS = "generalBlockInternalIndents", e.STRUCTURE_INTERNAL_INDENTS = "generalStructureInternalIndents", e))(F || {}), H = /* @__PURE__ */ ((e) => (e.ADJUST_TO_WIDTH = "adjustToWidth", e.ALIGNMENT = "buttonAlignment", e.BORDER = "buttonBorder", e.BORDER_RADIUS = "buttonBorderRadius", e.COLOR = "buttonColor", e.BUTTON_BLOCK_BACKGROUND_COLOR = "buttonBlockBackgroundColor", e.EXTERNAL_INDENTS = "buttonExternalIndents", e.FIXED_HEIGHT = "buttonFixedHeightForm", e.FONT_COLOR = "buttonFontColor", e.FONT_FAMILY = "buttonFontFamily", e.FONT_SIZE = "buttonFontSize", e.FONT_WEIGHT = "buttonFontWeight", e.ICON = "buttonIconContainer", e.ICON_ALIGN = "buttonIconAlign", e.ICON_INDENT = "buttonIconIndent", e.ICON_WIDTH = "buttonIconWidth", e.IMAGE = "buttonImageForm", e.INTERNAL_INDENTS = "buttonInternalIndents", e.LINK = "buttonLink", e.MIME_TYPE = "buttonMimeTypeForm", e.SWITCHER_HOVERED_STYLES = "buttonSwitcherHoveredStylesForm", e.TEXT = "buttonText", e.TEXT_STYLE_AND_COLOR = "buttonTextStyleAndColorForm", e.HOVERED_BORDER_COLOR = "hoveredStyleBorderButtonForm", e.HOVERED_COLOR = "hoveredButtonColorForm", e.HOVERED_TEXT_COLOR = "hoveredButtonTextColorForm", e))(H || {}), k = /* @__PURE__ */ ((e) => (e.HIDDEN_NODE = "hiddenNodeText", e.PARAGRAPH_STYLE = "paragraphStyleForm", e.ALIGN = "textAlignmentForm", e.ANCHOR_CONTAINER = "textAnchorForm", e.FONT_BACKGROUND_COLOR = "textBlockFontBackgroundColor", e.TEXT_BLOCK_BACKGROUND_COLOR = "textBlockBackgroundColor", e.FONT_COLOR = "textBlockFontColor", e.TEXT_BLOCK_FONT_FAMILY = "textBlockFontFamily", e.FONT_FAMILY = "textFontFamily", e.FONT_SIZE = "textBlockFontSize", e.FONT_WEIGHT = "textBlockFontWeight", e.DIRECTION = "textBlockDirectionForm", e.INSERT_FORM = "textBlockInsertForm", e.LETTER_SPACING = "textBlockLetterSpacing", e.LINK_DATA = "textBlockLinkDataForm", e.FORMAT = "textBlockTextFormatForm", e.FIXED_HEIGHT = "textFixedHeightForm", e.INTERNAL_INDENTS = "textInternalIndents", e.LINE_HEIGHT = "textLineHeightForm", e.MIME_TYPE = "textMimeTypeForm", e.NO_LINE_WRAPS = "textNoLineWrapsForm", e))(k || {}), X = /* @__PURE__ */ ((e) => (e.ALT_TEXT = "altText", e.LINK = "blockLink", e.ALIGNMENT = "imageAlignment", e.ANCHOR_LINK_CONTAINER = "imageAnchorLinkContainerForm", e.BORDER_RADIUS = "imageBorderRadiusForm", e.IMAGE = "imageImageForm", e.EXTERNAL_INDENTS = "imageExternalIndents", e.MIME_TYPE = "imageMimeTypeForm", e.RESPONSIVE = "imageResponsive", e.ROLLOVER_IMAGE = "imageRolloverImageForm", e.ROLLOVER_SWITCHER = "imageRolloverSwitcherForm", e.SIZE = "imageSizeContainer", e))(X || {}), ue = /* @__PURE__ */ ((e) => (e.BACKGROUND_COLOR = "containerBackgroundColorForm", e.BORDER_FORM = "containerBorderForm", e.BORDER_RADIUS = "containerBorderRadiusForm", e.EXTERNAL_INDENTS = "containerExternalIndentsForm", e.IMAGE_CONTAINER = "containerImageContainerForm", e.MIME_TYPE = "containerMimeTypeForm", e.DISPLAY_CONDITIONS = "displayConditions", e.HIDDEN_NODE = "containerHiddenNodeForm", e))(ue || {}), n = {
343
343
  BLOCK_BUTTON: H,
344
344
  BLOCK_TEXT: k,
345
- BLOCK_IMAGE: p,
345
+ BLOCK_IMAGE: X,
346
346
  GENERAL: F
347
- }, Ie = /* @__PURE__ */ ((e) => (e.SAVE_AS_MODULE = "saveAsModule", e.IMPROVE_WITH_AI = "improveWithAI", e.MOVE = "move", e.COPY = "copy", e.REMOVE = "remove", e.CLEAR_CONTAINER = "clearContainer", e.EXTERNAL_DISPLAY_CONDITION = "externalDisplayCondition", e))(Ie || {}), Te = /* @__PURE__ */ ((e) => (e.previewDeviceMode = "previewDeviceMode", e.panelPosition = "panelPosition", e.themeMode = "themeMode", e))(Te || {}), ce = /* @__PURE__ */ ((e) => (e.DESKTOP = "DESKTOP", e.MOBILE = "MOBILE", e))(ce || {}), be = /* @__PURE__ */ ((e) => (e.SETTINGS = "settings", e.STYLES = "styles", e.DATA = "data", e))(be || {}), a = {
347
+ }, Ie = /* @__PURE__ */ ((e) => (e.SAVE_AS_MODULE = "saveAsModule", e.IMPROVE_WITH_AI = "improveWithAI", e.MOVE = "move", e.COPY = "copy", e.REMOVE = "remove", e.CLEAR_CONTAINER = "clearContainer", e.EXTERNAL_DISPLAY_CONDITION = "externalDisplayCondition", e))(Ie || {}), ce = /* @__PURE__ */ ((e) => (e.previewDeviceMode = "previewDeviceMode", e.panelPosition = "panelPosition", e.themeMode = "themeMode", e))(ce || {}), Te = /* @__PURE__ */ ((e) => (e.DESKTOP = "DESKTOP", e.MOBILE = "MOBILE", e))(Te || {}), be = /* @__PURE__ */ ((e) => (e.SETTINGS = "settings", e.STYLES = "styles", e.DATA = "data", e))(be || {}), a = {
348
348
  name: "name",
349
349
  disabled: "disabled"
350
350
  }, he = {
@@ -369,18 +369,19 @@ var j = {
369
369
  hint: "hint"
370
370
  }, Le = {
371
371
  ...a,
372
- type: "type"
372
+ type: "type",
373
+ icon: "icon"
373
374
  }, _e = {
374
375
  ...a,
375
376
  buttons: "buttons"
376
- }, X = {
377
+ }, p = {
377
378
  ...a,
378
379
  searchable: "searchable",
379
380
  multiSelect: "multi-select",
380
381
  placeholder: "placeholder",
381
382
  items: "items"
382
383
  }, Ce = {
383
- ...X,
384
+ ...p,
384
385
  addCustomFontOption: "add-custom-font-option"
385
386
  }, Ae = {
386
387
  ...a,
@@ -422,10 +423,10 @@ var j = {
422
423
  }, xe = {
423
424
  ...a,
424
425
  controlId: "control-id"
425
- }, ye = {
426
+ }, Pe = {
426
427
  ...a,
427
428
  expanded: "expanded"
428
- }, Pe = {
429
+ }, ye = {
429
430
  ...a,
430
431
  icon: "icon",
431
432
  position: "position"
@@ -455,7 +456,7 @@ var j = {
455
456
  LABEL: Re,
456
457
  MESSAGE: Le,
457
458
  RADIO_BUTTONS: _e,
458
- SELECTPICKER: X,
459
+ SELECTPICKER: p,
459
460
  FONT_FAMILY_SELECT: Ce,
460
461
  SWITCHER: a,
461
462
  TEXT: Me,
@@ -465,15 +466,15 @@ var j = {
465
466
  SELECT_ITEM: Ae,
466
467
  RADIO_ITEM: Se,
467
468
  NESTED_CONTROL: xe,
468
- EXPANDABLE: ye,
469
- ORDERABLE: Pe,
469
+ EXPANDABLE: Pe,
470
+ ORDERABLE: ye,
470
471
  ORDERABLE_ITEM: Ue,
471
472
  ORDERABLE_ICON: we,
472
473
  REPEATABLE: Ke,
473
474
  DRAGGABLE_BLOCK: Fe,
474
475
  AMP_FORM_SERVICE_PICKER: He,
475
476
  MULTIPLE_SELECT: ke
476
- }, pe = /* @__PURE__ */ ((e) => (e.BUTTON = "UE-BUTTON", e.CHECKBOX = "UE-CHECKBOX", e.CHECK_BUTTONS = "UE-CHECK-BUTTONS", e.COLOR = "UE-COLOR", e.COUNTER = "UE-COUNTER", e.DATEPICKER = "UE-DATEPICKER", e.LABEL = "UE-LABEL", e.MESSAGE = "UE-MESSAGE", e.RADIO_BUTTONS = "UE-RADIO-BUTTONS", e.SELECTPICKER = "UE-SELECT", e.SWITCHER = "UE-SWITCHER", e.TEXT = "UE-TEXT", e.TEXTAREA = "UE-TEXTAREA", e.CHECK_ITEM = "UE-CHECK-ITEM", e.RADIO_ITEM = "UE-RADIO-ITEM", e.SELECT_ITEM = "UE-SELECT-ITEM", e.ICON = "UE-ICON", e.MERGETAGS = "UE-MERGETAGS", e.FONT_FAMILY_SELECT = "UE-FONT-FAMILY-SELECT", e.NESTED_CONTROL = "UE-NESTED-CONTROL", e.EXPANDABLE = "UE-EXPANDABLE", e.EXPANDABLE_HEADER = "UE-EXPANDABLE_HEADER", e.EXPANDABLE_CONTENT = "UE-EXPANDABLE_CONTENT", e.ORDERABLE = "UE-ORDERABLE", e.ORDERABLE_ITEM = "UE-ORDERABLE-ITEM", e.ORDERABLE_ICON = "UE-ORDERABLE-ICON", e.REPEATABLE = "UE-REPEATABLE", e.DRAGGABLE_BLOCK = "UE-DRAGGABLE-BLOCK", e.AMP_FORM_SERVICE_PICKER = "UE-AMP-FORM-SERVICE-PICKER", e.MULTIPLE_SELECT = "UE-MULTIPLE_SELECT", e.SCROLLABLE = "UE-SCROLLABLE-CONTAINER", e))(pe || {}), x = class {
477
+ }, Xe = /* @__PURE__ */ ((e) => (e.BUTTON = "UE-BUTTON", e.CHECKBOX = "UE-CHECKBOX", e.CHECK_BUTTONS = "UE-CHECK-BUTTONS", e.COLOR = "UE-COLOR", e.COUNTER = "UE-COUNTER", e.DATEPICKER = "UE-DATEPICKER", e.LABEL = "UE-LABEL", e.MESSAGE = "UE-MESSAGE", e.RADIO_BUTTONS = "UE-RADIO-BUTTONS", e.SELECTPICKER = "UE-SELECT", e.SWITCHER = "UE-SWITCHER", e.TEXT = "UE-TEXT", e.RICH_TEXT = "UE-RICH-TEXT", e.TEXTAREA = "UE-TEXTAREA", e.CHECK_ITEM = "UE-CHECK-ITEM", e.RADIO_ITEM = "UE-RADIO-ITEM", e.SELECT_ITEM = "UE-SELECT-ITEM", e.ICON = "UE-ICON", e.MERGETAGS = "UE-MERGETAGS", e.FONT_FAMILY_SELECT = "UE-FONT-FAMILY-SELECT", e.NESTED_CONTROL = "UE-NESTED-CONTROL", e.EXPANDABLE = "UE-EXPANDABLE", e.EXPANDABLE_HEADER = "UE-EXPANDABLE_HEADER", e.EXPANDABLE_CONTENT = "UE-EXPANDABLE_CONTENT", e.ORDERABLE = "UE-ORDERABLE", e.ORDERABLE_ITEM = "UE-ORDERABLE-ITEM", e.ORDERABLE_ICON = "UE-ORDERABLE-ICON", e.REPEATABLE = "UE-REPEATABLE", e.DRAGGABLE_BLOCK = "UE-DRAGGABLE-BLOCK", e.AMP_FORM_SERVICE_PICKER = "UE-AMP-FORM-SERVICE-PICKER", e.MULTIPLE_SELECT = "UE-MULTIPLE_SELECT", e.SCROLLABLE = "UE-SCROLLABLE-CONTAINER", e.POPUP_PANEL = "UE-POPUP-PANEL", e))(Xe || {}), x = class {
477
478
  /**
478
479
  * @description returns map of nodes parent control operates on
479
480
  */
@@ -619,7 +620,7 @@ var j = {
619
620
  }
620
621
  };
621
622
  G.REQUIRED_METHODS = ["getId", "getTemplate"];
622
- var Tt = G, Xe = class m extends i {
623
+ var ct = G, pe = class m extends i {
623
624
  constructor() {
624
625
  super(m.REQUIRED_METHODS, m);
625
626
  }
@@ -688,13 +689,13 @@ var Tt = G, Xe = class m extends i {
688
689
  onDestroy() {
689
690
  }
690
691
  };
691
- Xe.REQUIRED_METHODS = ["getId", "getIcon", "getName", "getTemplate", "getTabIndex"];
692
+ pe.REQUIRED_METHODS = ["getId", "getIcon", "getName", "getTemplate", "getTabIndex"];
692
693
  var V = class extends x {
693
694
  getTargetNodes(e) {
694
695
  const t = e.querySelectorAll(I.IMAGE), r = e.asElement().hasClass(K) ? [e] : [];
695
696
  return t.length ? t : r;
696
697
  }
697
- }, ct = class extends V {
698
+ }, Tt = class extends V {
698
699
  getParentControlId() {
699
700
  return n.BLOCK_IMAGE.EXTERNAL_INDENTS;
700
701
  }
@@ -1215,17 +1216,17 @@ export {
1215
1216
  It as ButtonTextStyleAndFontColorBuiltInControl,
1216
1217
  ue as ContainerControls,
1217
1218
  Ie as ContextActionType,
1218
- Tt as Control,
1219
- Te as EditorStatePropertyType,
1219
+ ct as Control,
1220
+ ce as EditorStatePropertyType,
1220
1221
  Ve as Extension,
1221
1222
  Nt as ExtensionBuilder,
1222
1223
  F as GeneralControls,
1223
1224
  Dt as IconsRegistry,
1224
- p as ImageControls,
1225
- ct as ImageMarginsBuiltInControl,
1225
+ X as ImageControls,
1226
+ Tt as ImageMarginsBuiltInControl,
1226
1227
  bt as ImageSizeBuiltInControl,
1227
1228
  St as ModificationDescription,
1228
- ce as PreviewDeviceMode,
1229
+ Te as PreviewDeviceMode,
1229
1230
  ht as SettingsPanelRegistry,
1230
1231
  mt as SettingsPanelTab,
1231
1232
  be as SettingsTab,
@@ -1240,5 +1241,5 @@ export {
1240
1241
  et as UEAttr,
1241
1242
  Mt as UIElement,
1242
1243
  Bt as UIElementTagRegistry,
1243
- pe as UIElementType
1244
+ Xe as UIElementType
1244
1245
  };
@@ -1,4 +1,4 @@
1
- const o = { stripo: { version: "2.73.0" } }, s = {
1
+ const o = { stripo: { version: "2.76.0" } }, s = {
2
2
  guido: o
3
3
  };
4
4
  export {
@@ -4,13 +4,14 @@ import { useToaster as C } from "../composables/useToaster.js";
4
4
  import { useTranslations as h } from "../composables/useTranslations.js";
5
5
  import { useLiquidValidator as S } from "../composables/validators/useLiquidValidator.js";
6
6
  import { EditorType as v } from "../enums/defaults.js";
7
- import { ToasterTypeOptions as N } from "../enums/toaster.js";
8
- import { useRecommendationExtensionStore as x } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
- import { useSaveAsTemplateStore as E } from "../stores/save-as-template.js";
7
+ import { ToasterTypeOptions as x } from "../enums/toaster.js";
8
+ import { useRecommendationExtensionStore as E } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
+ import { useSaveAsTemplateStore as N } from "../stores/save-as-template.js";
10
10
  import { base64EncodeWithSpecialChars as r } from "../utils/base64.js";
11
+ import { isPlainObject as P } from "../utils/genericUtil.js";
11
12
  import { useTemplatePreparation as A } from "../utils/templatePreparation.js";
12
- const j = () => {
13
- const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: g } = S(), u = h();
13
+ const B = () => {
14
+ const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: f } = S(), u = h();
14
15
  return {
15
16
  getCategories: async () => {
16
17
  try {
@@ -40,10 +41,10 @@ const j = () => {
40
41
  createTemplate: async () => {
41
42
  var e, t, d, y;
42
43
  try {
43
- const { prepareTemplateDetails: i } = A(), s = E(), a = await i();
44
- if (p("liquidSyntax") && !await g(a.compiledHtml))
44
+ const { prepareTemplateDetails: i } = A(), s = N(), a = await i();
45
+ if (p("liquidSyntax") && !await f(a.compiledHtml))
45
46
  return !1;
46
- const f = {
47
+ const T = {
47
48
  name: s.getTemplateName,
48
49
  categories: s.getSelectedCategoryIds,
49
50
  productId: ((t = (e = c.value) == null ? void 0 : e.partner) == null ? void 0 : t.productType) || 0,
@@ -54,7 +55,7 @@ const j = () => {
54
55
  unsubscriptionPreferencePageStatus: !1,
55
56
  unsubscriptionPreferencePages: [],
56
57
  recommendationCampaignUrls: r(
57
- x().recommendationCampaignUrls
58
+ E().recommendationCampaignUrls
58
59
  ),
59
60
  recommendationConfigs: r({}),
60
61
  isGuido: !0,
@@ -66,16 +67,18 @@ const j = () => {
66
67
  css: a.css,
67
68
  dynamicContentList: a.dynamicContentList
68
69
  })
69
- }, { data: { type: T } } = await m(
70
+ }, { data: g } = await m(
70
71
  "/newsletter/template-library/create-template",
71
- f
72
+ T
72
73
  );
73
- return T === "alert" ? (l({
74
+ if (!P(g))
75
+ throw new Error("Unexpected create-template response");
76
+ return g.type === "alert" ? (l({
74
77
  message: u(
75
78
  "newsletter.template-library-save-alert",
76
79
  { templateName: s.getTemplateName }
77
80
  ),
78
- type: N.Error
81
+ type: x.Error
79
82
  }), !1) : (l({
80
83
  message: u(
81
84
  "newsletter.template-library-save-success",
@@ -90,5 +93,5 @@ const j = () => {
90
93
  };
91
94
  };
92
95
  export {
93
- j as useTemplateLibraryApi
96
+ B as useTemplateLibraryApi
94
97
  };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2
+ export default _default;
@@ -5,7 +5,9 @@ export declare const URLS: {
5
5
  PRODUCT_ATTRIBUTES_PATH: string;
6
6
  RECOMMENDATION_STRATEGIES_PATH: string;
7
7
  RECOMMENDATION_STRATEGIES_PANEL_PATH: string;
8
+ RECOMMENDATION_STRATEGY_CREATE_PATH: string;
8
9
  };
10
+ export declare const strategyEditPath: (strategyId: string | number) => string;
9
11
  export declare const QUERY_PARAMS: {
10
12
  CLIENT_ID: string;
11
13
  };
@@ -10,6 +10,7 @@
10
10
  import type { RecommendationNodeConfig, CurrencyConfig, OmnibusTextConfig } from '../types/nodeConfig';
11
11
  export declare const PRE_RRS_CONFIG_VERSION = 1;
12
12
  export declare const CURRENT_CONFIG_VERSION = 2;
13
+ export declare const RRS_CONFIG_VERSION = 2;
13
14
  /**
14
15
  * Default currency configuration
15
16
  * Uses USD as the base currency with standard formatting
@@ -10,4 +10,4 @@ export { RecommendationBlockId } from './blockIds';
10
10
  export { RecommendationControlId } from './controlIds';
11
11
  export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CSS_CLASS_SKIP_COMPILE, RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_RECOMMENDATION_TITLE, SELECTOR_TITLE_CELL, ATTR_CUSTOM_PREFIX, ATTR_DATA_CARD_COMPOSITION, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, CSS_CLASS_ATTRIBUTE_ROW, CSS_CLASS_SPACER, SELECTOR_ATTRIBUTE_ROW, ATTR_DATA_ATTRIBUTE_TYPE, ATTR_DATA_VISIBILITY, PRODUCT_ATTRIBUTE_PREFIX, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
12
12
  export { LAYOUT_VALUES, LAYOUT_OPTIONS, DEFAULT_PRODUCTS_PER_ROW, DEFAULT_CARDS_IN_ROW, DEFAULT_MOBILE_CARDS_IN_ROW, MAX_PRODUCT_COUNT, MIN_PRODUCT_COUNT, MAX_PRODUCTS_PER_ROW, MIN_PRODUCTS_PER_ROW, MAX_MOBILE_PRODUCTS_PER_ROW, MIN_MOBILE_PRODUCTS_PER_ROW, DEFAULT_COLUMN_SPACING, DEFAULT_ROW_SPACING, DEFAULT_MOBILE_COLUMN_SPACING, DEFAULT_MOBILE_ROW_SPACING, MIN_SPACING, MAX_SPACING, SPACING_STEP, } from './layout';
13
- export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, PRE_RRS_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
13
+ export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, PRE_RRS_CONFIG_VERSION, RRS_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
@@ -20,7 +20,6 @@ export * from './utils';
20
20
  export declare class RecommendationBlockControl extends CommonControl {
21
21
  private store;
22
22
  private storeUnsubscription;
23
- private syncedConfigs;
24
23
  private pendingNodeConfigWrite;
25
24
  private pendingConfigFlushTimer;
26
25
  private algorithmControl;
@@ -64,8 +63,15 @@ export declare class RecommendationBlockControl extends CommonControl {
64
63
  * fingerprint diff on this hook is the only way to notice (SD-149105).
65
64
  * An unchanged fingerprint means the move came from us, so runtime store
66
65
  * edits are never clobbered (SD-141049).
66
+ *
67
+ * The fingerprint is kept on the block's own store state so deleting the
68
+ * block drops it with the state it describes. A control-owned memo outlived
69
+ * that state and made a re-dropped saved module keep the defaults its wiped
70
+ * state was rebuilt with (SD-150347).
67
71
  */
68
72
  private _syncNodeConfigIfChanged;
73
+ /** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
74
+ private _isPendingStrategyIdChange;
69
75
  private _capturePendingNodeConfigWrite;
70
76
  /**
71
77
  * Accumulates the pending write into `documentModifier` without applying, so the
@@ -2,6 +2,7 @@ import { CommonControl } from '../../../common-control';
2
2
  export declare const STRATEGY_CONTROL_ID = "recommendation-strategy-control";
3
3
  export declare class StrategyControl extends CommonControl {
4
4
  private store;
5
+ private onboardingStore;
5
6
  private storeUnsubscription;
6
7
  private listeners;
7
8
  private lastPaintedState;
@@ -9,6 +10,14 @@ export declare class StrategyControl extends CommonControl {
9
10
  getTemplate(): string;
10
11
  private _strategyAction;
11
12
  onRender(): void;
13
+ /**
14
+ * Whether the document itself says this block has no strategy.
15
+ *
16
+ * Read the node, not the store: when the main control cannot resolve the block id off the
17
+ * node it never syncs the persisted config, so the store still holds defaults (empty
18
+ * strategyId) for an assigned block.
19
+ */
20
+ private _isNodeUnassigned;
12
21
  onDestroy(): void;
13
22
  private _teardown;
14
23
  private _setupButtonListeners;
@@ -107,7 +107,7 @@ export interface RegenerateWithStylesOptions extends Omit<RegenerateProductRowsO
107
107
  * HTML removes the need for any post-rebuild reapply pass.
108
108
  * @param options - Configuration options for regeneration
109
109
  */
110
- export declare function regenerateProductRowsWithStyles(options: RegenerateWithStylesOptions): void;
110
+ export declare function regenerateProductRowsWithStyles(options: RegenerateWithStylesOptions): boolean;
111
111
  /**
112
112
  * Adjusts a products array to a target size.
113
113
  * Used by ProductLayoutControl to synchronously match products to the new size
@@ -151,6 +151,11 @@ export interface UpdateProductContentInPlaceOptions {
151
151
  currentNode: ImmutableHtmlNode | null | undefined;
152
152
  documentModifier: DocumentModifier;
153
153
  products: RecommendationProduct[];
154
+ /**
155
+ * Called when the batch was actually committed. Identical products commit nothing, which
156
+ * leaves anything a caller staged into the same batch unwritten unless it applies itself.
157
+ */
158
+ onApplied?: () => void;
154
159
  }
155
160
  /**
156
161
  * Updates product content in-place without regenerating HTML structure.
@@ -161,7 +166,7 @@ export interface UpdateProductContentInPlaceOptions {
161
166
  * After updating desktop, also updates mobile container to keep them in sync.
162
167
  *
163
168
  * Falls back to false when product count changed (need to add/remove elements).
164
- * @param options - Configuration options
169
+ * @param options - Configuration options; `onApplied` fires only when a batch was committed
165
170
  * @returns true if in-place update was successful, false to fall back to full regeneration
166
171
  */
167
172
  export declare function updateProductContentInPlace(options: UpdateProductContentInPlaceOptions): boolean;
@@ -41,6 +41,16 @@ interface PerBlockState {
41
41
  isInitialized: boolean;
42
42
  /** Snapshot of filters taken when the drawer opens, used to revert on cancel */
43
43
  filterSnapshot: Filter[] | null;
44
+ /**
45
+ * Fingerprint of the node config as this block's state last adopted it.
46
+ *
47
+ * Lives here, not on the control, because it is a claim ABOUT this state —
48
+ * "the store already holds that node config". Held on the control it
49
+ * outlived the state it described: `removeBlockState` tore the state down
50
+ * while the fingerprint survived, so re-dropping a saved module under the
51
+ * same id skipped the re-sync and kept the defaults (SD-150347).
52
+ */
53
+ syncedConfigFingerprint: string | null;
44
54
  }
45
55
  /**
46
56
  * Persisted-config subset used by `seedBlockUrlConfig` to reconstruct
@@ -57,6 +67,8 @@ export interface PerBlockUrlConfig {
57
67
  filters: Filter[];
58
68
  shuffleProducts: boolean;
59
69
  currencyCode: string;
70
+ /** The displayed symbol, which is not the code — a TRY block shows `₺`. */
71
+ currencySymbol: string;
60
72
  currencyAlignment: 'before' | 'after';
61
73
  currencyDecimalCount: number;
62
74
  currencyDecimalSeparator: string;
@@ -71,8 +83,11 @@ interface StoreState {
71
83
  strategies: RrsStrategy[];
72
84
  strategiesLoading: boolean;
73
85
  strategyUrlTemplates: Record<string, string>;
86
+ strategiesFetched: boolean;
87
+ strategiesSettled: boolean;
74
88
  blockStates: Record<number, PerBlockState>;
75
89
  currentRecommendationId: number | null;
90
+ strategyPanelOpen: boolean;
76
91
  configVersion: number;
77
92
  }
78
93
  export declare const useRecommendationExtensionStore: import("pinia").StoreDefinition<"guidoRecommendationExtension", StoreState, {
@@ -99,8 +114,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
99
114
  }[];
100
115
  strategiesLoading: boolean;
101
116
  strategyUrlTemplates: Record<string, string>;
117
+ strategiesFetched: boolean;
118
+ strategiesSettled: boolean;
102
119
  blockStates: Record<number, PerBlockState>;
103
120
  currentRecommendationId: number | null;
121
+ strategyPanelOpen: boolean;
104
122
  configVersion: number;
105
123
  } & import("pinia").PiniaCustomStateProperties<StoreState>): PerBlockConfigs;
106
124
  /**
@@ -125,8 +143,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
125
143
  }[];
126
144
  strategiesLoading: boolean;
127
145
  strategyUrlTemplates: Record<string, string>;
146
+ strategiesFetched: boolean;
147
+ strategiesSettled: boolean;
128
148
  blockStates: Record<number, PerBlockState>;
129
149
  currentRecommendationId: number | null;
150
+ strategyPanelOpen: boolean;
130
151
  configVersion: number;
131
152
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RecommendationProduct[];
132
153
  /**
@@ -151,8 +172,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
151
172
  }[];
152
173
  strategiesLoading: boolean;
153
174
  strategyUrlTemplates: Record<string, string>;
175
+ strategiesFetched: boolean;
176
+ strategiesSettled: boolean;
154
177
  blockStates: Record<number, PerBlockState>;
155
178
  currentRecommendationId: number | null;
179
+ strategyPanelOpen: boolean;
156
180
  configVersion: number;
157
181
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
158
182
  assignStrategyDrawerStatus(state: {
@@ -174,8 +198,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
174
198
  }[];
175
199
  strategiesLoading: boolean;
176
200
  strategyUrlTemplates: Record<string, string>;
201
+ strategiesFetched: boolean;
202
+ strategiesSettled: boolean;
177
203
  blockStates: Record<number, PerBlockState>;
178
204
  currentRecommendationId: number | null;
205
+ strategyPanelOpen: boolean;
179
206
  configVersion: number;
180
207
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
181
208
  removeStrategyModalStatus(state: {
@@ -197,8 +224,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
197
224
  }[];
198
225
  strategiesLoading: boolean;
199
226
  strategyUrlTemplates: Record<string, string>;
227
+ strategiesFetched: boolean;
228
+ strategiesSettled: boolean;
200
229
  blockStates: Record<number, PerBlockState>;
201
230
  currentRecommendationId: number | null;
231
+ strategyPanelOpen: boolean;
202
232
  configVersion: number;
203
233
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
204
234
  assignedStrategy(state: {
@@ -220,8 +250,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
220
250
  }[];
221
251
  strategiesLoading: boolean;
222
252
  strategyUrlTemplates: Record<string, string>;
253
+ strategiesFetched: boolean;
254
+ strategiesSettled: boolean;
223
255
  blockStates: Record<number, PerBlockState>;
224
256
  currentRecommendationId: number | null;
257
+ strategyPanelOpen: boolean;
225
258
  configVersion: number;
226
259
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
227
260
  /**
@@ -246,8 +279,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
246
279
  }[];
247
280
  strategiesLoading: boolean;
248
281
  strategyUrlTemplates: Record<string, string>;
282
+ strategiesFetched: boolean;
283
+ strategiesSettled: boolean;
249
284
  blockStates: Record<number, PerBlockState>;
250
285
  currentRecommendationId: number | null;
286
+ strategyPanelOpen: boolean;
251
287
  configVersion: number;
252
288
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
253
289
  /**
@@ -272,8 +308,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
272
308
  }[];
273
309
  strategiesLoading: boolean;
274
310
  strategyUrlTemplates: Record<string, string>;
311
+ strategiesFetched: boolean;
312
+ strategiesSettled: boolean;
275
313
  blockStates: Record<number, PerBlockState>;
276
314
  currentRecommendationId: number | null;
315
+ strategyPanelOpen: boolean;
277
316
  configVersion: number;
278
317
  } & import("pinia").PiniaCustomStateProperties<StoreState>): number;
279
318
  hasFilters(): boolean;
@@ -299,8 +338,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
299
338
  }[];
300
339
  strategiesLoading: boolean;
301
340
  strategyUrlTemplates: Record<string, string>;
341
+ strategiesFetched: boolean;
342
+ strategiesSettled: boolean;
302
343
  blockStates: Record<number, PerBlockState>;
303
344
  currentRecommendationId: number | null;
345
+ strategyPanelOpen: boolean;
304
346
  configVersion: number;
305
347
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
306
348
  text: string;
@@ -325,8 +367,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
325
367
  }[];
326
368
  strategiesLoading: boolean;
327
369
  strategyUrlTemplates: Record<string, string>;
370
+ strategiesFetched: boolean;
371
+ strategiesSettled: boolean;
328
372
  blockStates: Record<number, PerBlockState>;
329
373
  currentRecommendationId: number | null;
374
+ strategyPanelOpen: boolean;
330
375
  configVersion: number;
331
376
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
332
377
  text: string;
@@ -351,8 +396,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
351
396
  }[];
352
397
  strategiesLoading: boolean;
353
398
  strategyUrlTemplates: Record<string, string>;
399
+ strategiesFetched: boolean;
400
+ strategiesSettled: boolean;
354
401
  blockStates: Record<number, PerBlockState>;
355
402
  currentRecommendationId: number | null;
403
+ strategyPanelOpen: boolean;
356
404
  configVersion: number;
357
405
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
358
406
  text: string;
@@ -433,6 +481,40 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
433
481
  openRemoveStrategyModal(): void;
434
482
  closeRemoveStrategyModal(): void;
435
483
  fetchStrategies(): Promise<void>;
484
+ invalidateStrategies(): void;
485
+ /**
486
+ * Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
487
+ * the user comes back. `visibilitychange` only: a `focus` listener would also fire when
488
+ * focus merely returns from the Stripo canvas iframe to the panel, refetching and
489
+ * regenerating the canvas while the user never left the editor (SD-149916).
490
+ *
491
+ * Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
492
+ * strategy in it and come back again — a listener that disarmed on the first return would
493
+ * leave that one missing from the list. It disarms on the first return AFTER that tab is
494
+ * closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
495
+ * once the user actually opens a strategy page, so anyone who never does pays nothing.
496
+ */
497
+ _armStrategyPageReturn(url: string): void;
498
+ /**
499
+ * Reloads the products of the block the user is on, so an edit made in the strategy tab
500
+ * lands on the canvas instead of waiting for the assign drawer to be reopened.
501
+ *
502
+ * Only the selected block: the canvas regeneration is driven off the active block's
503
+ * product array, so refreshing an unselected block would fetch without redrawing it.
504
+ */
505
+ _refreshAssignedStrategyProducts(): Promise<void>;
506
+ /** Lets the editor tear the return listeners down when it unmounts. */
507
+ disposeStrategyPageReturn(): void;
508
+ /**
509
+ * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
510
+ * new strategy is offered; the user picks it themselves.
511
+ */
512
+ openStrategyCreation(): void;
513
+ /**
514
+ * Opens the strategy's edit page. Every return refreshes the list so the block reflects the
515
+ * edited configuration.
516
+ */
517
+ openStrategyEdit(strategyId: string | number): void;
436
518
  resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
437
519
  assignStrategy(strategy: RrsStrategy): void;
438
520
  removeStrategy(): void;
@@ -450,6 +532,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
450
532
  * every block's recommendationConfigs across user edits.
451
533
  */
452
534
  hasInvalidBlock(): boolean;
535
+ /**
536
+ * Which required fields are missing across the design's blocks, so the save
537
+ * toaster can name the cause instead of always showing the generic message.
538
+ */
539
+ invalidBlockFields(): string[];
453
540
  fetchRecommendationProducts(): Promise<void>;
454
541
  _doFetchProducts(): Promise<void>;
455
542
  _doFetchStrategyProducts(blockId: number): Promise<void>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Writes a strategy change and its products straight to the document, without the settings panel.
3
+ *
4
+ * Every entry point is host-rendered UI outside `ui-editor`, and none of them can rely on the
5
+ * panel control: opening the strategy page deselects the block, so by the time the user comes back
6
+ * and presses Assign the control — and with it the subscription that does the node write, the
7
+ * product fetch and the repaint — is gone. The assignment then reaches Pinia and nothing else
8
+ * (SD-149916).
9
+ *
10
+ * Call AFTER the store change (`assignStrategy` / `removeStrategy`).
11
+ * @param description - labels the undo entry
12
+ * @returns whether the write reached a node
13
+ */
14
+ export declare function commitStrategyChange(blockId: number, description: string): Promise<boolean>;
@@ -15,7 +15,11 @@ export interface RequiredField {
15
15
  getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
16
16
  condition?: (config: PerBlockConfigs) => boolean;
17
17
  }
18
+ /** Field key of the strategy/algorithm descriptor, used to pick the toaster message. */
19
+ export declare const STRATEGY_FIELD_KEY = "strategy";
18
20
  export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
19
21
  export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
22
+ /** Shown instead of the generic message when the only thing missing is the strategy. */
23
+ export declare const RecommendationAssignStrategyKey = "newsletter.recommendation-assign-strategy";
20
24
  export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
21
25
  export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;