@useinsider/guido 3.2.1-beta.d58ee72 → 3.3.0-beta.1d2853a
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/README.md +117 -1
- package/dist/@types/config/schemas.js +153 -95
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +91 -87
- package/dist/components/organisms/AutoSaveController.vue.js +17 -0
- package/dist/components/organisms/AutoSaveController.vue2.js +13 -0
- package/dist/components/organisms/header/AiStatusPill.vue.js +18 -0
- package/dist/components/organisms/header/AiStatusPill.vue2.js +13 -0
- package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
- package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
- package/dist/components/organisms/header/MiddleSlot.vue.js +7 -7
- package/dist/components/organisms/header/MiddleSlot.vue2.js +8 -7
- package/dist/components/organisms/header/RightSlot.vue.js +8 -8
- package/dist/components/organisms/header/RightSlot.vue2.js +9 -8
- package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
- package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
- package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
- package/dist/composables/useAutoSave.js +71 -0
- package/dist/composables/useCortexBlueprintBridge.js +91 -0
- package/dist/composables/useEmailTemplateApplier.js +41 -0
- package/dist/composables/useFullStoryBridge.js +14 -0
- package/dist/composables/useGuidoStateBridge.js +48 -0
- package/dist/composables/useHtmlValidator.js +41 -36
- package/dist/composables/useRecommendation.js +46 -26
- package/dist/composables/useRibbonOffset.js +21 -0
- package/dist/composables/useSave.js +19 -16
- package/dist/composables/useStripo.js +40 -40
- package/dist/composables/validators/useCouponBlockValidator.js +24 -0
- package/dist/config/compiler/recommendationCompilerRules.js +25 -25
- package/dist/config/compiler/unsubscribeCompilerRules.js +40 -37
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +107 -71
- package/dist/config/migrator/index.js +9 -9
- package/dist/config/migrator/radioButtonMigrator.js +64 -44
- package/dist/config/migrator/recommendation/compositionMapper.js +98 -0
- package/dist/config/migrator/recommendation/extractors.js +27 -0
- package/dist/config/migrator/recommendation/htmlBuilder.js +496 -0
- package/dist/config/migrator/recommendation/parseLegacyConfig.js +33 -0
- package/dist/config/migrator/recommendation/settingsMapper.js +70 -0
- package/dist/config/migrator/recommendation/themeMapper.js +93 -0
- package/dist/config/migrator/recommendationMigrator.js +74 -290
- package/dist/enums/extensions/recommendationBlock.js +97 -42
- package/dist/enums/onboarding.js +7 -2
- package/dist/enums/unsubscribe.js +39 -31
- package/dist/extensions/Blocks/Checkbox/control.js +23 -23
- package/dist/extensions/Blocks/RadioButton/control.js +15 -15
- package/dist/extensions/Blocks/RadioButton/template.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +60 -50
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +5 -5
- package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
- package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +27 -26
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +228 -181
- package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
- package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
- package/dist/extensions/Blocks/Recommendation/services/configService.js +76 -33
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +144 -91
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +19 -10
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +8 -8
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +25 -15
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +11 -11
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +1 -1
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +21 -0
- package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +13 -22
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +33 -0
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
- package/dist/node_modules/valibot/dist/index.js +450 -235
- package/dist/package.json.js +1 -1
- package/dist/services/templateLibraryApi.js +5 -4
- package/dist/services/unsubscribeApi.js +6 -6
- package/dist/src/@types/config/defaults.d.ts +5 -1
- package/dist/src/@types/config/index.d.ts +3 -3
- package/dist/src/@types/config/schemas.d.ts +217 -0
- package/dist/src/@types/config/types.d.ts +9 -1
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/AutoSaveController.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/AiStatusPill.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/AutoSaveToggle.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useAutoSave.d.ts +3 -0
- package/dist/src/composables/useConfig.d.ts +58 -0
- package/dist/src/composables/useCortexBlueprintBridge.d.ts +28 -0
- package/dist/src/composables/useEmailTemplateApplier.d.ts +21 -0
- package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
- package/dist/src/composables/useGuidoStateBridge.d.ts +22 -0
- package/dist/src/composables/useRecommendation.d.ts +10 -1
- package/dist/src/composables/useRecommendation.test.d.ts +1 -0
- package/dist/src/composables/useRibbonOffset.d.ts +4 -0
- package/dist/src/composables/useSave.d.ts +1 -1
- package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
- package/dist/src/config/migrator/index.d.ts +2 -1
- package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +2 -0
- package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +7 -0
- package/dist/src/config/migrator/recommendation/extractors.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +11 -0
- package/dist/src/config/migrator/recommendation/parseLegacyConfig.d.ts +15 -0
- package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +7 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/themeMapper.d.ts +5 -0
- package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/types.d.ts +205 -0
- package/dist/src/config/migrator/recommendationMigrator.d.ts +13 -1
- package/dist/src/config/migrator/recommendationMigrator.test.d.ts +1 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +5 -1
- package/dist/src/enums/onboarding.d.ts +6 -0
- package/dist/src/enums/unsubscribe.d.ts +13 -3
- package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
- package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +21 -3
- package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +41 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +21 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -3
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +21 -0
- package/dist/src/library.d.ts +1 -1
- package/dist/src/stores/ai-status.d.ts +41 -0
- package/dist/src/stores/autosave.d.ts +12 -0
- package/dist/src/stores/config.d.ts +522 -0
- package/dist/src/stores/editor.d.ts +23 -0
- package/dist/src/stores/guido-email-editor.d.ts +41 -0
- package/dist/src/stores/onboarding.d.ts +4 -0
- package/dist/src/utils/htmlEscape.d.ts +5 -0
- package/dist/src/utils/htmlEscape.test.d.ts +1 -0
- package/dist/src/utils/timeUtil.d.ts +8 -0
- package/dist/static/styles/components/button.css.js +16 -9
- package/dist/static/styles/components/loader.css.js +4 -0
- package/dist/static/styles/components/narrow-panel.css.js +52 -0
- package/dist/stores/ai-status.js +25 -0
- package/dist/stores/autosave.js +17 -0
- package/dist/stores/editor.js +3 -1
- package/dist/stores/guido-email-editor.js +20 -0
- package/dist/stores/onboarding.js +4 -0
- package/dist/utils/htmlEscape.js +13 -0
- package/dist/utils/pairProductVariables.js +89 -88
- package/dist/utils/templatePreparation.js +72 -32
- package/dist/utils/timeUtil.js +19 -0
- package/package.json +7 -3
- package/dist/enums/displayConditions.js +0 -80
- package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +0 -251
- package/dist/src/enums/displayConditions.d.ts +0 -2
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import { defineStore as
|
|
1
|
+
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as y } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as C } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
5
5
|
import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
|
|
6
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
6
|
+
import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
|
|
7
7
|
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
8
8
|
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
9
|
-
import { isFilterValid as
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
import { isFilterValid as w } from "../validation/filterSchema.js";
|
|
10
|
+
import { isConfigValid as v } from "../validation/requiredFields.js";
|
|
11
|
+
const h = C();
|
|
12
|
+
let m = null, u = null, d = null;
|
|
13
|
+
function k() {
|
|
13
14
|
return {
|
|
14
15
|
cardsInRow: F,
|
|
15
16
|
currencySettings: {
|
|
@@ -37,9 +38,9 @@ function I() {
|
|
|
37
38
|
customAttributes: []
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
function
|
|
41
|
+
function I() {
|
|
41
42
|
return {
|
|
42
|
-
recommendationConfigs:
|
|
43
|
+
recommendationConfigs: k(),
|
|
43
44
|
recommendationProducts: [],
|
|
44
45
|
filterStatus: !1,
|
|
45
46
|
filterSelectionDrawerStatus: !1,
|
|
@@ -48,7 +49,7 @@ function P() {
|
|
|
48
49
|
filterSnapshot: null
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
|
-
const
|
|
52
|
+
const N = () => ({
|
|
52
53
|
recommendationCampaignUrls: {},
|
|
53
54
|
activePredictiveAlgorithms: [],
|
|
54
55
|
languages: {},
|
|
@@ -57,8 +58,8 @@ const v = () => ({
|
|
|
57
58
|
blockStates: {},
|
|
58
59
|
currentRecommendationId: null,
|
|
59
60
|
configVersion: 0
|
|
60
|
-
}),
|
|
61
|
-
state: () =>
|
|
61
|
+
}), M = P("guidoRecommendationExtension", {
|
|
62
|
+
state: () => N(),
|
|
62
63
|
getters: {
|
|
63
64
|
// ====================================================================
|
|
64
65
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -68,7 +69,7 @@ const v = () => ({
|
|
|
68
69
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
69
70
|
*/
|
|
70
71
|
recommendationConfigs(t) {
|
|
71
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
72
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
|
|
72
73
|
},
|
|
73
74
|
/**
|
|
74
75
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -102,46 +103,45 @@ const v = () => ({
|
|
|
102
103
|
},
|
|
103
104
|
hasValidFilters() {
|
|
104
105
|
const { filters: t } = this.recommendationConfigs;
|
|
105
|
-
return t.length ? t.every((
|
|
106
|
+
return t.length ? t.every((e) => e.isValid) : !1;
|
|
106
107
|
},
|
|
107
108
|
getFilterGroupCount() {
|
|
108
109
|
const { filters: t } = this.recommendationConfigs;
|
|
109
|
-
return t.length ? new Set(t.map((
|
|
110
|
+
return t.length ? new Set(t.map((e) => e.filterGroup)).size : 0;
|
|
110
111
|
},
|
|
111
112
|
getUniqueFilterGroups() {
|
|
112
113
|
const { filters: t } = this.recommendationConfigs;
|
|
113
|
-
return [...new Set(t.map((
|
|
114
|
+
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
114
115
|
},
|
|
115
116
|
getActivePredictiveAlgorithms: (t) => {
|
|
116
|
-
const r = [];
|
|
117
|
-
return t.activePredictiveAlgorithms.filter((
|
|
118
|
-
r.push(...
|
|
119
|
-
}), r.map((
|
|
120
|
-
text:
|
|
121
|
-
value:
|
|
117
|
+
const e = g(), r = [];
|
|
118
|
+
return t.activePredictiveAlgorithms.filter((n) => !D.includes(n)).forEach((n) => {
|
|
119
|
+
r.push(...e.filter((c) => c.id === n));
|
|
120
|
+
}), r.map((n) => ({
|
|
121
|
+
text: n.name,
|
|
122
|
+
value: n.key
|
|
122
123
|
}));
|
|
123
124
|
},
|
|
124
|
-
getLanguages: (t) => Object.entries(t.languages).map(([
|
|
125
|
-
text:
|
|
126
|
-
value:
|
|
125
|
+
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
126
|
+
text: r,
|
|
127
|
+
value: e
|
|
127
128
|
})),
|
|
128
|
-
getCurrencySymbolList: (t) => t.currencyList.map((
|
|
129
|
-
text:
|
|
130
|
-
value:
|
|
129
|
+
getCurrencySymbolList: (t) => t.currencyList.map((e) => ({
|
|
130
|
+
text: e.text,
|
|
131
|
+
value: e.text
|
|
131
132
|
})),
|
|
132
133
|
getFilterList() {
|
|
133
134
|
return Object.values(this.filterList).map((t) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
|
|
135
|
+
let e;
|
|
136
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : y.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
137
137
|
text: t.displayName,
|
|
138
|
-
value:
|
|
138
|
+
value: e,
|
|
139
139
|
type: t.attributeType
|
|
140
140
|
};
|
|
141
141
|
});
|
|
142
142
|
},
|
|
143
143
|
getSelectedFilterGroup() {
|
|
144
|
-
return (t) => [...this.recommendationConfigs.filters].filter((
|
|
144
|
+
return (t) => [...this.recommendationConfigs.filters].filter((e) => e.filterGroup === t);
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
147
|
actions: {
|
|
@@ -155,7 +155,7 @@ const v = () => ({
|
|
|
155
155
|
setCurrentBlock(t) {
|
|
156
156
|
this.blockStates[t] || (this.blockStates = {
|
|
157
157
|
...this.blockStates,
|
|
158
|
-
[t]:
|
|
158
|
+
[t]: I()
|
|
159
159
|
}), this.currentRecommendationId = t;
|
|
160
160
|
},
|
|
161
161
|
/**
|
|
@@ -163,10 +163,15 @@ const v = () => ({
|
|
|
163
163
|
* Resets currentRecommendationId if it was the deleted block.
|
|
164
164
|
*/
|
|
165
165
|
removeBlockState(t) {
|
|
166
|
+
const e = t.toString();
|
|
167
|
+
if (this.recommendationCampaignUrls[e]) {
|
|
168
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
169
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
170
|
+
}
|
|
166
171
|
const r = { ...this.blockStates };
|
|
167
172
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
168
|
-
const
|
|
169
|
-
this.currentRecommendationId =
|
|
173
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
174
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
170
175
|
}
|
|
171
176
|
},
|
|
172
177
|
/**
|
|
@@ -176,37 +181,75 @@ const v = () => ({
|
|
|
176
181
|
markBlockInitialized(t) {
|
|
177
182
|
this.blockStates[t] && (this.blockStates[t].isInitialized = !0);
|
|
178
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* Seeds the URL-relevant fields of a block from a persisted node config.
|
|
186
|
+
*
|
|
187
|
+
* Used at save-time to ensure the campaign URL is built from the
|
|
188
|
+
* persisted truth (the `esd-ext-config` blob in the raw HTML) even when
|
|
189
|
+
* the user never selected the block in this editor session — without
|
|
190
|
+
* this seed, `_syncNodeConfigToStore` would never have run for that
|
|
191
|
+
* block and the store would hold default values (USD/en_US/mostPopular)
|
|
192
|
+
* instead of the real config.
|
|
193
|
+
*
|
|
194
|
+
* Creates the block entry if missing; otherwise patches only the URL-
|
|
195
|
+
* relevant subset and leaves runtime fields (e.g., `recommendedProducts`,
|
|
196
|
+
* `isInitialized`) alone.
|
|
197
|
+
*/
|
|
198
|
+
seedBlockUrlConfig(t, e) {
|
|
199
|
+
const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
|
|
200
|
+
name: e.currencyCode,
|
|
201
|
+
value: e.currencyCode,
|
|
202
|
+
symbol: e.currencyCode,
|
|
203
|
+
alignment: e.currencyAlignment === "before" ? "0" : "1",
|
|
204
|
+
decimalCount: String(e.currencyDecimalCount),
|
|
205
|
+
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
206
|
+
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
207
|
+
}, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
|
|
208
|
+
i.recommendationConfigs = {
|
|
209
|
+
...i.recommendationConfigs,
|
|
210
|
+
strategy: e.strategy,
|
|
211
|
+
language: e.language,
|
|
212
|
+
size: e.size,
|
|
213
|
+
productIds: e.productIds,
|
|
214
|
+
filters: e.filters,
|
|
215
|
+
shuffleProducts: e.shuffleProducts,
|
|
216
|
+
currencySettings: n
|
|
217
|
+
}, c && (this.blockStates = {
|
|
218
|
+
...this.blockStates,
|
|
219
|
+
[t]: i
|
|
220
|
+
});
|
|
221
|
+
},
|
|
179
222
|
/**
|
|
180
223
|
* Patches the current block's recommendationConfigs.
|
|
181
224
|
* Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
|
|
182
225
|
*/
|
|
183
|
-
patchCurrentBlockConfig(t,
|
|
226
|
+
patchCurrentBlockConfig(t, e = {}) {
|
|
184
227
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
185
228
|
return;
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
...
|
|
229
|
+
const r = this.blockStates[this.currentRecommendationId];
|
|
230
|
+
r.recommendationConfigs = {
|
|
231
|
+
...r.recommendationConfigs,
|
|
189
232
|
...t,
|
|
190
233
|
currencySettings: {
|
|
191
|
-
...
|
|
234
|
+
...r.recommendationConfigs.currencySettings,
|
|
192
235
|
...t.currencySettings || {}
|
|
193
236
|
}
|
|
194
237
|
};
|
|
195
|
-
const { triggerRefetch: n = !0 } =
|
|
238
|
+
const { triggerRefetch: n = !0 } = e;
|
|
196
239
|
n && this.configVersion++;
|
|
197
240
|
},
|
|
198
241
|
/**
|
|
199
242
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
200
243
|
*/
|
|
201
|
-
createDefaultFilter(t,
|
|
202
|
-
const [
|
|
244
|
+
createDefaultFilter(t, e) {
|
|
245
|
+
const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
|
|
203
246
|
return {
|
|
204
247
|
type: "standardFilter",
|
|
205
|
-
attribute: (
|
|
248
|
+
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
206
249
|
operator: (n == null ? void 0 : n.value) ?? "",
|
|
207
250
|
innerGroupOperator: "*",
|
|
208
251
|
outerGroupOperator: "*",
|
|
209
|
-
filterNumber:
|
|
252
|
+
filterNumber: e,
|
|
210
253
|
filterGroup: t,
|
|
211
254
|
isValid: !1,
|
|
212
255
|
value: ""
|
|
@@ -251,43 +294,43 @@ const v = () => ({
|
|
|
251
294
|
// ====================================================================
|
|
252
295
|
async fetchRecommendationCreateData() {
|
|
253
296
|
if (!this.activePredictiveAlgorithms.length) {
|
|
254
|
-
if (
|
|
255
|
-
await
|
|
297
|
+
if (m) {
|
|
298
|
+
await m;
|
|
256
299
|
return;
|
|
257
300
|
}
|
|
258
|
-
|
|
301
|
+
m = (async () => {
|
|
259
302
|
const {
|
|
260
303
|
activePredictiveAlgorithms: t,
|
|
261
|
-
languages:
|
|
262
|
-
currencies:
|
|
304
|
+
languages: e,
|
|
305
|
+
currencies: r
|
|
263
306
|
} = await h.fetchRecommendationCreateData();
|
|
264
|
-
if (this.activePredictiveAlgorithms = t, this.languages =
|
|
307
|
+
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
265
308
|
const n = this.blockStates[this.currentRecommendationId];
|
|
266
309
|
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
267
310
|
}
|
|
268
|
-
this.currencyList =
|
|
311
|
+
this.currencyList = r;
|
|
269
312
|
})();
|
|
270
313
|
try {
|
|
271
|
-
await
|
|
314
|
+
await m;
|
|
272
315
|
} finally {
|
|
273
|
-
|
|
316
|
+
m = null;
|
|
274
317
|
}
|
|
275
318
|
}
|
|
276
319
|
},
|
|
277
320
|
async fetchRecommendationFilters() {
|
|
278
321
|
if (!Object.keys(this.filterList).length) {
|
|
279
|
-
if (
|
|
280
|
-
await
|
|
322
|
+
if (u) {
|
|
323
|
+
await u;
|
|
281
324
|
return;
|
|
282
325
|
}
|
|
283
|
-
|
|
326
|
+
u = (async () => {
|
|
284
327
|
const t = await h.fetchRecommendationFilters();
|
|
285
328
|
this.filterList = t;
|
|
286
329
|
})();
|
|
287
330
|
try {
|
|
288
|
-
await
|
|
331
|
+
await u;
|
|
289
332
|
} finally {
|
|
290
|
-
|
|
333
|
+
u = null;
|
|
291
334
|
}
|
|
292
335
|
}
|
|
293
336
|
},
|
|
@@ -302,8 +345,8 @@ const v = () => ({
|
|
|
302
345
|
deleteFilterGroup(t) {
|
|
303
346
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
304
347
|
return;
|
|
305
|
-
const
|
|
306
|
-
|
|
348
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
|
|
349
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
307
350
|
...i,
|
|
308
351
|
filterGroup: c.get(i.filterGroup) ?? i.filterGroup
|
|
309
352
|
}));
|
|
@@ -311,51 +354,59 @@ const v = () => ({
|
|
|
311
354
|
updateFilter(t) {
|
|
312
355
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
313
356
|
return;
|
|
314
|
-
const
|
|
315
|
-
if (
|
|
316
|
-
const n = [...
|
|
317
|
-
n[
|
|
357
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
358
|
+
if (r !== -1) {
|
|
359
|
+
const n = [...e.recommendationConfigs.filters];
|
|
360
|
+
n[r] = {
|
|
318
361
|
...t,
|
|
319
|
-
isValid:
|
|
320
|
-
},
|
|
362
|
+
isValid: w(t)
|
|
363
|
+
}, e.recommendationConfigs.filters = n;
|
|
321
364
|
}
|
|
322
365
|
},
|
|
323
366
|
deleteFilter(t) {
|
|
324
367
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
325
368
|
return;
|
|
326
|
-
const
|
|
327
|
-
if (
|
|
328
|
-
let n = [...
|
|
329
|
-
if (n.splice(
|
|
369
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
370
|
+
if (r !== -1) {
|
|
371
|
+
let n = [...e.recommendationConfigs.filters];
|
|
372
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
330
373
|
let i = 1;
|
|
331
374
|
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
332
375
|
} else {
|
|
333
|
-
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s,
|
|
376
|
+
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
|
|
334
377
|
n = n.map((s) => ({
|
|
335
378
|
...s,
|
|
336
379
|
filterGroup: o.get(s.filterGroup) ?? s.filterGroup
|
|
337
380
|
}));
|
|
338
381
|
}
|
|
339
|
-
|
|
382
|
+
e.recommendationConfigs.filters = n;
|
|
340
383
|
}
|
|
341
384
|
},
|
|
342
385
|
addFilter(t) {
|
|
343
386
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
344
387
|
return;
|
|
345
|
-
const
|
|
388
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
|
|
346
389
|
(o) => o.filterGroup === t.filterGroup
|
|
347
|
-
).length + 1, i =
|
|
348
|
-
i !== -1 ?
|
|
390
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
391
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
349
392
|
...t,
|
|
350
393
|
filterNumber: c
|
|
351
|
-
}) :
|
|
394
|
+
}) : r.push({
|
|
352
395
|
...t,
|
|
353
396
|
filterNumber: c
|
|
354
|
-
}),
|
|
397
|
+
}), e.recommendationConfigs.filters = r;
|
|
355
398
|
},
|
|
356
399
|
generateFilterQuery() {
|
|
357
400
|
return b(this.recommendationConfigs.filters);
|
|
358
401
|
},
|
|
402
|
+
/**
|
|
403
|
+
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
404
|
+
* (not a getter) so reading it does not register reactive tracking on
|
|
405
|
+
* every block's recommendationConfigs across user edits.
|
|
406
|
+
*/
|
|
407
|
+
hasInvalidBlock() {
|
|
408
|
+
return Object.values(this.blockStates).some((t) => !v(t.recommendationConfigs, this));
|
|
409
|
+
},
|
|
359
410
|
// ====================================================================
|
|
360
411
|
// Per-Block Product Fetching
|
|
361
412
|
// ====================================================================
|
|
@@ -375,29 +426,31 @@ const v = () => ({
|
|
|
375
426
|
},
|
|
376
427
|
async _doFetchProducts() {
|
|
377
428
|
var p;
|
|
378
|
-
const t = this.currentRecommendationId,
|
|
379
|
-
locale:
|
|
380
|
-
currency:
|
|
429
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
|
|
430
|
+
locale: r.language,
|
|
431
|
+
currency: r.currencySettings.value,
|
|
381
432
|
partnerName: o.partnerName,
|
|
382
|
-
size:
|
|
433
|
+
size: r.size,
|
|
383
434
|
details: !0,
|
|
384
435
|
campaignId: o.variationId
|
|
385
436
|
};
|
|
386
|
-
|
|
387
|
-
const l = parseInt(e.size) || 6;
|
|
437
|
+
r.strategy === "manualMerchandising" ? a.productId = r.productIds.slice(0, s).join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0);
|
|
388
438
|
let f;
|
|
389
439
|
try {
|
|
390
|
-
f = await h.fetchRecommendationProducts(i,
|
|
440
|
+
f = await h.fetchRecommendationProducts(i, a);
|
|
391
441
|
} catch {
|
|
392
442
|
f = [];
|
|
393
443
|
}
|
|
394
444
|
if (this.blockStates[t]) {
|
|
395
|
-
const
|
|
396
|
-
this.blockStates[t].recommendationProducts =
|
|
445
|
+
const l = f.length > 0 ? f : S(s);
|
|
446
|
+
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
447
|
+
...l,
|
|
448
|
+
...S(s - l.length)
|
|
449
|
+
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
397
450
|
}
|
|
398
451
|
}
|
|
399
452
|
}
|
|
400
453
|
});
|
|
401
454
|
export {
|
|
402
|
-
|
|
455
|
+
M as useRecommendationExtensionStore
|
|
403
456
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RecommendationBlockId as s } from "../../constants/blockIds.js";
|
|
2
|
-
import { ATTR_PRODUCT_ATTR as
|
|
2
|
+
import { ATTR_PRODUCT_ATTR as b, ATTR_PRODUCT_BUTTON as u, ATTR_PRODUCT_OMNIBUS_DISCOUNT as m, ATTR_PRODUCT_OMNIBUS_PRICE as h, ATTR_PRODUCT_OLD_PRICE as y, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_NAME as f, ATTR_PRODUCT_IMAGE as x } from "../../constants/selectors.js";
|
|
3
3
|
import { useRecommendationExtensionStore as _ } from "../../store/recommendation.js";
|
|
4
4
|
import { formatPrice as $ } from "../../utils/priceFormatter.js";
|
|
5
5
|
import { sanitizeImageUrl as C, CUSTOM_CELL_HTML as R } from "../utils.js";
|
|
@@ -15,7 +15,7 @@ function p() {
|
|
|
15
15
|
thousandSeparator: e.thousandSeparator
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function i(t, e = "price") {
|
|
19
19
|
const o = p(), n = t[e], d = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
|
|
20
20
|
return $({
|
|
21
21
|
price: d,
|
|
@@ -92,7 +92,7 @@ const I = {
|
|
|
92
92
|
align="center"
|
|
93
93
|
esd-extension-block-id="${s.PRICE}">
|
|
94
94
|
<p contenteditable="false" style="font-size: 16px; color: #333333;">
|
|
95
|
-
<strong>${
|
|
95
|
+
<strong>${i(t, "price")}</strong>
|
|
96
96
|
</p>
|
|
97
97
|
</td>
|
|
98
98
|
</tr>
|
|
@@ -116,7 +116,7 @@ const I = {
|
|
|
116
116
|
align="center"
|
|
117
117
|
esd-extension-block-id="${s.OLD_PRICE}">
|
|
118
118
|
<p contenteditable="false" style="font-size: 14px; color: #999999;">
|
|
119
|
-
<strong>${
|
|
119
|
+
<strong>${i(t, "original_price")}</strong>
|
|
120
120
|
</p>
|
|
121
121
|
</td>
|
|
122
122
|
</tr>
|
|
@@ -143,7 +143,7 @@ const I = {
|
|
|
143
143
|
esd-extension-block-id="${s.OMNIBUS_PRICE}">
|
|
144
144
|
<p contenteditable="false" style="font-size: 12px; color: #666666;">
|
|
145
145
|
<span class="omnibus-text-before">Lowest 30-day price: </span>
|
|
146
|
-
<span class="omnibus-price-value">${
|
|
146
|
+
<span class="omnibus-price-value">${i(t, "original_price")}</span>
|
|
147
147
|
<span class="omnibus-text-after"></span>
|
|
148
148
|
</p>
|
|
149
149
|
</td>
|
|
@@ -153,8 +153,8 @@ const I = {
|
|
|
153
153
|
</td>
|
|
154
154
|
`,
|
|
155
155
|
[m]: (t) => {
|
|
156
|
-
var
|
|
157
|
-
const e = p(), o = ((
|
|
156
|
+
var r, c;
|
|
157
|
+
const e = p(), o = ((r = t.original_price) == null ? void 0 : r[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((c = t.price) == null ? void 0 : c[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, d = o > 0 ? Math.round((o - n) / o * 100) : 0, g = d > 0 ? `-${d}%` : "0%";
|
|
158
158
|
return `
|
|
159
159
|
<td class="${l}" style="padding: ${a}; height: 100%;" valign="top">
|
|
160
160
|
<table
|
|
@@ -174,7 +174,7 @@ const I = {
|
|
|
174
174
|
esd-extension-block-id="${s.OMNIBUS_DISCOUNT}">
|
|
175
175
|
<p contenteditable="false" style="font-size: 12px; color: #666666;">
|
|
176
176
|
<span class="omnibus-text-before"></span>
|
|
177
|
-
<span class="omnibus-discount-value">${
|
|
177
|
+
<span class="omnibus-discount-value">${g}</span>
|
|
178
178
|
<span class="omnibus-text-after"></span>
|
|
179
179
|
</p>
|
|
180
180
|
</td>
|
|
@@ -210,7 +210,16 @@ const I = {
|
|
|
210
210
|
href="#"
|
|
211
211
|
class="es-button buy-button"
|
|
212
212
|
target="_blank"
|
|
213
|
-
style="
|
|
213
|
+
style="
|
|
214
|
+
color: rgb(56, 118, 29);
|
|
215
|
+
background: rgb(217, 234, 211);
|
|
216
|
+
font-family: arial, 'helvetica neue', helvetica, sans-serif;
|
|
217
|
+
font-size: 16px;
|
|
218
|
+
font-weight: normal;
|
|
219
|
+
line-height: 120%;
|
|
220
|
+
mso-border-alt: 10px solid rgb(217, 234, 211);
|
|
221
|
+
mso-padding-alt: 0;
|
|
222
|
+
">
|
|
214
223
|
Buy
|
|
215
224
|
</a>
|
|
216
225
|
</span>
|
|
@@ -240,7 +249,7 @@ const I = {
|
|
|
240
249
|
<tbody>
|
|
241
250
|
<tr valign="top">
|
|
242
251
|
<td
|
|
243
|
-
${
|
|
252
|
+
${b}="${t}"
|
|
244
253
|
class="esd-block-text product-custom-attribute es-p0t es-p0b es-p15l es-p15r"
|
|
245
254
|
align="center"
|
|
246
255
|
esd-extension-block-id="${s.CUSTOM_ATTRIBUTE}">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_PRODUCTS_PER_ROW as L } from "../../constants/layout.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { getDefaultProducts as E, createBlockTemplate as I, DEFAULTS as _, DEFAULT_CARD_COMPOSITION as S, spacer as b, buildElementRenderer as A, DEFAULT_CARD_VISIBILITY as f } from "../utils.js";
|
|
3
|
+
import { ATTRIBUTE_CELL_CLASS as w, DEFAULT_CELL_PADDING as D, gridElementRenderer as C } from "./elementRenderer.js";
|
|
4
4
|
const O = `
|
|
5
5
|
<tr class="recommendation-product-row">
|
|
6
6
|
<td>
|
|
@@ -27,8 +27,8 @@ const O = `
|
|
|
27
27
|
{-{-CELLS-}-}
|
|
28
28
|
</tr>
|
|
29
29
|
`;
|
|
30
|
-
function P(t, e, o, r =
|
|
31
|
-
const c = (100 / e).toFixed(2), i = e - t.length, l = `<td class="${
|
|
30
|
+
function P(t, e, o, r = S, n = {}) {
|
|
31
|
+
const c = (100 / e).toFixed(2), i = e - t.length, l = `<td class="${w}" style="padding: ${D};" width="${c}%"></td>`, d = i > 0 ? l.repeat(i) : "", a = A(o, r, n);
|
|
32
32
|
return r.filter((s) => a[s]).map((s) => {
|
|
33
33
|
const T = f[s] ?? !0, u = T ? "" : 'style="display: none;"', R = t.map((m) => a[s](m).replace("<td", `<td width="${c}%"`)).join("");
|
|
34
34
|
return g.replace("{-{-ATTR_TYPE-}-}", s).replace("{-{-VISIBILITY-}-}", T ? "1" : "0").replace("{-{-DISPLAY_STYLE-}-}", u).replace("{-{-CELLS-}-}", R + d);
|
|
@@ -46,15 +46,15 @@ function U(t, e, o, r, n = {}) {
|
|
|
46
46
|
r,
|
|
47
47
|
n
|
|
48
48
|
), p = O.replace("{-{-ATTRIBUTE_ROWS-}-}", a);
|
|
49
|
-
return d > 0 ?
|
|
49
|
+
return d > 0 ? b + p : p;
|
|
50
50
|
}).join("");
|
|
51
51
|
}
|
|
52
52
|
function h(t, e, o, r = {}) {
|
|
53
|
-
return U(t, e,
|
|
53
|
+
return U(t, e, C, o, r);
|
|
54
54
|
}
|
|
55
55
|
function F(t) {
|
|
56
|
-
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o =
|
|
57
|
-
return o.replace("{-{-TITLE-}-}",
|
|
56
|
+
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o = I("grid", e), r = E(), n = h(r, L);
|
|
57
|
+
return o.replace("{-{-TITLE-}-}", _.TITLE).replace("{-{-PRODUCT_ROWS-}-}", n).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
|
|
58
58
|
}
|
|
59
59
|
export {
|
|
60
60
|
F as getDefaultTemplate,
|