@useinsider/guido 3.17.0 → 3.18.0-beta.0ece468
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 +6 -5
- package/dist/@types/config/schemas.js +7 -6
- package/dist/components/Guido.vue.js +10 -10
- package/dist/components/Guido.vue2.js +84 -78
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +23 -0
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +122 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +20 -18
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +46 -0
- package/dist/composables/useCustomInterfaceAppearance.js +52 -38
- package/dist/composables/useModuleRepair.js +33 -0
- package/dist/composables/useRecommendation.js +41 -34
- package/dist/composables/useSave.js +30 -29
- package/dist/composables/useStripo.js +15 -15
- package/dist/composables/useSyncModuleExtractor.js +15 -13
- package/dist/composables/validators/useSyncModuleBlockValidator.js +24 -0
- package/dist/config/i18n/en/labels.json.js +1 -1
- package/dist/config/migrator/index.js +9 -8
- package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
- package/dist/config/migrator/recommendation/extractors.js +29 -24
- package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
- package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
- package/dist/config/migrator/recommendationMigrator.js +31 -25
- package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
- package/dist/enums/academy.js +2 -1
- package/dist/enums/date.js +5 -3
- package/dist/enums/extensions/recommendationBlock.js +40 -31
- package/dist/extensions/Blocks/Items/block.js +118 -49
- package/dist/extensions/Blocks/Items/constants/currency.js +25 -0
- package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
- package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
- package/dist/extensions/Blocks/Items/template.js +153 -152
- package/dist/extensions/Blocks/Items/utils/constants.js +4 -0
- package/dist/extensions/Blocks/Recommendation/block.js +35 -29
- package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +29 -27
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +309 -236
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +241 -180
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +128 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
- package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
- package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
- package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +236 -79
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
- package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
- package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +10 -6
- package/dist/extensions/Blocks/common-control.js +22 -19
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +69 -30
- package/dist/src/@types/config/schemas.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
- package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
- package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useModuleRepair.d.ts +18 -0
- package/dist/src/composables/useRecommendation.d.ts +1 -0
- package/dist/src/composables/useSyncModuleExtractor.d.ts +2 -0
- package/dist/src/composables/validators/useSyncModuleBlockValidator.d.ts +3 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
- package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
- package/dist/src/enums/academy.d.ts +1 -0
- package/dist/src/enums/date.d.ts +1 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +4 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +35 -0
- package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +43 -0
- package/dist/src/extensions/Blocks/Items/utils/constants.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +3 -6
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +17 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +225 -10
- package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +6 -2
- package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
- package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
- package/dist/src/services/recommendationApi.d.ts +4 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/stores/onboarding.d.ts +377 -0
- package/dist/src/stores/save-as-template.d.ts +4 -3
- package/dist/src/utils/genericUtil.d.ts +5 -0
- package/dist/src/utils/itemsCurrencyRepair.d.ts +17 -0
- package/dist/static/assets/icons/line-change.svg.js +5 -0
- package/dist/static/assets/icons/line-delete.svg.js +5 -0
- package/dist/static/assets/icons/line-plus.svg.js +5 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +172 -0
- package/dist/static/styles/customEditorStyle.css.js +3 -1
- package/dist/stores/onboarding.js +41 -36
- package/dist/utils/dateUtil.js +23 -10
- package/dist/utils/genericUtil.js +28 -27
- package/dist/utils/itemsCurrencyRepair.js +39 -0
- package/dist/utils/pairProductVariables.js +58 -58
- package/dist/utils/templatePreparation.js +35 -34
- package/package.json +3 -2
- package/dist/composables/useModuleDynamicContentRepair.js +0 -37
- package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -13
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import { getRecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import {
|
|
1
|
+
import { getRecommendationFeedSourceMaps as C, strategyEditPath as _, URLS as D, getOperatorOptions as L, PriceAttributes as N } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as U } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as E } from "../../../../stores/config.js";
|
|
4
|
+
import { asText as w } from "../../../../utils/genericUtil.js";
|
|
5
|
+
import { defineStore as A } from "pinia";
|
|
5
6
|
import "../constants/selectors.js";
|
|
6
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
7
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
8
|
-
import { getDefaultProducts as
|
|
9
|
-
import { generateCompleteFilterQuery as
|
|
10
|
-
import { getPartnerRecommendationParams as
|
|
11
|
-
import { sanitizeProductIds as
|
|
12
|
-
import { isFilterValid as
|
|
13
|
-
import { isConfigValid as
|
|
14
|
-
const
|
|
15
|
-
let
|
|
16
|
-
|
|
7
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as x, DEFAULT_CARDS_IN_ROW as B } from "../constants/layout.js";
|
|
8
|
+
import { DEFAULT_NODE_CONFIG as M, EXCLUDED_ALGORITHM_IDS as T } from "../constants/defaultConfig.js";
|
|
9
|
+
import { getDefaultProducts as v } from "../templates/utils.js";
|
|
10
|
+
import { generateCompleteFilterQuery as G } from "../utils/filterUtil.js";
|
|
11
|
+
import { getPartnerRecommendationParams as O } from "../utils/partnerCustomizations.js";
|
|
12
|
+
import { sanitizeProductIds as z } from "../utils/productIds.js";
|
|
13
|
+
import { isFilterValid as V } from "../validation/filterSchema.js";
|
|
14
|
+
import { isConfigValid as $ } from "../validation/requiredFields.js";
|
|
15
|
+
const d = U();
|
|
16
|
+
let g = null, h = null, S = null, p = null, I = 0;
|
|
17
|
+
const b = /* @__PURE__ */ new Map();
|
|
18
|
+
let u = null, y = null;
|
|
19
|
+
const j = (t, e) => {
|
|
20
|
+
const r = t.filter((s) => !e.has(String(s.strategy_id)));
|
|
21
|
+
if (!r.length)
|
|
22
|
+
return null;
|
|
23
|
+
const n = r.reduce((s, i) => w(i.created_at) > w(s.created_at) ? i : s);
|
|
24
|
+
return String(n.strategy_id);
|
|
25
|
+
};
|
|
26
|
+
function P() {
|
|
17
27
|
return {
|
|
18
|
-
cardsInRow:
|
|
28
|
+
cardsInRow: B,
|
|
19
29
|
currencySettings: {
|
|
20
30
|
name: "USD",
|
|
21
31
|
value: "USD",
|
|
@@ -29,13 +39,14 @@ function k() {
|
|
|
29
39
|
productIds: [],
|
|
30
40
|
id: 1,
|
|
31
41
|
language: "en_US",
|
|
32
|
-
mobileCardsInRow:
|
|
42
|
+
mobileCardsInRow: x,
|
|
33
43
|
mobileLayoutEnabled: !1,
|
|
34
44
|
orientation: "grid",
|
|
35
45
|
recommendedProducts: [],
|
|
36
46
|
sendProductRequestFlag: !1,
|
|
37
47
|
shuffleProducts: !1,
|
|
38
48
|
strategy: "mostPopular",
|
|
49
|
+
strategyId: "",
|
|
39
50
|
textTrimming: !0,
|
|
40
51
|
unresponsive: !1,
|
|
41
52
|
size: "6",
|
|
@@ -44,28 +55,35 @@ function k() {
|
|
|
44
55
|
priceHideIfSameAsDiscounted: !1
|
|
45
56
|
};
|
|
46
57
|
}
|
|
47
|
-
function
|
|
58
|
+
function F() {
|
|
48
59
|
return {
|
|
49
|
-
recommendationConfigs:
|
|
60
|
+
recommendationConfigs: P(),
|
|
50
61
|
recommendationProducts: [],
|
|
51
62
|
filterStatus: !1,
|
|
52
63
|
filterSelectionDrawerStatus: !1,
|
|
64
|
+
assignStrategyDrawerStatus: !1,
|
|
65
|
+
removeStrategyModalStatus: !1,
|
|
53
66
|
filterGroup: 1,
|
|
54
67
|
isInitialized: !1,
|
|
55
68
|
filterSnapshot: null
|
|
56
69
|
};
|
|
57
70
|
}
|
|
58
|
-
const
|
|
71
|
+
const q = () => ({
|
|
59
72
|
recommendationCampaignUrls: {},
|
|
60
73
|
activePredictiveAlgorithms: [],
|
|
61
74
|
languages: {},
|
|
62
75
|
currencyList: [],
|
|
63
76
|
filterList: {},
|
|
77
|
+
strategies: [],
|
|
78
|
+
strategiesLoading: !1,
|
|
79
|
+
strategyUrlTemplates: {},
|
|
80
|
+
lastCreatedStrategyId: null,
|
|
81
|
+
strategiesFetched: !1,
|
|
64
82
|
blockStates: {},
|
|
65
83
|
currentRecommendationId: null,
|
|
66
84
|
configVersion: 0
|
|
67
|
-
}),
|
|
68
|
-
state: () =>
|
|
85
|
+
}), st = A("guidoRecommendationExtension", {
|
|
86
|
+
state: () => q(),
|
|
69
87
|
getters: {
|
|
70
88
|
// ====================================================================
|
|
71
89
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -75,7 +93,7 @@ const U = () => ({
|
|
|
75
93
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
76
94
|
*/
|
|
77
95
|
recommendationConfigs(t) {
|
|
78
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
96
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : P();
|
|
79
97
|
},
|
|
80
98
|
/**
|
|
81
99
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -89,6 +107,16 @@ const U = () => ({
|
|
|
89
107
|
filterSelectionDrawerStatus(t) {
|
|
90
108
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
91
109
|
},
|
|
110
|
+
assignStrategyDrawerStatus(t) {
|
|
111
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
|
|
112
|
+
},
|
|
113
|
+
removeStrategyModalStatus(t) {
|
|
114
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
|
|
115
|
+
},
|
|
116
|
+
assignedStrategy(t) {
|
|
117
|
+
const { strategyId: e } = this.recommendationConfigs;
|
|
118
|
+
return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
|
|
119
|
+
},
|
|
92
120
|
/**
|
|
93
121
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
94
122
|
*/
|
|
@@ -120,9 +148,9 @@ const U = () => ({
|
|
|
120
148
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
121
149
|
},
|
|
122
150
|
getActivePredictiveAlgorithms: (t) => {
|
|
123
|
-
const e =
|
|
124
|
-
return t.activePredictiveAlgorithms.filter((n) => !
|
|
125
|
-
r.push(...e.filter((
|
|
151
|
+
const e = C(), r = [];
|
|
152
|
+
return t.activePredictiveAlgorithms.filter((n) => !T.includes(n)).forEach((n) => {
|
|
153
|
+
r.push(...e.filter((s) => s.id === n));
|
|
126
154
|
}), r.map((n) => ({
|
|
127
155
|
text: n.name,
|
|
128
156
|
value: n.key
|
|
@@ -139,7 +167,7 @@ const U = () => ({
|
|
|
139
167
|
getFilterList() {
|
|
140
168
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
141
169
|
let e;
|
|
142
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
170
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : N.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
143
171
|
text: t.displayName,
|
|
144
172
|
value: e,
|
|
145
173
|
type: t.attributeType
|
|
@@ -161,7 +189,7 @@ const U = () => ({
|
|
|
161
189
|
setCurrentBlock(t) {
|
|
162
190
|
this.blockStates[t] || (this.blockStates = {
|
|
163
191
|
...this.blockStates,
|
|
164
|
-
[t]:
|
|
192
|
+
[t]: F()
|
|
165
193
|
}), this.currentRecommendationId = t;
|
|
166
194
|
},
|
|
167
195
|
/**
|
|
@@ -193,10 +221,10 @@ const U = () => ({
|
|
|
193
221
|
[e]: o
|
|
194
222
|
};
|
|
195
223
|
}
|
|
196
|
-
const n = t.toString(),
|
|
224
|
+
const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
|
|
197
225
|
i && (this.recommendationCampaignUrls = {
|
|
198
226
|
...this.recommendationCampaignUrls,
|
|
199
|
-
[
|
|
227
|
+
[s]: i
|
|
200
228
|
});
|
|
201
229
|
},
|
|
202
230
|
/**
|
|
@@ -221,7 +249,7 @@ const U = () => ({
|
|
|
221
249
|
* `isInitialized`) alone.
|
|
222
250
|
*/
|
|
223
251
|
seedBlockUrlConfig(t, e) {
|
|
224
|
-
const r = (o,
|
|
252
|
+
const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
|
|
225
253
|
name: e.currencyCode,
|
|
226
254
|
value: e.currencyCode,
|
|
227
255
|
symbol: e.currencyCode,
|
|
@@ -229,17 +257,18 @@ const U = () => ({
|
|
|
229
257
|
decimalCount: String(e.currencyDecimalCount),
|
|
230
258
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
231
259
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
232
|
-
},
|
|
260
|
+
}, s = !this.blockStates[t], i = s ? F() : this.blockStates[t];
|
|
233
261
|
i.recommendationConfigs = {
|
|
234
262
|
...i.recommendationConfigs,
|
|
235
263
|
strategy: e.strategy,
|
|
264
|
+
strategyId: e.strategyId,
|
|
236
265
|
language: e.language,
|
|
237
266
|
size: e.size,
|
|
238
267
|
productIds: e.productIds,
|
|
239
268
|
filters: e.filters,
|
|
240
269
|
shuffleProducts: e.shuffleProducts,
|
|
241
270
|
currencySettings: n
|
|
242
|
-
},
|
|
271
|
+
}, s && (this.blockStates = {
|
|
243
272
|
...this.blockStates,
|
|
244
273
|
[t]: i
|
|
245
274
|
});
|
|
@@ -267,7 +296,7 @@ const U = () => ({
|
|
|
267
296
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
268
297
|
*/
|
|
269
298
|
createDefaultFilter(t, e) {
|
|
270
|
-
const [r] = this.getFilterList, [n] =
|
|
299
|
+
const [r] = this.getFilterList, [n] = L(r == null ? void 0 : r.type);
|
|
271
300
|
return {
|
|
272
301
|
type: "standardFilter",
|
|
273
302
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
@@ -314,21 +343,121 @@ const U = () => ({
|
|
|
314
343
|
const t = this.blockStates[this.currentRecommendationId];
|
|
315
344
|
t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
|
|
316
345
|
},
|
|
346
|
+
openAssignStrategyDrawer() {
|
|
347
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !0);
|
|
348
|
+
},
|
|
349
|
+
closeAssignStrategyDrawer() {
|
|
350
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
|
|
351
|
+
},
|
|
352
|
+
openRemoveStrategyModal() {
|
|
353
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !0);
|
|
354
|
+
},
|
|
355
|
+
closeRemoveStrategyModal() {
|
|
356
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
|
|
357
|
+
},
|
|
358
|
+
async fetchStrategies() {
|
|
359
|
+
if (p && await p, this.strategiesFetched)
|
|
360
|
+
return;
|
|
361
|
+
const t = I;
|
|
362
|
+
p = (async () => {
|
|
363
|
+
this.strategiesLoading = !0;
|
|
364
|
+
try {
|
|
365
|
+
const e = await d.fetchRecommendationStrategies();
|
|
366
|
+
if (t !== I)
|
|
367
|
+
return;
|
|
368
|
+
if (this.strategies = e, this.strategiesFetched = !0, y) {
|
|
369
|
+
const r = j(e, y);
|
|
370
|
+
r && (this.lastCreatedStrategyId = r), y = new Set(e.map((n) => String(n.strategy_id)));
|
|
371
|
+
}
|
|
372
|
+
} finally {
|
|
373
|
+
this.strategiesLoading = !1;
|
|
374
|
+
}
|
|
375
|
+
})();
|
|
376
|
+
try {
|
|
377
|
+
await p;
|
|
378
|
+
} finally {
|
|
379
|
+
p = null;
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
invalidateStrategies() {
|
|
383
|
+
this.strategiesFetched = !1, I += 1;
|
|
384
|
+
},
|
|
385
|
+
/**
|
|
386
|
+
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
387
|
+
* the user comes back. `visibilitychange` covers the tab case; `focus` covers the page
|
|
388
|
+
* landing in a separate window, where this document never goes hidden.
|
|
389
|
+
*
|
|
390
|
+
* Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
|
|
391
|
+
* strategy in it and come back again — a listener that disarmed on the first return would
|
|
392
|
+
* leave that one missing from the list. Armed only once the user actually opens a strategy
|
|
393
|
+
* page, so anyone who never does pays nothing.
|
|
394
|
+
*/
|
|
395
|
+
_armStrategyPageReturn(t) {
|
|
396
|
+
window.open(t, "_blank", "noopener"), u == null || u();
|
|
397
|
+
let e = !1;
|
|
398
|
+
const r = () => {
|
|
399
|
+
document.hidden || e || (e = !0, this.invalidateStrategies(), this.fetchStrategies().catch(() => {
|
|
400
|
+
}).finally(() => {
|
|
401
|
+
e = !1;
|
|
402
|
+
}));
|
|
403
|
+
};
|
|
404
|
+
document.addEventListener("visibilitychange", r), window.addEventListener("focus", r), u = () => {
|
|
405
|
+
document.removeEventListener("visibilitychange", r), window.removeEventListener("focus", r), u = null;
|
|
406
|
+
};
|
|
407
|
+
},
|
|
408
|
+
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
409
|
+
disposeStrategyPageReturn() {
|
|
410
|
+
u == null || u(), y = null;
|
|
411
|
+
},
|
|
412
|
+
/**
|
|
413
|
+
* Opens Smart Recommender's strategy creation page. Every return refreshes the list, and any
|
|
414
|
+
* strategy that appeared since the page was opened is remembered so the drawer preselects it —
|
|
415
|
+
* including a second one created without ever closing that tab.
|
|
416
|
+
*/
|
|
417
|
+
openStrategyCreation() {
|
|
418
|
+
y = new Set(this.strategies.map((t) => String(t.strategy_id))), this._armStrategyPageReturn(D.RECOMMENDATION_STRATEGY_CREATE_PATH);
|
|
419
|
+
},
|
|
420
|
+
/**
|
|
421
|
+
* Opens the strategy's edit page. Every return refreshes the list so the block reflects the
|
|
422
|
+
* edited configuration; nothing is preselected because the strategy is already assigned.
|
|
423
|
+
*/
|
|
424
|
+
openStrategyEdit(t) {
|
|
425
|
+
this._armStrategyPageReturn(_(t));
|
|
426
|
+
},
|
|
427
|
+
async resolveStrategyUrlTemplate(t, e) {
|
|
428
|
+
const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
|
|
429
|
+
if (s)
|
|
430
|
+
return s;
|
|
431
|
+
const { full_path: i = "" } = await d.generateStrategyEndpoint(t, e) ?? {};
|
|
432
|
+
return n && i && (this.strategyUrlTemplates = {
|
|
433
|
+
...this.strategyUrlTemplates,
|
|
434
|
+
[n]: i
|
|
435
|
+
}), i;
|
|
436
|
+
},
|
|
437
|
+
assignStrategy(t) {
|
|
438
|
+
this.patchCurrentBlockConfig({
|
|
439
|
+
strategyId: String(t.strategy_id),
|
|
440
|
+
...t.size !== void 0 ? { size: String(t.size) } : {}
|
|
441
|
+
});
|
|
442
|
+
},
|
|
443
|
+
removeStrategy() {
|
|
444
|
+
this.patchCurrentBlockConfig({ strategyId: "", size: M.size });
|
|
445
|
+
},
|
|
317
446
|
// ====================================================================
|
|
318
447
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
319
448
|
// ====================================================================
|
|
320
449
|
async fetchRecommendationCreateData() {
|
|
321
450
|
if (!this.activePredictiveAlgorithms.length) {
|
|
322
|
-
if (
|
|
323
|
-
await
|
|
451
|
+
if (g) {
|
|
452
|
+
await g;
|
|
324
453
|
return;
|
|
325
454
|
}
|
|
326
|
-
|
|
455
|
+
g = (async () => {
|
|
327
456
|
const {
|
|
328
457
|
activePredictiveAlgorithms: t,
|
|
329
458
|
languages: e,
|
|
330
459
|
currencies: r
|
|
331
|
-
} = await
|
|
460
|
+
} = await d.fetchRecommendationCreateData();
|
|
332
461
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
333
462
|
const n = this.blockStates[this.currentRecommendationId];
|
|
334
463
|
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
@@ -336,26 +465,26 @@ const U = () => ({
|
|
|
336
465
|
this.currencyList = r;
|
|
337
466
|
})();
|
|
338
467
|
try {
|
|
339
|
-
await
|
|
468
|
+
await g;
|
|
340
469
|
} finally {
|
|
341
|
-
|
|
470
|
+
g = null;
|
|
342
471
|
}
|
|
343
472
|
}
|
|
344
473
|
},
|
|
345
474
|
async fetchRecommendationFilters() {
|
|
346
475
|
if (!Object.keys(this.filterList).length) {
|
|
347
|
-
if (
|
|
348
|
-
await
|
|
476
|
+
if (h) {
|
|
477
|
+
await h;
|
|
349
478
|
return;
|
|
350
479
|
}
|
|
351
|
-
|
|
352
|
-
const t = await
|
|
480
|
+
h = (async () => {
|
|
481
|
+
const t = await d.fetchRecommendationFilters();
|
|
353
482
|
this.filterList = t;
|
|
354
483
|
})();
|
|
355
484
|
try {
|
|
356
|
-
await
|
|
485
|
+
await h;
|
|
357
486
|
} finally {
|
|
358
|
-
|
|
487
|
+
h = null;
|
|
359
488
|
}
|
|
360
489
|
}
|
|
361
490
|
},
|
|
@@ -370,10 +499,10 @@ const U = () => ({
|
|
|
370
499
|
deleteFilterGroup(t) {
|
|
371
500
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
372
501
|
return;
|
|
373
|
-
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),
|
|
502
|
+
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), s = new Map(n.map((i, o) => [i, o + 1]));
|
|
374
503
|
e.recommendationConfigs.filters = r.map((i) => ({
|
|
375
504
|
...i,
|
|
376
|
-
filterGroup:
|
|
505
|
+
filterGroup: s.get(i.filterGroup) ?? i.filterGroup
|
|
377
506
|
}));
|
|
378
507
|
},
|
|
379
508
|
updateFilter(t) {
|
|
@@ -384,7 +513,7 @@ const U = () => ({
|
|
|
384
513
|
const n = [...e.recommendationConfigs.filters];
|
|
385
514
|
n[r] = {
|
|
386
515
|
...t,
|
|
387
|
-
isValid:
|
|
516
|
+
isValid: V(t)
|
|
388
517
|
}, e.recommendationConfigs.filters = n;
|
|
389
518
|
}
|
|
390
519
|
},
|
|
@@ -398,10 +527,10 @@ const U = () => ({
|
|
|
398
527
|
let i = 1;
|
|
399
528
|
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
400
529
|
} else {
|
|
401
|
-
const i = [...new Set(n.map((
|
|
402
|
-
n = n.map((
|
|
403
|
-
...
|
|
404
|
-
filterGroup: o.get(
|
|
530
|
+
const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
|
|
531
|
+
n = n.map((c) => ({
|
|
532
|
+
...c,
|
|
533
|
+
filterGroup: o.get(c.filterGroup) ?? c.filterGroup
|
|
405
534
|
}));
|
|
406
535
|
}
|
|
407
536
|
e.recommendationConfigs.filters = n;
|
|
@@ -410,19 +539,19 @@ const U = () => ({
|
|
|
410
539
|
addFilter(t) {
|
|
411
540
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
412
541
|
return;
|
|
413
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters],
|
|
542
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
|
|
414
543
|
(o) => o.filterGroup === t.filterGroup
|
|
415
544
|
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
416
545
|
i !== -1 ? r.splice(i + 1, 0, {
|
|
417
546
|
...t,
|
|
418
|
-
filterNumber:
|
|
547
|
+
filterNumber: s
|
|
419
548
|
}) : r.push({
|
|
420
549
|
...t,
|
|
421
|
-
filterNumber:
|
|
550
|
+
filterNumber: s
|
|
422
551
|
}), e.recommendationConfigs.filters = r;
|
|
423
552
|
},
|
|
424
553
|
generateFilterQuery() {
|
|
425
|
-
return
|
|
554
|
+
return G(this.recommendationConfigs.filters);
|
|
426
555
|
},
|
|
427
556
|
/**
|
|
428
557
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -430,55 +559,83 @@ const U = () => ({
|
|
|
430
559
|
* every block's recommendationConfigs across user edits.
|
|
431
560
|
*/
|
|
432
561
|
hasInvalidBlock() {
|
|
433
|
-
return Object.values(this.blockStates).some((t) =>
|
|
562
|
+
return Object.values(this.blockStates).some((t) => !$(t.recommendationConfigs, this));
|
|
434
563
|
},
|
|
435
564
|
// ====================================================================
|
|
436
565
|
// Per-Block Product Fetching
|
|
437
566
|
// ====================================================================
|
|
438
567
|
async fetchRecommendationProducts() {
|
|
439
568
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
440
|
-
if (
|
|
441
|
-
await
|
|
569
|
+
if (S) {
|
|
570
|
+
await S;
|
|
442
571
|
return;
|
|
443
572
|
}
|
|
444
|
-
|
|
573
|
+
S = this._doFetchProducts();
|
|
445
574
|
try {
|
|
446
|
-
await
|
|
575
|
+
await S;
|
|
447
576
|
} finally {
|
|
448
|
-
|
|
577
|
+
S = null;
|
|
449
578
|
}
|
|
450
579
|
}
|
|
451
580
|
},
|
|
452
581
|
async _doFetchProducts() {
|
|
453
|
-
var
|
|
454
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n =
|
|
582
|
+
var f;
|
|
583
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = E();
|
|
584
|
+
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
585
|
+
await this._doFetchStrategyProducts(t);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
const s = r.filters.filter((m) => m.isValid), i = G(s), o = ((f = C().find((m) => m.key === r.strategy)) == null ? void 0 : f.path) || "", c = parseInt(r.size) || 6, a = {
|
|
455
589
|
locale: r.language,
|
|
456
590
|
currency: r.currencySettings.value,
|
|
457
|
-
partnerName:
|
|
591
|
+
partnerName: n.partnerName,
|
|
458
592
|
size: r.size,
|
|
459
593
|
details: !0,
|
|
460
|
-
campaignId:
|
|
594
|
+
campaignId: n.variationId
|
|
461
595
|
};
|
|
462
|
-
r.strategy === "manualMerchandising" ? a.productId =
|
|
596
|
+
r.strategy === "manualMerchandising" ? a.productId = z(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
463
597
|
a,
|
|
464
|
-
|
|
598
|
+
O(n.partnerName, r.strategy)
|
|
465
599
|
);
|
|
466
|
-
let
|
|
600
|
+
let l;
|
|
467
601
|
try {
|
|
468
|
-
|
|
602
|
+
l = await d.fetchRecommendationProducts(o, a);
|
|
469
603
|
} catch {
|
|
470
|
-
|
|
604
|
+
l = [];
|
|
471
605
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
606
|
+
this._setBlockProducts(t, l, c);
|
|
607
|
+
},
|
|
608
|
+
async _doFetchStrategyProducts(t) {
|
|
609
|
+
const e = (b.get(t) ?? 0) + 1;
|
|
610
|
+
b.set(t, e);
|
|
611
|
+
const { recommendationConfigs: r } = this.blockStates[t];
|
|
612
|
+
let n = [], s = parseInt(r.size) || 6;
|
|
613
|
+
try {
|
|
614
|
+
await this.fetchStrategies();
|
|
615
|
+
const i = this.strategies.find(
|
|
616
|
+
(o) => String(o.strategy_id) === r.strategyId
|
|
617
|
+
);
|
|
618
|
+
if (i) {
|
|
619
|
+
s = parseInt(String(i.size ?? "")) || s;
|
|
620
|
+
const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), f = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((k) => k && !k.startsWith("user_id=")), R = m.length ? `${f}?${m.join("&")}` : f;
|
|
621
|
+
R && (n = await d.fetchRecommendationProductsByUrl(R));
|
|
622
|
+
}
|
|
623
|
+
} catch {
|
|
624
|
+
n = [];
|
|
478
625
|
}
|
|
626
|
+
b.get(t) === e && this._setBlockProducts(t, n, s);
|
|
627
|
+
},
|
|
628
|
+
_setBlockProducts(t, e, r) {
|
|
629
|
+
if (!this.blockStates[t])
|
|
630
|
+
return;
|
|
631
|
+
const n = e.length > 0 ? e : v(r);
|
|
632
|
+
this.blockStates[t].recommendationProducts = [
|
|
633
|
+
...n.slice(0, r),
|
|
634
|
+
...v(Math.max(0, r - n.length))
|
|
635
|
+
];
|
|
479
636
|
}
|
|
480
637
|
}
|
|
481
638
|
});
|
|
482
639
|
export {
|
|
483
|
-
|
|
640
|
+
st as useRecommendationExtensionStore
|
|
484
641
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ATTR_PRODUCT_PRICE as f, ATTR_PRODUCT_OLD_PRICE as O } from "../../constants/selectors.js";
|
|
2
2
|
import { DEFAULT_PRODUCTS_PER_ROW as w } from "../../constants/layout.js";
|
|
3
|
-
import {
|
|
3
|
+
import { createBlockTemplate as A, getDefaultProducts as g, DEFAULTS as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
|
|
4
4
|
import { DEFAULT_CELL_PADDING as k, renderInlineGridPriceCell as H, buildFillerCell as x, gridElementRenderer as y } from "./elementRenderer.js";
|
|
5
5
|
const G = `
|
|
6
6
|
<tr class="recommendation-product-row">
|
|
@@ -69,8 +69,8 @@ function M(t, r, o, e = {}, c = {}) {
|
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
function Q(t) {
|
|
72
|
-
const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o =
|
|
73
|
-
return o.replace("{-{-TITLE-}-}",
|
|
72
|
+
const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = A("grid", r), e = g(), c = M(e, w);
|
|
73
|
+
return o.replace("{-{-TITLE-}-}", U.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
|
|
74
74
|
}
|
|
75
75
|
export {
|
|
76
76
|
Q as getDefaultTemplate,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { RecommendationBlockId as r } from "../constants/blockIds.js";
|
|
2
|
+
import { DEFAULT_ROW_SPACING as l } from "../constants/layout.js";
|
|
3
|
+
import { CSS_CLASS_ATTRIBUTE_ROW as d, ATTR_RECOMMENDATION_TITLE as n, ATTR_DATA_VISIBILITY as A, CSS_CLASS_TITLE_CELL as _, CSS_CLASS_SPACER as c } from "../constants/selectors.js";
|
|
4
|
+
const a = "You May Also Like!", i = '<p style="font-size: 28px; color: #333333;"><strong>{-{-TITLE-}-}</strong></p>';
|
|
5
|
+
function E(s = i, t = !0, T = l) {
|
|
6
|
+
const e = `class="${d}" data-attribute-type="${n}" ${A}="${t ? "1" : "0"}"`, o = t ? "" : ' style="display: none;"';
|
|
7
|
+
return `
|
|
8
|
+
<tr ${e}${o}>
|
|
9
|
+
<td>
|
|
10
|
+
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
|
11
|
+
<tbody>
|
|
12
|
+
<tr>
|
|
13
|
+
<td
|
|
14
|
+
class="esd-block-text ${_} es-p10t es-p10b es-p20l es-p20r"
|
|
15
|
+
align="center"
|
|
16
|
+
esd-extension-block-id="${r.TITLE}">
|
|
17
|
+
${s}
|
|
18
|
+
</td>
|
|
19
|
+
</tr>
|
|
20
|
+
</tbody>
|
|
21
|
+
</table>
|
|
22
|
+
</td>
|
|
23
|
+
</tr>
|
|
24
|
+
<tr ${e}${o}>
|
|
25
|
+
<td class="${c}" style="height: ${T}px;"></td>
|
|
26
|
+
</tr>
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
i as DEFAULT_TITLE_PARAGRAPH,
|
|
31
|
+
a as DEFAULT_TITLE_TEXT,
|
|
32
|
+
E as buildTitleRows
|
|
33
|
+
};
|