@useinsider/guido 3.18.2-beta.ec25841 → 3.18.2-beta.eedafd2

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 (81) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +28 -26
  3. package/dist/components/Guido.vue.js +6 -6
  4. package/dist/components/Guido.vue2.js +72 -70
  5. package/dist/components/organisms/AutoSaveController.vue2.js +9 -8
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +11 -13
  7. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +52 -70
  8. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +37 -23
  9. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  10. package/dist/components/organisms/header/EditorActions.vue2.js +86 -56
  11. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  12. package/dist/components/organisms/header/LeftSlot.vue2.js +16 -12
  13. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
  14. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +34 -34
  15. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +20 -0
  16. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +48 -0
  17. package/dist/components/wrappers/WpDrawer.vue.js +9 -7
  18. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  19. package/dist/composables/useCustomInterfaceAppearance.js +46 -56
  20. package/dist/composables/useHtmlCompiler.js +37 -26
  21. package/dist/composables/useHtmlValidator.js +81 -84
  22. package/dist/composables/useHttp.js +24 -22
  23. package/dist/composables/useRecommendation.js +35 -40
  24. package/dist/composables/useSave.js +90 -45
  25. package/dist/composables/useSaveValidation.js +279 -0
  26. package/dist/composables/useSaveValidationRollout.js +9 -0
  27. package/dist/composables/useStripo.js +30 -30
  28. package/dist/composables/validators/useCouponBlockValidator.js +24 -21
  29. package/dist/composables/validators/useUnsubscribeBlockValidator.js +34 -27
  30. package/dist/enums/extensions/recommendationBlock.js +31 -38
  31. package/dist/enums/save-validation.js +4 -0
  32. package/dist/extensions/Blocks/Recommendation/block.js +39 -43
  33. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
  34. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +33 -38
  35. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -84
  36. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +78 -168
  37. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
  38. package/dist/guido.css +1 -1
  39. package/dist/services/templateLibraryApi.js +17 -14
  40. package/dist/src/@types/config/schemas.d.ts +4 -0
  41. package/dist/src/@types/save-validation.d.ts +19 -0
  42. package/dist/src/components/Guido.vue.d.ts +17 -1
  43. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +17 -1
  44. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +17 -1
  45. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +17 -1
  46. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +4 -3
  47. package/dist/src/composables/useConfig.d.ts +2 -0
  48. package/dist/src/composables/useHtmlValidator.d.ts +21 -0
  49. package/dist/src/composables/useSave.d.ts +6 -1
  50. package/dist/src/composables/useSaveValidation.d.ts +6 -0
  51. package/dist/src/composables/useSaveValidationRollout.d.ts +3 -0
  52. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  53. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +10 -0
  54. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
  55. package/dist/src/enums/save-validation.d.ts +27 -0
  56. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
  57. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  58. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
  59. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -9
  60. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +3 -73
  61. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
  62. package/dist/src/stores/config.d.ts +30 -0
  63. package/dist/src/stores/onboarding.d.ts +0 -377
  64. package/dist/src/stores/save-validation.d.ts +22 -0
  65. package/dist/src/utils/genericUtil.d.ts +6 -0
  66. package/dist/src/utils/liquidDynamicContent.d.ts +20 -0
  67. package/dist/src/utils/templatePreparation.d.ts +30 -0
  68. package/dist/static/styles/components/recommendation-strategy.css.js +4 -34
  69. package/dist/stores/config.js +39 -22
  70. package/dist/stores/onboarding.js +36 -41
  71. package/dist/stores/save-validation.js +30 -0
  72. package/dist/utils/genericUtil.js +63 -54
  73. package/dist/utils/liquidDynamicContent.js +15 -0
  74. package/dist/utils/templatePreparation.js +63 -59
  75. package/package.json +1 -1
  76. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +0 -21
  77. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +0 -47
  78. package/dist/extensions/Blocks/Recommendation/utils/strategyDetach.js +0 -19
  79. package/dist/src/extensions/Blocks/Recommendation/utils/strategyDetach.d.ts +0 -12
  80. package/dist/static/styles/components/skeleton.css.js +0 -23
  81. /package/dist/src/components/organisms/{onboarding/RecommendationStrategyOnboarding.vue.d.ts → validation/ValidationErrorDrawer.vue.d.ts} +0 -0
@@ -15,7 +15,23 @@ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_T
15
15
  close: () => void;
16
16
  };
17
17
  hasChanges: import("vue").ComputedRef<boolean>;
18
- saveSilent: () => Promise<Omit<SavedTemplateDetails, "metadata" | "silent"> | undefined> | undefined;
18
+ saveSilent: () => Promise<{
19
+ dynamicContentList: import("@@/Types/generic").DynamicContent[];
20
+ compiledHtml: string;
21
+ rawHtml: string;
22
+ css: string;
23
+ ampHtml: string;
24
+ ampErrors: string[];
25
+ modules: number[];
26
+ recommendation: {
27
+ campaignUrls: Record<string, import("../@types/recommendation").RecommendationCampaignUrlValue>;
28
+ configs: Record<string, string>;
29
+ };
30
+ unsubscribe: {
31
+ status: boolean;
32
+ config: number[];
33
+ };
34
+ } | undefined> | undefined;
19
35
  setLoading: (value: boolean) => void;
20
36
  }, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {
21
37
  "dynamic-content:open": (detail: {
@@ -1,4 +1,20 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
- handleSave: (isSilent: boolean) => Promise<Omit<import("../../../@types/stripo.js").SavedTemplateDetails, "metadata" | "silent"> | undefined> | undefined;
2
+ handleSave: (isSilent: boolean) => Promise<{
3
+ dynamicContentList: import("../../../@types/generic.js").DynamicContent[];
4
+ compiledHtml: string;
5
+ rawHtml: string;
6
+ css: string;
7
+ ampHtml: string;
8
+ ampErrors: string[];
9
+ modules: number[];
10
+ recommendation: {
11
+ campaignUrls: Record<string, import("../../../@types/recommendation.js").RecommendationCampaignUrlValue>;
12
+ configs: Record<string, string>;
13
+ };
14
+ unsubscribe: {
15
+ status: boolean;
16
+ config: number[];
17
+ };
18
+ } | undefined> | undefined;
3
19
  }, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
4
20
  export default _default;
@@ -1,4 +1,20 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
- handleSave: (isSilent: boolean) => Promise<Omit<import("../../../@types/stripo.js").SavedTemplateDetails, "metadata" | "silent"> | undefined> | undefined;
2
+ handleSave: (isSilent: boolean) => Promise<{
3
+ dynamicContentList: import("../../../@types/generic.js").DynamicContent[];
4
+ compiledHtml: string;
5
+ rawHtml: string;
6
+ css: string;
7
+ ampHtml: string;
8
+ ampErrors: string[];
9
+ modules: number[];
10
+ recommendation: {
11
+ campaignUrls: Record<string, import("../../../@types/recommendation.js").RecommendationCampaignUrlValue>;
12
+ configs: Record<string, string>;
13
+ };
14
+ unsubscribe: {
15
+ status: boolean;
16
+ config: number[];
17
+ };
18
+ } | undefined> | undefined;
3
19
  }, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
4
20
  export default _default;
@@ -1,4 +1,20 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
- handleSave: (isSilent: boolean) => Promise<Omit<import("../../../@types/stripo.js").SavedTemplateDetails, "metadata" | "silent"> | undefined> | undefined;
2
+ handleSave: (isSilent: boolean) => Promise<{
3
+ dynamicContentList: import("../../../@types/generic.js").DynamicContent[];
4
+ compiledHtml: string;
5
+ rawHtml: string;
6
+ css: string;
7
+ ampHtml: string;
8
+ ampErrors: string[];
9
+ modules: number[];
10
+ recommendation: {
11
+ campaignUrls: Record<string, import("../../../@types/recommendation.js").RecommendationCampaignUrlValue>;
12
+ configs: Record<string, string>;
13
+ };
14
+ unsubscribe: {
15
+ status: boolean;
16
+ config: number[];
17
+ };
18
+ } | undefined> | undefined;
3
19
  }, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
4
20
  export default _default;
@@ -10,11 +10,11 @@ interface Props {
10
10
  status: boolean;
11
11
  titleText: string;
12
12
  }
13
- declare var __VLS_12: {}, __VLS_14: {};
13
+ declare var __VLS_13: {}, __VLS_15: {};
14
14
  type __VLS_Slots = {} & {
15
- headerBottomSlot?: (props: typeof __VLS_12) => any;
15
+ headerBottomSlot?: (props: typeof __VLS_13) => any;
16
16
  } & {
17
- default?: (props: typeof __VLS_14) => any;
17
+ default?: (props: typeof __VLS_15) => any;
18
18
  };
19
19
  declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<Props>, {
20
20
  className: string;
@@ -26,6 +26,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<
26
26
  cancelOrBackButtonEvent: () => void;
27
27
  onCloseEvent: () => void;
28
28
  primaryButtonEvent: () => void;
29
+ secondaryButtonEvent: () => void;
29
30
  }, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<Props>, {
30
31
  className: string;
31
32
  size: string;
@@ -99,6 +99,7 @@ export declare const useConfig: () => {
99
99
  autosave: boolean;
100
100
  allowlistEnabled: boolean;
101
101
  linkTrackingIds: boolean;
102
+ allowSaveWithErrors: boolean;
102
103
  reusableRecommendationStrategy: boolean;
103
104
  };
104
105
  blocks: {
@@ -234,6 +235,7 @@ export declare const useConfig: () => {
234
235
  autosave: boolean;
235
236
  allowlistEnabled: boolean;
236
237
  linkTrackingIds: boolean;
238
+ allowSaveWithErrors: boolean;
237
239
  reusableRecommendationStrategy: boolean;
238
240
  } | null>;
239
241
  blocks: import("vue").ComputedRef<{
@@ -1,5 +1,12 @@
1
1
  import type { DynamicContent } from '@@/Types/generic';
2
2
  import type { FiltersResponse } from '@@/Types/recommendation';
3
+ /**
4
+ * Extracts recommendation block IDs directly from the HTML by parsing
5
+ * the recommendation-id attribute on block elements.
6
+ * This avoids depending on store state which may not be populated
7
+ * when the settings panel hasn't been opened yet (e.g., saved templates).
8
+ */
9
+ export declare function getRecommendationBlockIds(html: string): string[];
3
10
  /**
4
11
  * Parses a `{{recoId_index_attributeName}}` variable (already stripped of the
5
12
  * braces/whitespace) into its recommendation id and attribute name. Returns
@@ -27,6 +34,20 @@ export declare function buildPartnerAttributeNameSet(filterList: FiltersResponse
27
34
  * before, so flagging it would false-positive on merge tags like `{{user.name}}`.
28
35
  */
29
36
  export declare function findInvalidCustomFields(html: string, validCustomFields: string[], recommendationBlockIds: string[], ignoredIds: Set<string>, ignoredAttributeNames: Set<string> | null): string[];
37
+ /**
38
+ * Returns the invalid `{{ ... }}` dynamic-content tags found in the HTML.
39
+ *
40
+ * A tag's variable name is the part before the first `|` (everything after it is the fallback).
41
+ * Surrounding whitespace is always allowed (trimmed). A tag is valid only when the variable name
42
+ * is an allowed system token, or it is a clean identifier (`[A-Za-z0-9_.]`) and — when a `|` is
43
+ * present — the fallback after it is not empty. Otherwise the tag is invalid (e.g.
44
+ * `{{Api Response: OA1 Main Item Url}}` — spaces/`:` — or `{{bounce|}}` — empty fallback).
45
+ *
46
+ * `data-*` block-config attribute values are excluded from the scan: blocks such as Items/cart
47
+ * store product merge tags (`data-product_button_link="{{Abandoned Cart Item (1) Url}}"`) that the
48
+ * backend resolves through its own pipeline, so they must not be treated as user-authored tags.
49
+ */
50
+ export declare function getInvalidDynamicContentTags(html: string): string[];
30
51
  export declare const useHtmlValidator: () => {
31
52
  validateHtml: (html: string, customFields: DynamicContent[], isOnSaveValidation?: boolean) => Promise<boolean>;
32
53
  };
@@ -1,4 +1,9 @@
1
1
  import type { SavedTemplateDetails } from '@@/Types/stripo';
2
+ type SaveDetails = Omit<SavedTemplateDetails, 'metadata' | 'silent'>;
3
+ type SaveResult = SaveDetails | undefined;
2
4
  export declare const useSave: () => {
3
- save: (suppressEmit?: boolean, silent?: boolean) => Promise<Omit<SavedTemplateDetails, "metadata" | "silent"> | undefined>;
5
+ save: (suppressEmit?: boolean, silent?: boolean) => Promise<SaveResult>;
6
+ saveWithErrors: () => Promise<SaveResult>;
7
+ saveRawOnly: () => Promise<SaveResult>;
4
8
  };
9
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { DynamicContent } from '@@/Types/generic';
2
+ import type { SaveValidationError } from '@@/Types/save-validation';
3
+ export declare const useSaveValidation: () => {
4
+ collectSaveValidationErrors: (compiledHtml: string, dynamicContentList: DynamicContent[]) => Promise<SaveValidationError[]>;
5
+ validateCurrentTemplate: () => Promise<SaveValidationError[]>;
6
+ };
@@ -0,0 +1,3 @@
1
+ export declare const useSaveValidationRollout: () => {
2
+ isEnabled: import("vue").ComputedRef<boolean>;
3
+ };
@@ -1,3 +1,6 @@
1
+ export declare const COUPON_TAG_MODIFIED_KEY = "newsletter.coupon-tag-modified";
2
+ /** Pure core: the tag text of every coupon block whose code was modified. */
3
+ export declare function findInvalidCouponBlocks(html: string): string[];
1
4
  export declare const useCouponBlockValidator: () => {
2
5
  validateCouponBlockTags: (html: string) => boolean;
3
6
  };
@@ -1,4 +1,14 @@
1
+ declare const SINGLETON_BLOCK_RULES: {
2
+ pageType: number;
3
+ messageKey: string;
4
+ }[];
5
+ export declare const EMPTY_BLOCK_KEY = "unsubscription-preference.select-page-to-continue";
6
+ /** Pure core: the singleton rules whose page type appears more than once. */
7
+ export declare function findDuplicateUnsubPageTypes(html: string): typeof SINGLETON_BLOCK_RULES;
8
+ /** Pure core: count of unsubscribe blocks with no page type or page list chosen. */
9
+ export declare function countUnsubBlocksWithoutPage(html: string): number;
1
10
  export declare const useUnsubscribeBlockValidator: () => {
2
11
  validateUnsubscribeBlockUniqueness: (html: string) => boolean;
3
12
  validateUnsubscribeBlockHasTemplate: (html: string) => boolean;
4
13
  };
14
+ export {};
@@ -5,9 +5,7 @@ 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;
9
8
  };
10
- export declare const strategyEditPath: (strategyId: string | number) => string;
11
9
  export declare const QUERY_PARAMS: {
12
10
  CLIENT_ID: string;
13
11
  };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Stable discriminators for each save-validation rule site — one per rule that
3
+ * can produce a drawer row, kept in sync with the collector + legacy validator chains.
4
+ */
5
+ export declare enum SaveValidationRule {
6
+ CouponTagModified = "coupon-tag-modified",
7
+ DuplicateUnsubBlock = "duplicate-unsub-block",
8
+ UnsubBlockMissingTemplate = "unsub-block-missing-template",
9
+ LiquidSyntax = "liquid-syntax",
10
+ InvalidLinks = "invalid-links",
11
+ LinkCheckInProgress = "link-check-in-progress",
12
+ CustomFieldScript = "custom-field-script",
13
+ EmptyHtml = "empty-html",
14
+ MismatchedBraces = "mismatched-braces",
15
+ InvalidDynamicTag = "invalid-dynamic-tag",
16
+ InvalidCustomField = "invalid-custom-field",
17
+ ConditionsSyntax = "conditions-syntax",
18
+ WrongEqualityOperator = "wrong-equality-operator",
19
+ MissingIfEndif = "missing-if-endif",
20
+ ConditionTagSpacing = "condition-tag-spacing",
21
+ BracesInsideIfTag = "braces-inside-if-tag",
22
+ RecommendationRequiredFields = "recommendation-required-fields",
23
+ RecommendationFilters = "recommendation-filters",
24
+ InvalidImageType = "invalid-image-type",
25
+ CheckboxUnsubGroup = "checkbox-unsub-group",
26
+ RadioButtonUnsubGroup = "radio-button-unsub-group"
27
+ }
@@ -10,7 +10,6 @@
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;
14
13
  /**
15
14
  * Default currency configuration
16
15
  * 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, 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, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
@@ -70,8 +70,6 @@ export declare class RecommendationBlockControl extends CommonControl {
70
70
  * state was rebuilt with (SD-150347).
71
71
  */
72
72
  private _syncNodeConfigIfChanged;
73
- /** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
74
- private _isPendingStrategyIdChange;
75
73
  private _capturePendingNodeConfigWrite;
76
74
  /**
77
75
  * Accumulates the pending write into `documentModifier` without applying, so the
@@ -2,7 +2,6 @@ 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;
6
5
  private storeUnsubscription;
7
6
  private listeners;
8
7
  private lastPaintedState;
@@ -10,14 +9,6 @@ export declare class StrategyControl extends CommonControl {
10
9
  getTemplate(): string;
11
10
  private _strategyAction;
12
11
  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;
21
12
  onDestroy(): void;
22
13
  private _teardown;
23
14
  private _setupButtonListeners;
@@ -83,11 +83,8 @@ interface StoreState {
83
83
  strategies: RrsStrategy[];
84
84
  strategiesLoading: boolean;
85
85
  strategyUrlTemplates: Record<string, string>;
86
- strategiesFetched: boolean;
87
- strategiesSettled: boolean;
88
86
  blockStates: Record<number, PerBlockState>;
89
87
  currentRecommendationId: number | null;
90
- strategyPanelOpen: boolean;
91
88
  configVersion: number;
92
89
  }
93
90
  export declare const useRecommendationExtensionStore: import("pinia").StoreDefinition<"guidoRecommendationExtension", StoreState, {
@@ -114,11 +111,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
114
111
  }[];
115
112
  strategiesLoading: boolean;
116
113
  strategyUrlTemplates: Record<string, string>;
117
- strategiesFetched: boolean;
118
- strategiesSettled: boolean;
119
114
  blockStates: Record<number, PerBlockState>;
120
115
  currentRecommendationId: number | null;
121
- strategyPanelOpen: boolean;
122
116
  configVersion: number;
123
117
  } & import("pinia").PiniaCustomStateProperties<StoreState>): PerBlockConfigs;
124
118
  /**
@@ -143,11 +137,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
143
137
  }[];
144
138
  strategiesLoading: boolean;
145
139
  strategyUrlTemplates: Record<string, string>;
146
- strategiesFetched: boolean;
147
- strategiesSettled: boolean;
148
140
  blockStates: Record<number, PerBlockState>;
149
141
  currentRecommendationId: number | null;
150
- strategyPanelOpen: boolean;
151
142
  configVersion: number;
152
143
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RecommendationProduct[];
153
144
  /**
@@ -172,11 +163,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
172
163
  }[];
173
164
  strategiesLoading: boolean;
174
165
  strategyUrlTemplates: Record<string, string>;
175
- strategiesFetched: boolean;
176
- strategiesSettled: boolean;
177
166
  blockStates: Record<number, PerBlockState>;
178
167
  currentRecommendationId: number | null;
179
- strategyPanelOpen: boolean;
180
168
  configVersion: number;
181
169
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
182
170
  assignStrategyDrawerStatus(state: {
@@ -198,11 +186,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
198
186
  }[];
199
187
  strategiesLoading: boolean;
200
188
  strategyUrlTemplates: Record<string, string>;
201
- strategiesFetched: boolean;
202
- strategiesSettled: boolean;
203
189
  blockStates: Record<number, PerBlockState>;
204
190
  currentRecommendationId: number | null;
205
- strategyPanelOpen: boolean;
206
191
  configVersion: number;
207
192
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
208
193
  removeStrategyModalStatus(state: {
@@ -224,11 +209,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
224
209
  }[];
225
210
  strategiesLoading: boolean;
226
211
  strategyUrlTemplates: Record<string, string>;
227
- strategiesFetched: boolean;
228
- strategiesSettled: boolean;
229
212
  blockStates: Record<number, PerBlockState>;
230
213
  currentRecommendationId: number | null;
231
- strategyPanelOpen: boolean;
232
214
  configVersion: number;
233
215
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
234
216
  assignedStrategy(state: {
@@ -250,11 +232,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
250
232
  }[];
251
233
  strategiesLoading: boolean;
252
234
  strategyUrlTemplates: Record<string, string>;
253
- strategiesFetched: boolean;
254
- strategiesSettled: boolean;
255
235
  blockStates: Record<number, PerBlockState>;
256
236
  currentRecommendationId: number | null;
257
- strategyPanelOpen: boolean;
258
237
  configVersion: number;
259
238
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
260
239
  /**
@@ -279,11 +258,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
279
258
  }[];
280
259
  strategiesLoading: boolean;
281
260
  strategyUrlTemplates: Record<string, string>;
282
- strategiesFetched: boolean;
283
- strategiesSettled: boolean;
284
261
  blockStates: Record<number, PerBlockState>;
285
262
  currentRecommendationId: number | null;
286
- strategyPanelOpen: boolean;
287
263
  configVersion: number;
288
264
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
289
265
  /**
@@ -308,11 +284,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
308
284
  }[];
309
285
  strategiesLoading: boolean;
310
286
  strategyUrlTemplates: Record<string, string>;
311
- strategiesFetched: boolean;
312
- strategiesSettled: boolean;
313
287
  blockStates: Record<number, PerBlockState>;
314
288
  currentRecommendationId: number | null;
315
- strategyPanelOpen: boolean;
316
289
  configVersion: number;
317
290
  } & import("pinia").PiniaCustomStateProperties<StoreState>): number;
318
291
  hasFilters(): boolean;
@@ -338,11 +311,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
338
311
  }[];
339
312
  strategiesLoading: boolean;
340
313
  strategyUrlTemplates: Record<string, string>;
341
- strategiesFetched: boolean;
342
- strategiesSettled: boolean;
343
314
  blockStates: Record<number, PerBlockState>;
344
315
  currentRecommendationId: number | null;
345
- strategyPanelOpen: boolean;
346
316
  configVersion: number;
347
317
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
348
318
  text: string;
@@ -367,11 +337,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
367
337
  }[];
368
338
  strategiesLoading: boolean;
369
339
  strategyUrlTemplates: Record<string, string>;
370
- strategiesFetched: boolean;
371
- strategiesSettled: boolean;
372
340
  blockStates: Record<number, PerBlockState>;
373
341
  currentRecommendationId: number | null;
374
- strategyPanelOpen: boolean;
375
342
  configVersion: number;
376
343
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
377
344
  text: string;
@@ -396,11 +363,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
396
363
  }[];
397
364
  strategiesLoading: boolean;
398
365
  strategyUrlTemplates: Record<string, string>;
399
- strategiesFetched: boolean;
400
- strategiesSettled: boolean;
401
366
  blockStates: Record<number, PerBlockState>;
402
367
  currentRecommendationId: number | null;
403
- strategyPanelOpen: boolean;
404
368
  configVersion: number;
405
369
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
406
370
  text: string;
@@ -481,40 +445,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
481
445
  openRemoveStrategyModal(): void;
482
446
  closeRemoveStrategyModal(): void;
483
447
  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;
518
448
  resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
519
449
  assignStrategy(strategy: RrsStrategy): void;
520
450
  removeStrategy(): void;
@@ -533,10 +463,10 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
533
463
  */
534
464
  hasInvalidBlock(): boolean;
535
465
  /**
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.
466
+ * Per-instance counterpart to `hasInvalidBlock`: the ids of every block
467
+ * that fails required-field validation, one drawer row each (SD-147430).
538
468
  */
539
- invalidBlockFields(): string[];
469
+ invalidBlockIds(): string[];
540
470
  fetchRecommendationProducts(): Promise<void>;
541
471
  _doFetchProducts(): Promise<void>;
542
472
  _doFetchStrategyProducts(blockId: number): Promise<void>;
@@ -15,11 +15,7 @@ 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";
20
18
  export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
21
19
  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";
24
20
  export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
25
21
  export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;