@useinsider/guido 3.12.0-beta.b73c720 → 3.12.0-beta.bec0e55
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/dist/@types/config/schemas.js +8 -13
- package/dist/components/Guido.vue.js +6 -6
- package/dist/components/Guido.vue2.js +49 -50
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
- package/dist/composables/usePreviewInteractionGuard.js +36 -11
- package/dist/composables/useRecommendation.js +51 -82
- package/dist/composables/useRecommendationPreview.js +61 -60
- package/dist/config/migrator/recommendationMigrator.js +4 -7
- package/dist/enums/date.js +3 -4
- package/dist/enums/extensions/recommendationBlock.js +22 -28
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +11 -12
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +109 -123
- package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +1 -1
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +102 -256
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -24
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
- package/dist/extensions/Blocks/controlFactories.js +125 -75
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +27 -65
- package/dist/src/@types/config/schemas.d.ts +0 -10
- package/dist/src/composables/useConfig.d.ts +0 -2
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
- package/dist/src/composables/useRecommendation.d.ts +0 -2
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -10
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -3
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -606
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -7
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +1 -3
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
- package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
- package/dist/src/services/recommendationApi.d.ts +1 -7
- package/dist/src/stores/config.d.ts +0 -18
- package/dist/src/utils/genericUtil.d.ts +0 -9
- package/dist/src/utils/urlSchemes.d.ts +6 -0
- package/dist/static/styles/base.css.js +0 -15
- package/dist/utils/dateUtil.js +10 -23
- package/dist/utils/genericUtil.js +1 -10
- package/dist/utils/templatePreparation.js +58 -62
- package/dist/utils/urlSchemes.js +4 -0
- package/package.json +1 -1
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +0 -36
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +0 -244
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +0 -18
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +0 -42
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +0 -20
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +0 -18
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +0 -20
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +0 -60
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +0 -19
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +0 -19
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +0 -22
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +0 -29
- package/dist/composables/useStrategyFilters.js +0 -16
- package/dist/enums/extensions/filteringV2.js +0 -8
- package/dist/enums/extensions/strategyDetail.js +0 -148
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -146
- package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +0 -97
- package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +0 -10
- package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +0 -2
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +0 -43
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +0 -29
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +0 -40
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +0 -38
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +0 -51
- package/dist/src/composables/useStrategyFilters.d.ts +0 -24
- package/dist/src/enums/extensions/filteringV2.d.ts +0 -72
- package/dist/src/enums/extensions/strategyDetail.d.ts +0 -90
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -61
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +0 -50
- package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +0 -34
|
@@ -54,13 +54,6 @@ export interface RecommendationNodeConfig {
|
|
|
54
54
|
* @example 'mostPopular', 'complementaryItems', 'manualMerchandising'
|
|
55
55
|
*/
|
|
56
56
|
strategy: string;
|
|
57
|
-
/**
|
|
58
|
-
* Reusable Recommendation Strategy (RRS) id from Smart Recommender.
|
|
59
|
-
* Empty string means no strategy is assigned.
|
|
60
|
-
* Only used when the `reusableRecommendationStrategy` feature is enabled;
|
|
61
|
-
* when set, it supersedes `strategy` for building the recommendation URL.
|
|
62
|
-
*/
|
|
63
|
-
strategyId: string;
|
|
64
57
|
/**
|
|
65
58
|
* Product IDs for manual merchandising strategy
|
|
66
59
|
* Only used when strategy === 'manualMerchandising'
|
|
@@ -7,15 +7,13 @@ import type { Currency, Languages } from '@@/Types/recommendation';
|
|
|
7
7
|
export interface ExtensionStoreSlice {
|
|
8
8
|
languages: Languages;
|
|
9
9
|
currencyList: Currency[];
|
|
10
|
-
/** Whether the `reusableRecommendationStrategy` feature is enabled. */
|
|
11
|
-
isRrsEnabled: boolean;
|
|
12
10
|
}
|
|
13
11
|
export interface RequiredField {
|
|
14
12
|
key: string;
|
|
15
13
|
canBeEmpty?: boolean;
|
|
16
14
|
getValue: (config: PerBlockConfigs) => string;
|
|
17
15
|
getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
|
|
18
|
-
condition?: (config: PerBlockConfigs
|
|
16
|
+
condition?: (config: PerBlockConfigs) => boolean;
|
|
19
17
|
}
|
|
20
18
|
export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
|
|
21
19
|
export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
|
|
@@ -9,3 +9,4 @@ export declare const DATA_ATTRIBUTES: {
|
|
|
9
9
|
readonly BLOCK_ID: "data-unsubscribe-block-id";
|
|
10
10
|
};
|
|
11
11
|
export declare const UNSUBSCRIBE_BLOCK_SELECTOR = ".unsubscribe-block-v2";
|
|
12
|
+
export declare const UNSUBSCRIBE_LINK_SELECTOR = "a[data-unsubscribe-link=\"true\"], a.unsubscribe-link";
|
|
@@ -115,6 +115,42 @@ export declare function createTextBackgroundColorControl(controlId: string, targ
|
|
|
115
115
|
isVisible(_node: ImmutableHtmlNode): boolean;
|
|
116
116
|
};
|
|
117
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* Factory for a background-color control that paints a whole extension block (SD-145082).
|
|
120
|
+
*
|
|
121
|
+
* Base is `ButtonBackgroundColorBuiltInControl` because its `GENERAL.BACKGROUND_COLOR` form key
|
|
122
|
+
* round-trips through `getValues()`; the block-text base (`TextBlockBackgroundBuiltInControl`, the
|
|
123
|
+
* built-in this replaces) reports `textBlockBackgroundColor`, which our read path never sees. That
|
|
124
|
+
* borrowed base targets the block's Buy buttons, so `getTargetNodes` here is a GUARD that keeps it
|
|
125
|
+
* off the buttons — not the write path.
|
|
126
|
+
*
|
|
127
|
+
* The write is entirely ours (`getAdditionalModifications`): Stripo's built-in emits a stylesheet
|
|
128
|
+
* rule that inline styles from regeneration outrank (SD-143023), so it would silently no-op on the
|
|
129
|
+
* next edit. We write inline `background-color` + `bgcolor` on the block `<td>` instead — surviving
|
|
130
|
+
* regeneration and reaching Outlook, matching the migrator's convention.
|
|
131
|
+
*/
|
|
132
|
+
export declare function createBlockBackgroundColorControl(controlId: string, blockRootSelector?: string): {
|
|
133
|
+
new (): {
|
|
134
|
+
getId(): string;
|
|
135
|
+
/** The parent control renders its own generic title; restore the block-level wording. */
|
|
136
|
+
getLabels(): {
|
|
137
|
+
title: string;
|
|
138
|
+
};
|
|
139
|
+
/** Guard: redirect the borrowed button parent onto the block `<td>` so it never paints the Buy buttons. */
|
|
140
|
+
getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
|
|
141
|
+
/**
|
|
142
|
+
* Writes the picked background onto the block as an inline style plus a `bgcolor`
|
|
143
|
+
* attribute. This is the whole mechanism, not a mirror: the parent control's own
|
|
144
|
+
* write never reaches the block element (verified at runtime). `bgcolor` is the
|
|
145
|
+
* channel Outlook honours on a `<td>`, and matches what the migrator emits.
|
|
146
|
+
*/
|
|
147
|
+
getAdditionalModifications(root: ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
|
|
148
|
+
getParentControlId(): string;
|
|
149
|
+
api: import("@stripoinc/ui-editor-extensions").ControlApi;
|
|
150
|
+
getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
|
|
151
|
+
isVisible(_node: ImmutableHtmlNode): boolean;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
118
154
|
/**
|
|
119
155
|
* Factory function to create paddings controls for different block elements
|
|
120
156
|
* When targetBlockId and containerSelector are not provided, applies directly to root
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams
|
|
2
|
-
/** Translation lookup, matching `useTranslations()`. */
|
|
3
|
-
type TranslateFn = (key: string, params?: Record<string, string | number | boolean>) => string;
|
|
1
|
+
import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams } from '@@/Types/recommendation';
|
|
4
2
|
export declare const useRecommendationApi: () => {
|
|
5
3
|
fetchRecommendationCreateData: () => Promise<InitialResponse>;
|
|
6
4
|
fetchRecommendationFilters: () => Promise<FiltersResponse>;
|
|
7
5
|
fetchRecommendationProducts: (strategy: string, params: RecommendationProductsParams) => Promise<RecommendationProduct[]>;
|
|
8
|
-
fetchRecommendationStrategies: () => Promise<RrsStrategy[]>;
|
|
9
|
-
fetchStrategyCampaigns: (strategyId: string, trans: TranslateFn) => Promise<RrsCampaign[]>;
|
|
10
|
-
fetchStrategyRecommendationUrl: (strategyId: string) => Promise<RrsStrategyUrl | null>;
|
|
11
6
|
};
|
|
12
|
-
export {};
|
|
@@ -101,7 +101,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
101
101
|
modulesDisabled: boolean;
|
|
102
102
|
liquidSyntax: boolean;
|
|
103
103
|
autosave: boolean;
|
|
104
|
-
reusableRecommendationStrategy: boolean;
|
|
105
104
|
};
|
|
106
105
|
blocks: {
|
|
107
106
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -239,7 +238,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
239
238
|
modulesDisabled: boolean;
|
|
240
239
|
liquidSyntax: boolean;
|
|
241
240
|
autosave: boolean;
|
|
242
|
-
reusableRecommendationStrategy: boolean;
|
|
243
241
|
};
|
|
244
242
|
blocks: {
|
|
245
243
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -377,7 +375,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
377
375
|
modulesDisabled: boolean;
|
|
378
376
|
liquidSyntax: boolean;
|
|
379
377
|
autosave: boolean;
|
|
380
|
-
reusableRecommendationStrategy: boolean;
|
|
381
378
|
};
|
|
382
379
|
blocks: {
|
|
383
380
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -515,7 +512,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
515
512
|
modulesDisabled: boolean;
|
|
516
513
|
liquidSyntax: boolean;
|
|
517
514
|
autosave: boolean;
|
|
518
|
-
reusableRecommendationStrategy: boolean;
|
|
519
515
|
};
|
|
520
516
|
blocks: {
|
|
521
517
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -653,7 +649,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
653
649
|
modulesDisabled: boolean;
|
|
654
650
|
liquidSyntax: boolean;
|
|
655
651
|
autosave: boolean;
|
|
656
|
-
reusableRecommendationStrategy: boolean;
|
|
657
652
|
};
|
|
658
653
|
blocks: {
|
|
659
654
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -791,7 +786,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
791
786
|
modulesDisabled: boolean;
|
|
792
787
|
liquidSyntax: boolean;
|
|
793
788
|
autosave: boolean;
|
|
794
|
-
reusableRecommendationStrategy: boolean;
|
|
795
789
|
};
|
|
796
790
|
blocks: {
|
|
797
791
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -929,7 +923,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
929
923
|
modulesDisabled: boolean;
|
|
930
924
|
liquidSyntax: boolean;
|
|
931
925
|
autosave: boolean;
|
|
932
|
-
reusableRecommendationStrategy: boolean;
|
|
933
926
|
};
|
|
934
927
|
blocks: {
|
|
935
928
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1067,7 +1060,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1067
1060
|
modulesDisabled: boolean;
|
|
1068
1061
|
liquidSyntax: boolean;
|
|
1069
1062
|
autosave: boolean;
|
|
1070
|
-
reusableRecommendationStrategy: boolean;
|
|
1071
1063
|
};
|
|
1072
1064
|
blocks: {
|
|
1073
1065
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1205,7 +1197,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1205
1197
|
modulesDisabled: boolean;
|
|
1206
1198
|
liquidSyntax: boolean;
|
|
1207
1199
|
autosave: boolean;
|
|
1208
|
-
reusableRecommendationStrategy: boolean;
|
|
1209
1200
|
};
|
|
1210
1201
|
blocks: {
|
|
1211
1202
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1343,7 +1334,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1343
1334
|
modulesDisabled: boolean;
|
|
1344
1335
|
liquidSyntax: boolean;
|
|
1345
1336
|
autosave: boolean;
|
|
1346
|
-
reusableRecommendationStrategy: boolean;
|
|
1347
1337
|
};
|
|
1348
1338
|
blocks: {
|
|
1349
1339
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1481,7 +1471,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1481
1471
|
modulesDisabled: boolean;
|
|
1482
1472
|
liquidSyntax: boolean;
|
|
1483
1473
|
autosave: boolean;
|
|
1484
|
-
reusableRecommendationStrategy: boolean;
|
|
1485
1474
|
};
|
|
1486
1475
|
blocks: {
|
|
1487
1476
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1619,7 +1608,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1619
1608
|
modulesDisabled: boolean;
|
|
1620
1609
|
liquidSyntax: boolean;
|
|
1621
1610
|
autosave: boolean;
|
|
1622
|
-
reusableRecommendationStrategy: boolean;
|
|
1623
1611
|
};
|
|
1624
1612
|
blocks: {
|
|
1625
1613
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1757,7 +1745,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1757
1745
|
modulesDisabled: boolean;
|
|
1758
1746
|
liquidSyntax: boolean;
|
|
1759
1747
|
autosave: boolean;
|
|
1760
|
-
reusableRecommendationStrategy: boolean;
|
|
1761
1748
|
};
|
|
1762
1749
|
blocks: {
|
|
1763
1750
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1895,7 +1882,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1895
1882
|
modulesDisabled: boolean;
|
|
1896
1883
|
liquidSyntax: boolean;
|
|
1897
1884
|
autosave: boolean;
|
|
1898
|
-
reusableRecommendationStrategy: boolean;
|
|
1899
1885
|
};
|
|
1900
1886
|
blocks: {
|
|
1901
1887
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2033,7 +2019,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2033
2019
|
modulesDisabled: boolean;
|
|
2034
2020
|
liquidSyntax: boolean;
|
|
2035
2021
|
autosave: boolean;
|
|
2036
|
-
reusableRecommendationStrategy: boolean;
|
|
2037
2022
|
};
|
|
2038
2023
|
blocks: {
|
|
2039
2024
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2171,7 +2156,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2171
2156
|
modulesDisabled: boolean;
|
|
2172
2157
|
liquidSyntax: boolean;
|
|
2173
2158
|
autosave: boolean;
|
|
2174
|
-
reusableRecommendationStrategy: boolean;
|
|
2175
2159
|
};
|
|
2176
2160
|
blocks: {
|
|
2177
2161
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2309,7 +2293,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2309
2293
|
modulesDisabled: boolean;
|
|
2310
2294
|
liquidSyntax: boolean;
|
|
2311
2295
|
autosave: boolean;
|
|
2312
|
-
reusableRecommendationStrategy: boolean;
|
|
2313
2296
|
};
|
|
2314
2297
|
blocks: {
|
|
2315
2298
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2447,7 +2430,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2447
2430
|
modulesDisabled: boolean;
|
|
2448
2431
|
liquidSyntax: boolean;
|
|
2449
2432
|
autosave: boolean;
|
|
2450
|
-
reusableRecommendationStrategy: boolean;
|
|
2451
2433
|
};
|
|
2452
2434
|
blocks: {
|
|
2453
2435
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -25,12 +25,3 @@ export declare const getCsrfToken: () => string;
|
|
|
25
25
|
export declare const getUrlParams: () => URLSearchParams;
|
|
26
26
|
export declare const getUrlParam: (paramName: string, defaultValue?: string) => string;
|
|
27
27
|
export declare const replaceString: (string?: string, values?: Record<string, string | number>, isRemoveEmptyValues?: boolean) => string;
|
|
28
|
-
/**
|
|
29
|
-
* Parses a JSON-string field, yielding `fallback` on absent or malformed input.
|
|
30
|
-
*
|
|
31
|
-
* Smart Recommender returns several strategy fields (`filters`, `base_product`, ...)
|
|
32
|
-
* as embedded JSON strings, and every surface that reads them must degrade to a
|
|
33
|
-
* sensible empty value rather than break. Shared so a hardening change (rejecting
|
|
34
|
-
* non-object payloads, logging a malformed blob) lands on all of them at once.
|
|
35
|
-
*/
|
|
36
|
-
export declare const parseJsonField: <T>(raw: string | undefined, fallback: T) => T;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL schemes that are safe to follow from partner-authored email HTML. Shared so a
|
|
3
|
+
* future bypass fix lands in one place — the preview guard and the recommendation
|
|
4
|
+
* sanitizer both gate on it. Stored with the trailing colon to match `anchor.protocol`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BASE_SAFE_URL_SCHEMES: readonly string[];
|
|
@@ -10,21 +10,6 @@ ue-stripe-thumb,
|
|
|
10
10
|
height: 100% !important;
|
|
11
11
|
min-height: 0 !important;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
* The Recommendation Strategy select and its details-drawer icon button share a
|
|
16
|
-
* single cell of Stripo's two-column panel grid, so they need their own row box.
|
|
17
|
-
*/
|
|
18
|
-
.strategy-control__select-row {
|
|
19
|
-
display: flex;
|
|
20
|
-
align-items: center;
|
|
21
|
-
gap: 8px;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.strategy-control__select-row ue-select {
|
|
25
|
-
flex: 1;
|
|
26
|
-
min-width: 0;
|
|
27
|
-
}
|
|
28
13
|
`;
|
|
29
14
|
export {
|
|
30
15
|
n as default
|
package/dist/utils/dateUtil.js
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import { DEFAULT_LOCALE as r, DEFAULT as
|
|
2
|
-
const
|
|
1
|
+
import { DEFAULT_LOCALE as r, DEFAULT as o } from "../enums/date.js";
|
|
2
|
+
const c = () => {
|
|
3
3
|
const t = window.l10n;
|
|
4
|
-
return (t == null ? void 0 : t.locale) ===
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}, D = (t, e = s(), n = f()) => {
|
|
9
|
-
const o = {
|
|
10
|
-
year: "numeric",
|
|
11
|
-
month: "2-digit",
|
|
12
|
-
day: "2-digit",
|
|
13
|
-
timeZone: n
|
|
14
|
-
}, i = m(t);
|
|
15
|
-
return new Intl.DateTimeFormat(e, o).format(i);
|
|
16
|
-
}, T = (t) => {
|
|
4
|
+
return (t == null ? void 0 : t.locale) === o ? r : (t == null ? void 0 : t.locale) || r;
|
|
5
|
+
};
|
|
6
|
+
new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7
|
+
const i = (t) => {
|
|
17
8
|
if (!t)
|
|
18
9
|
return "";
|
|
19
10
|
const e = new Date(t);
|
|
@@ -25,13 +16,9 @@ const m = (t) => t ? t instanceof Date ? t : typeof t == "string" ? t.length ===
|
|
|
25
16
|
second: "2-digit",
|
|
26
17
|
hour12: !1
|
|
27
18
|
}).format(e);
|
|
28
|
-
},
|
|
19
|
+
}, m = (t) => t ? Math.floor(Date.now() / 1e3) >= t : !1;
|
|
29
20
|
export {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
h as isAfterDate,
|
|
34
|
-
u as localTz,
|
|
35
|
-
s as locale,
|
|
36
|
-
f as timezone
|
|
21
|
+
i as formatPatchDate,
|
|
22
|
+
m as isAfterDate,
|
|
23
|
+
c as locale
|
|
37
24
|
};
|
|
@@ -58,20 +58,11 @@ const o = (l) => {
|
|
|
58
58
|
}, i = () => {
|
|
59
59
|
var l;
|
|
60
60
|
return ((l = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : l.getAttribute("content")) ?? "";
|
|
61
|
-
}, k = (l, s) => {
|
|
62
|
-
if (!l)
|
|
63
|
-
return s;
|
|
64
|
-
try {
|
|
65
|
-
return JSON.parse(l);
|
|
66
|
-
} catch {
|
|
67
|
-
return s;
|
|
68
|
-
}
|
|
69
61
|
};
|
|
70
62
|
export {
|
|
71
63
|
v as buildMergeTagEntries,
|
|
72
64
|
f as dynamicContentToMergeTags,
|
|
73
65
|
b as flattenDynamicContentList,
|
|
74
66
|
i as getCsrfToken,
|
|
75
|
-
o as mergeTagToDynamicContent
|
|
76
|
-
k as parseJsonField
|
|
67
|
+
o as mergeTagToDynamicContent
|
|
77
68
|
};
|
|
@@ -1,60 +1,59 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useHtmlCompiler as
|
|
3
|
-
import { DEFAULT_CURRENCY as
|
|
4
|
-
import { useRecommendationExtensionStore as
|
|
5
|
-
import { mapLegacyStrategy as
|
|
6
|
-
import { DATA_ATTRIBUTES as
|
|
7
|
-
import { parsePageList as
|
|
8
|
-
import { useDynamicContentStore as
|
|
9
|
-
import { useUnsubscribeStore as
|
|
10
|
-
function
|
|
11
|
-
const o = new DOMParser().parseFromString(
|
|
12
|
-
return o.forEach((
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
}), [...new Set(
|
|
1
|
+
import { useActionsApi as P } from "../composables/useActionsApi.js";
|
|
2
|
+
import { useHtmlCompiler as w } from "../composables/useHtmlCompiler.js";
|
|
3
|
+
import { DEFAULT_CURRENCY as l, DEFAULT_NODE_CONFIG as i } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
|
|
4
|
+
import { useRecommendationExtensionStore as b } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
5
|
+
import { mapLegacyStrategy as E } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
|
|
6
|
+
import { DATA_ATTRIBUTES as h } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
7
|
+
import { parsePageList as H } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
|
|
8
|
+
import { useDynamicContentStore as U } from "../stores/dynamic-content.js";
|
|
9
|
+
import { useUnsubscribeStore as F } from "../stores/unsubscribe.js";
|
|
10
|
+
function L(s) {
|
|
11
|
+
const o = new DOMParser().parseFromString(s, "text/html").querySelectorAll(`[${h.PAGE_LIST}]`), t = [];
|
|
12
|
+
return o.forEach((a) => {
|
|
13
|
+
const n = a.getAttribute(h.PAGE_LIST);
|
|
14
|
+
n && t.push(...H(n));
|
|
15
|
+
}), [...new Set(t)];
|
|
16
16
|
}
|
|
17
|
-
async function
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
17
|
+
async function R(s) {
|
|
18
|
+
const m = new DOMParser().parseFromString(s, "text/html").querySelectorAll(".recommendation-block-v2");
|
|
19
|
+
if (m.length === 0)
|
|
20
20
|
return;
|
|
21
|
-
const o =
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
const
|
|
25
|
-
if (!Number.isFinite(
|
|
21
|
+
const o = b();
|
|
22
|
+
m.forEach((t) => {
|
|
23
|
+
var c, p, g, f, r;
|
|
24
|
+
const a = t.getAttribute("recommendation-id"), n = a ? Number(a) : NaN;
|
|
25
|
+
if (!Number.isFinite(n))
|
|
26
26
|
return;
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
27
|
+
const d = t.getAttribute("esd-ext-config");
|
|
28
|
+
if (!d)
|
|
29
29
|
return;
|
|
30
30
|
let e;
|
|
31
31
|
try {
|
|
32
|
-
e = JSON.parse(
|
|
32
|
+
e = JSON.parse(d);
|
|
33
33
|
} catch {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
if (!e || typeof e != "object" || Array.isArray(e))
|
|
37
37
|
return;
|
|
38
|
-
const
|
|
38
|
+
const y = {
|
|
39
39
|
// Normalize legacy strategy keys (e.g. `mostViewed` → `mostPopular`) so
|
|
40
40
|
// already-saved blocks that never re-run the migrator don't emit a
|
|
41
41
|
// strategy-less campaign URL. `||` also catches '' / undefined (SD-144882).
|
|
42
|
-
strategy:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
size: e.size ?? n.size,
|
|
42
|
+
strategy: E(e.strategy) || i.strategy,
|
|
43
|
+
language: e.language ?? i.language,
|
|
44
|
+
size: e.size ?? i.size,
|
|
46
45
|
// Spread the default arrays so each block gets a fresh reference
|
|
47
46
|
// instead of sharing the singleton in DEFAULT_NODE_CONFIG.
|
|
48
|
-
productIds: e.productIds ?? [...
|
|
49
|
-
filters: e.filters ?? [...
|
|
50
|
-
shuffleProducts: e.shuffleProducts ??
|
|
51
|
-
currencyCode: ((
|
|
52
|
-
currencyAlignment: ((
|
|
53
|
-
currencyDecimalCount: ((
|
|
54
|
-
currencyDecimalSeparator: ((
|
|
55
|
-
currencyThousandSeparator: ((
|
|
47
|
+
productIds: e.productIds ?? [...i.productIds],
|
|
48
|
+
filters: e.filters ?? [...i.filters],
|
|
49
|
+
shuffleProducts: e.shuffleProducts ?? i.shuffleProducts,
|
|
50
|
+
currencyCode: ((c = e.currency) == null ? void 0 : c.code) ?? l.code,
|
|
51
|
+
currencyAlignment: ((p = e.currency) == null ? void 0 : p.alignment) ?? l.alignment,
|
|
52
|
+
currencyDecimalCount: ((g = e.currency) == null ? void 0 : g.decimalCount) ?? l.decimalCount,
|
|
53
|
+
currencyDecimalSeparator: ((f = e.currency) == null ? void 0 : f.decimalSeparator) ?? l.decimalSeparator,
|
|
54
|
+
currencyThousandSeparator: ((r = e.currency) == null ? void 0 : r.thousandSeparator) ?? l.thousandSeparator
|
|
56
55
|
};
|
|
57
|
-
o.seedBlockUrlConfig(
|
|
56
|
+
o.seedBlockUrlConfig(n, y);
|
|
58
57
|
});
|
|
59
58
|
try {
|
|
60
59
|
await o.fetchRecommendationCreateData();
|
|
@@ -64,47 +63,44 @@ async function L(m) {
|
|
|
64
63
|
t
|
|
65
64
|
);
|
|
66
65
|
}
|
|
67
|
-
r.delete(""), await Promise.all(
|
|
68
|
-
[...r].map((t) => o.fetchStrategyUrlTemplate(t))
|
|
69
|
-
);
|
|
70
66
|
}
|
|
71
67
|
const G = () => {
|
|
72
|
-
const
|
|
68
|
+
const s = U(), u = F(), { getCompiledEmail: m, getTemplateData: o } = P(), { compileHtml: t, compileAmpHtml: a } = w();
|
|
73
69
|
return {
|
|
74
70
|
prepareTemplateDetails: async () => {
|
|
75
|
-
const { html:
|
|
71
|
+
const { html: d, ampHtml: e = "", ampErrors: y = [] } = await m({
|
|
76
72
|
minimize: !0,
|
|
77
73
|
resetDataSavedFlag: !1
|
|
78
|
-
}), { html:
|
|
79
|
-
u.selectedUnsubscribePages.length && await u.fetchTemplates(), await
|
|
80
|
-
const { compiledHtml:
|
|
74
|
+
}), { html: c, css: p, syncModulesIds: g = [] } = await o();
|
|
75
|
+
u.selectedUnsubscribePages.length && await u.fetchTemplates(), await R(c);
|
|
76
|
+
const { compiledHtml: f, stats: r, appliedRules: A } = t(d), C = e && a(e).compiledHtml, T = s.getSelectedDynamicContentList, D = b(), S = L(c);
|
|
81
77
|
return console.debug("HTML Compilation Stats:", {
|
|
82
|
-
originalSize:
|
|
83
|
-
compiledSize:
|
|
84
|
-
reduction: `${
|
|
85
|
-
appliedRules:
|
|
86
|
-
executionTime: `${
|
|
78
|
+
originalSize: r.originalSize,
|
|
79
|
+
compiledSize: r.compiledSize,
|
|
80
|
+
reduction: `${r.reductionPercentage.toFixed(2)}%`,
|
|
81
|
+
appliedRules: A,
|
|
82
|
+
executionTime: `${r.executionTime.toFixed(2)}ms`
|
|
87
83
|
}), {
|
|
88
84
|
dynamicContentList: T,
|
|
89
|
-
compiledHtml:
|
|
90
|
-
rawHtml:
|
|
91
|
-
css:
|
|
85
|
+
compiledHtml: f,
|
|
86
|
+
rawHtml: c,
|
|
87
|
+
css: p,
|
|
92
88
|
ampHtml: C,
|
|
93
|
-
ampErrors:
|
|
94
|
-
modules:
|
|
89
|
+
ampErrors: y,
|
|
90
|
+
modules: g.map(Number),
|
|
95
91
|
recommendation: {
|
|
96
|
-
campaignUrls:
|
|
92
|
+
campaignUrls: D.recommendationCampaignUrls,
|
|
97
93
|
configs: {}
|
|
98
94
|
},
|
|
99
95
|
unsubscribe: {
|
|
100
|
-
status:
|
|
101
|
-
config:
|
|
96
|
+
status: S.length > 0,
|
|
97
|
+
config: S
|
|
102
98
|
}
|
|
103
99
|
};
|
|
104
100
|
}
|
|
105
101
|
};
|
|
106
102
|
};
|
|
107
103
|
export {
|
|
108
|
-
|
|
104
|
+
L as getHtmlReferencedUnsubscribePages,
|
|
109
105
|
G as useTemplatePreparation
|
|
110
106
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.12.0-beta.
|
|
3
|
+
"version": "3.12.0-beta.bec0e55",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import o from "./StrategyDetailDrawer.vue2.js";
|
|
2
|
-
/* empty css */
|
|
3
|
-
import l from "../../../../_virtual/_plugin-vue2_normalizer.js";
|
|
4
|
-
var c = function() {
|
|
5
|
-
var i;
|
|
6
|
-
var a = this, s = a._self._c, t = a._self._setupProxy;
|
|
7
|
-
return s(t.InDrawer, { attrs: { id: "recommendation-strategy-detail-drawer", "close-button-status": "", "full-width-content-status": "", "overlay-status": "", size: "medium", state: "default", "description-status": !1, "footer-status": !1, status: t.isOpen, "title-text": ((i = t.strategy) == null ? void 0 : i.name) || "" }, on: { onCloseEvent: t.close }, scopedSlots: a._u([{ key: "headerBottomSlot", fn: function() {
|
|
8
|
-
return [t.strategy ? s(t.InTabs, { staticClass: "p-r z-4 px-5", attrs: { "active-tab": t.activeTab, "add-new-tab-active": !1, draggable: !1, "dropdown-tabs": !1, "tabs-list": t.tabs, "use-router": !1 }, on: { click: function(e) {
|
|
9
|
-
t.activeTab = e;
|
|
10
|
-
} } }) : a._e()];
|
|
11
|
-
}, proxy: !0 }, { key: "contentSlot", fn: function() {
|
|
12
|
-
return [t.strategy ? s("div", [t.activeTab === t.DetailTabs.GENERAL ? s("div", [s("div", { staticClass: "px-5 py-5 bor-b-s-s bor-b-c-6 bor-b-w-1" }, [s("div", { staticClass: "f-s-13 f-w-600 mb-3" }, [a._v(" " + a._s(t.trans("discovery-strategy.suitable-page-and-channel-types")) + " ")]), a._l(t.visibleRows(t.pageAndChannelDetails), function(e, r) {
|
|
13
|
-
return s(t.InfoDisplayValue, { key: e.title, attrs: { index: r, title: e.title, "translate-value": e.translateValue, value: e.value } });
|
|
14
|
-
})], 2), s("div", { staticClass: "px-5 py-5 bor-b-s-s bor-b-c-6 bor-b-w-1" }, [s("div", { staticClass: "f-s-13 f-w-600 mb-3" }, [a._v(" " + a._s(t.trans("discovery-strategy.recommendation-widget-preferences")) + " ")]), a._l(t.visibleRows(t.widgetPreferences), function(e, r) {
|
|
15
|
-
return s(t.InfoDisplayValue, { key: e.title, attrs: { index: r, title: e.title, "translate-value": e.translateValue, value: e.value } });
|
|
16
|
-
})], 2), s("div", { staticClass: "px-5 py-5 bor-b-s-s bor-b-c-6 bor-b-w-1" }, [s("div", { staticClass: "f-s-13 f-w-600 mb-3" }, [a._v(" " + a._s(t.trans("discovery-strategy.advanced-personalization-criteria")) + " ")]), a._l(t.visibleRows(t.advancedPersonalization), function(e, r) {
|
|
17
|
-
return s(t.InfoDisplayValue, { key: e.title, attrs: { index: r, title: e.title, "translate-value": e.translateValue, value: e.value } });
|
|
18
|
-
})], 2), s("div", { staticClass: "px-5 py-5" }, [s("div", { staticClass: "f-s-13 f-w-600 mb-3" }, [a._v(" " + a._s(t.trans("discovery-strategy.filters")) + " ")]), s(t.FilterHumanizer, { attrs: { filters: t.strategy.filters } })], 1)]) : a._e(), t.activeTab === t.DetailTabs.OTHER ? s("div", [s("div", { staticClass: "px-5 py-5 bor-b-s-s bor-b-c-6 bor-b-w-1 other-details" }, a._l(t.visibleRows(t.otherDetails), function(e, r) {
|
|
19
|
-
return s(t.InfoDisplayValue, { key: e.title, attrs: { icon: e.icon, "icon-tooltip": e.iconTooltip, "icon-tooltip-after-clicked": e.iconTooltipAfterClicked, index: r, title: e.title, "translate-value": e.translateValue, value: e.value }, on: { iconClick: function(b) {
|
|
20
|
-
var n;
|
|
21
|
-
(n = e.iconClick) == null || n.call(e, e.value);
|
|
22
|
-
} } });
|
|
23
|
-
}), 1), s("div", { staticClass: "px-5 py-5" }, [s(t.CampaignTable, { attrs: { campaigns: t.store.strategyCampaigns, loading: t.store.strategyCampaignsLoading } })], 1)]) : a._e()]) : a._e()];
|
|
24
|
-
}, proxy: !0 }]) });
|
|
25
|
-
}, u = [], v = /* @__PURE__ */ l(
|
|
26
|
-
o,
|
|
27
|
-
c,
|
|
28
|
-
u,
|
|
29
|
-
!1,
|
|
30
|
-
null,
|
|
31
|
-
"008cf324"
|
|
32
|
-
);
|
|
33
|
-
const d = v.exports;
|
|
34
|
-
export {
|
|
35
|
-
d as default
|
|
36
|
-
};
|