@useinsider/guido 3.17.0-beta.6255bfc → 3.17.0-beta.77567eb
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 +5 -6
- package/dist/@types/config/schemas.js +6 -12
- package/dist/components/Guido.vue.js +2 -2
- package/dist/components/Guido.vue2.js +30 -31
- package/dist/composables/useCustomInterfaceAppearance.js +38 -52
- package/dist/composables/useRecommendation.js +44 -52
- package/dist/config/migrator/recommendation/settingsMapper.js +17 -19
- package/dist/config/migrator/recommendationMigrator.js +4 -6
- package/dist/enums/academy.js +1 -2
- package/dist/enums/date.js +3 -4
- package/dist/enums/extensions/recommendationBlock.js +1 -4
- package/dist/extensions/Blocks/Recommendation/block.js +21 -26
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +34 -36
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +95 -96
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +166 -180
- package/dist/extensions/Blocks/Recommendation/services/configService.js +35 -35
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +110 -251
- package/dist/extensions/Blocks/common-control.js +19 -22
- package/dist/guido.css +1 -1
- package/dist/package.json.js +1 -1
- package/dist/services/recommendationApi.js +30 -75
- package/dist/src/@types/config/schemas.d.ts +0 -12
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useConfig.d.ts +0 -2
- package/dist/src/composables/useRecommendation.d.ts +0 -1
- package/dist/src/enums/academy.d.ts +0 -1
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +6 -7
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -15
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +10 -206
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -6
- package/dist/src/extensions/Blocks/common-control.d.ts +1 -4
- package/dist/src/services/recommendationApi.d.ts +1 -4
- package/dist/src/stores/config.d.ts +0 -18
- package/dist/utils/dateUtil.js +10 -29
- package/dist/utils/templatePreparation.js +34 -37
- package/package.json +3 -4
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +0 -18
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +0 -66
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -142
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +0 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -30
- package/dist/src/mock/api/recommendation-strategies.d.ts +0 -63
- package/dist/src/utils/strategyInfoBox.d.ts +0 -22
- package/dist/static/assets/icons/line-change.svg.js +0 -5
- package/dist/static/assets/icons/line-delete.svg.js +0 -5
- package/dist/static/assets/icons/line-plus.svg.js +0 -5
- package/dist/static/styles/components/recommendation-strategy.css.js +0 -188
- package/dist/utils/strategyInfoBox.js +0 -37
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { defineStore as F } from "pinia";
|
|
1
|
+
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
6
5
|
import "../constants/selectors.js";
|
|
7
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
8
|
-
import {
|
|
9
|
-
import { getDefaultProducts as
|
|
10
|
-
import { generateCompleteFilterQuery as
|
|
11
|
-
import { getPartnerRecommendationParams as
|
|
12
|
-
import { sanitizeProductIds as
|
|
13
|
-
import { isFilterValid as
|
|
14
|
-
import { isConfigValid as
|
|
15
|
-
const
|
|
16
|
-
let
|
|
17
|
-
function
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as F, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
|
|
7
|
+
import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
|
|
8
|
+
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
9
|
+
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
10
|
+
import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
|
|
11
|
+
import { sanitizeProductIds as N } from "../utils/productIds.js";
|
|
12
|
+
import { isFilterValid as x } from "../validation/filterSchema.js";
|
|
13
|
+
import { isConfigValid as L } from "../validation/requiredFields.js";
|
|
14
|
+
const h = y();
|
|
15
|
+
let m = null, u = null, d = null;
|
|
16
|
+
function k() {
|
|
18
17
|
return {
|
|
19
|
-
cardsInRow:
|
|
18
|
+
cardsInRow: D,
|
|
20
19
|
currencySettings: {
|
|
21
20
|
name: "USD",
|
|
22
21
|
value: "USD",
|
|
@@ -30,14 +29,13 @@ function R() {
|
|
|
30
29
|
productIds: [],
|
|
31
30
|
id: 1,
|
|
32
31
|
language: "en_US",
|
|
33
|
-
mobileCardsInRow:
|
|
32
|
+
mobileCardsInRow: F,
|
|
34
33
|
mobileLayoutEnabled: !1,
|
|
35
34
|
orientation: "grid",
|
|
36
35
|
recommendedProducts: [],
|
|
37
36
|
sendProductRequestFlag: !1,
|
|
38
37
|
shuffleProducts: !1,
|
|
39
38
|
strategy: "mostPopular",
|
|
40
|
-
strategyId: "",
|
|
41
39
|
textTrimming: !0,
|
|
42
40
|
unresponsive: !1,
|
|
43
41
|
size: "6",
|
|
@@ -46,32 +44,28 @@ function R() {
|
|
|
46
44
|
priceHideIfSameAsDiscounted: !1
|
|
47
45
|
};
|
|
48
46
|
}
|
|
49
|
-
function
|
|
47
|
+
function I() {
|
|
50
48
|
return {
|
|
51
|
-
recommendationConfigs:
|
|
49
|
+
recommendationConfigs: k(),
|
|
52
50
|
recommendationProducts: [],
|
|
53
51
|
filterStatus: !1,
|
|
54
52
|
filterSelectionDrawerStatus: !1,
|
|
55
|
-
assignStrategyDrawerStatus: !1,
|
|
56
53
|
filterGroup: 1,
|
|
57
54
|
isInitialized: !1,
|
|
58
55
|
filterSnapshot: null
|
|
59
56
|
};
|
|
60
57
|
}
|
|
61
|
-
const
|
|
58
|
+
const U = () => ({
|
|
62
59
|
recommendationCampaignUrls: {},
|
|
63
60
|
activePredictiveAlgorithms: [],
|
|
64
61
|
languages: {},
|
|
65
62
|
currencyList: [],
|
|
66
63
|
filterList: {},
|
|
67
|
-
strategies: [],
|
|
68
|
-
strategiesLoading: !1,
|
|
69
|
-
strategyUrlTemplates: {},
|
|
70
64
|
blockStates: {},
|
|
71
65
|
currentRecommendationId: null,
|
|
72
66
|
configVersion: 0
|
|
73
|
-
}),
|
|
74
|
-
state: () =>
|
|
67
|
+
}), H = P("guidoRecommendationExtension", {
|
|
68
|
+
state: () => U(),
|
|
75
69
|
getters: {
|
|
76
70
|
// ====================================================================
|
|
77
71
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -81,7 +75,7 @@ const z = () => ({
|
|
|
81
75
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
82
76
|
*/
|
|
83
77
|
recommendationConfigs(t) {
|
|
84
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
78
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
|
|
85
79
|
},
|
|
86
80
|
/**
|
|
87
81
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -95,20 +89,6 @@ const z = () => ({
|
|
|
95
89
|
filterSelectionDrawerStatus(t) {
|
|
96
90
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
97
91
|
},
|
|
98
|
-
/**
|
|
99
|
-
* Proxy getter: delegates to blockStates[currentRecommendationId].assignStrategyDrawerStatus
|
|
100
|
-
*/
|
|
101
|
-
assignStrategyDrawerStatus(t) {
|
|
102
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
|
|
103
|
-
},
|
|
104
|
-
/**
|
|
105
|
-
* The current block's assigned strategy record from the listing,
|
|
106
|
-
* or null when nothing is assigned / the strategy is no longer listed.
|
|
107
|
-
*/
|
|
108
|
-
assignedStrategy(t) {
|
|
109
|
-
const { strategyId: e } = this.recommendationConfigs;
|
|
110
|
-
return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
|
|
111
|
-
},
|
|
112
92
|
/**
|
|
113
93
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
114
94
|
*/
|
|
@@ -140,12 +120,12 @@ const z = () => ({
|
|
|
140
120
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
141
121
|
},
|
|
142
122
|
getActivePredictiveAlgorithms: (t) => {
|
|
143
|
-
const e =
|
|
144
|
-
return t.activePredictiveAlgorithms.filter((
|
|
145
|
-
r.push(...e.filter((
|
|
146
|
-
}), r.map((
|
|
147
|
-
text:
|
|
148
|
-
value:
|
|
123
|
+
const e = g(), r = [];
|
|
124
|
+
return t.activePredictiveAlgorithms.filter((n) => !w.includes(n)).forEach((n) => {
|
|
125
|
+
r.push(...e.filter((c) => c.id === n));
|
|
126
|
+
}), r.map((n) => ({
|
|
127
|
+
text: n.name,
|
|
128
|
+
value: n.key
|
|
149
129
|
}));
|
|
150
130
|
},
|
|
151
131
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
@@ -159,7 +139,7 @@ const z = () => ({
|
|
|
159
139
|
getFilterList() {
|
|
160
140
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
161
141
|
let e;
|
|
162
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
142
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
163
143
|
text: t.displayName,
|
|
164
144
|
value: e,
|
|
165
145
|
type: t.attributeType
|
|
@@ -181,7 +161,7 @@ const z = () => ({
|
|
|
181
161
|
setCurrentBlock(t) {
|
|
182
162
|
this.blockStates[t] || (this.blockStates = {
|
|
183
163
|
...this.blockStates,
|
|
184
|
-
[t]:
|
|
164
|
+
[t]: I()
|
|
185
165
|
}), this.currentRecommendationId = t;
|
|
186
166
|
},
|
|
187
167
|
/**
|
|
@@ -191,13 +171,13 @@ const z = () => ({
|
|
|
191
171
|
removeBlockState(t) {
|
|
192
172
|
const e = t.toString();
|
|
193
173
|
if (this.recommendationCampaignUrls[e]) {
|
|
194
|
-
const
|
|
195
|
-
delete
|
|
174
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
175
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
196
176
|
}
|
|
197
177
|
const r = { ...this.blockStates };
|
|
198
178
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
199
|
-
const
|
|
200
|
-
this.currentRecommendationId =
|
|
179
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
180
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
201
181
|
}
|
|
202
182
|
},
|
|
203
183
|
/**
|
|
@@ -213,10 +193,10 @@ const z = () => ({
|
|
|
213
193
|
[e]: o
|
|
214
194
|
};
|
|
215
195
|
}
|
|
216
|
-
const
|
|
217
|
-
|
|
196
|
+
const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
|
|
197
|
+
i && (this.recommendationCampaignUrls = {
|
|
218
198
|
...this.recommendationCampaignUrls,
|
|
219
|
-
[
|
|
199
|
+
[c]: i
|
|
220
200
|
});
|
|
221
201
|
},
|
|
222
202
|
/**
|
|
@@ -241,7 +221,7 @@ const z = () => ({
|
|
|
241
221
|
* `isInitialized`) alone.
|
|
242
222
|
*/
|
|
243
223
|
seedBlockUrlConfig(t, e) {
|
|
244
|
-
const r = (o,
|
|
224
|
+
const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
|
|
245
225
|
name: e.currencyCode,
|
|
246
226
|
value: e.currencyCode,
|
|
247
227
|
symbol: e.currencyCode,
|
|
@@ -249,20 +229,19 @@ const z = () => ({
|
|
|
249
229
|
decimalCount: String(e.currencyDecimalCount),
|
|
250
230
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
251
231
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
252
|
-
},
|
|
253
|
-
|
|
254
|
-
...
|
|
232
|
+
}, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
|
|
233
|
+
i.recommendationConfigs = {
|
|
234
|
+
...i.recommendationConfigs,
|
|
255
235
|
strategy: e.strategy,
|
|
256
|
-
strategyId: e.strategyId,
|
|
257
236
|
language: e.language,
|
|
258
237
|
size: e.size,
|
|
259
238
|
productIds: e.productIds,
|
|
260
239
|
filters: e.filters,
|
|
261
240
|
shuffleProducts: e.shuffleProducts,
|
|
262
|
-
currencySettings:
|
|
263
|
-
},
|
|
241
|
+
currencySettings: n
|
|
242
|
+
}, c && (this.blockStates = {
|
|
264
243
|
...this.blockStates,
|
|
265
|
-
[t]:
|
|
244
|
+
[t]: i
|
|
266
245
|
});
|
|
267
246
|
},
|
|
268
247
|
/**
|
|
@@ -281,18 +260,18 @@ const z = () => ({
|
|
|
281
260
|
...t.currencySettings || {}
|
|
282
261
|
}
|
|
283
262
|
};
|
|
284
|
-
const { triggerRefetch:
|
|
285
|
-
|
|
263
|
+
const { triggerRefetch: n = !0 } = e;
|
|
264
|
+
n && this.configVersion++;
|
|
286
265
|
},
|
|
287
266
|
/**
|
|
288
267
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
289
268
|
*/
|
|
290
269
|
createDefaultFilter(t, e) {
|
|
291
|
-
const [r] = this.getFilterList, [
|
|
270
|
+
const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
|
|
292
271
|
return {
|
|
293
272
|
type: "standardFilter",
|
|
294
273
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
295
|
-
operator: (
|
|
274
|
+
operator: (n == null ? void 0 : n.value) ?? "",
|
|
296
275
|
innerGroupOperator: "*",
|
|
297
276
|
outerGroupOperator: "*",
|
|
298
277
|
filterNumber: e,
|
|
@@ -336,129 +315,47 @@ const z = () => ({
|
|
|
336
315
|
t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
|
|
337
316
|
},
|
|
338
317
|
// ====================================================================
|
|
339
|
-
// Reusable Recommendation Strategy (SD-149105)
|
|
340
|
-
// ====================================================================
|
|
341
|
-
/**
|
|
342
|
-
* Opens the Assign Strategy drawer for the current block.
|
|
343
|
-
* Selection state lives in the drawer component until Assign is
|
|
344
|
-
* pressed, so closing without assigning needs no snapshot/revert.
|
|
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
|
-
/**
|
|
353
|
-
* Fetches the active + EMAIL strategy listing. Always fetches fresh
|
|
354
|
-
* (dead-strategy detection and post-create refresh need freshness);
|
|
355
|
-
* only concurrent in-flight calls share one request.
|
|
356
|
-
*/
|
|
357
|
-
async fetchStrategies() {
|
|
358
|
-
if (S) {
|
|
359
|
-
await S;
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
S = (async () => {
|
|
363
|
-
this.strategiesLoading = !0;
|
|
364
|
-
try {
|
|
365
|
-
this.strategies = await d.fetchRecommendationStrategies();
|
|
366
|
-
} finally {
|
|
367
|
-
this.strategiesLoading = !1;
|
|
368
|
-
}
|
|
369
|
-
})();
|
|
370
|
-
try {
|
|
371
|
-
await S;
|
|
372
|
-
} finally {
|
|
373
|
-
S = null;
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
/**
|
|
377
|
-
* Resolves a strategy's recommendation endpoint template via
|
|
378
|
-
* endpoint-generate, cached per strategy id + revision + currency.
|
|
379
|
-
* Failures throw and are NOT cached, so the next attempt retries.
|
|
380
|
-
*
|
|
381
|
-
* `full_path` bakes in the algorithm path and `size=` as they were when
|
|
382
|
-
* generated, so the revision keys the cache — and a record with no
|
|
383
|
-
* revision is not cached at all, since its key could never change.
|
|
384
|
-
* Currency joins the key because it is sent in the request body, so two
|
|
385
|
-
* currencies can resolve to different paths for the same revision.
|
|
386
|
-
*/
|
|
387
|
-
async resolveStrategyUrlTemplate(t, e) {
|
|
388
|
-
const r = typeof t.updated_at == "string" ? t.updated_at : "", i = r ? `${t.strategy_id}:${r}:${e}` : "", s = i ? this.strategyUrlTemplates[i] : void 0;
|
|
389
|
-
if (s)
|
|
390
|
-
return s;
|
|
391
|
-
const { full_path: n } = await d.generateStrategyEndpoint(t, e);
|
|
392
|
-
return i && (this.strategyUrlTemplates = {
|
|
393
|
-
...this.strategyUrlTemplates,
|
|
394
|
-
[i]: n
|
|
395
|
-
}), n;
|
|
396
|
-
},
|
|
397
|
-
/**
|
|
398
|
-
* Assigns a strategy to the current block. The config write is
|
|
399
|
-
* synchronous (before any await) so a block switch cannot misdirect
|
|
400
|
-
* it; the configVersion bump persists it to node config and triggers
|
|
401
|
-
* the product refetch via the coordinator control's subscription.
|
|
402
|
-
*/
|
|
403
|
-
assignStrategy(t) {
|
|
404
|
-
this.patchCurrentBlockConfig({
|
|
405
|
-
strategyId: String(t.strategy_id),
|
|
406
|
-
...t.size !== void 0 ? { size: String(t.size) } : {}
|
|
407
|
-
});
|
|
408
|
-
},
|
|
409
|
-
/**
|
|
410
|
-
* Clears the current block's strategy; it falls back to the per-block
|
|
411
|
-
* algorithm settings.
|
|
412
|
-
*
|
|
413
|
-
* `size` goes back to the default rather than staying on the removed
|
|
414
|
-
* strategy's count: with Number of Products hidden in RRS mode, a block
|
|
415
|
-
* left on that count would have no UI to correct it.
|
|
416
|
-
*/
|
|
417
|
-
removeStrategy() {
|
|
418
|
-
this.patchCurrentBlockConfig({ strategyId: "", size: U.size });
|
|
419
|
-
},
|
|
420
|
-
// ====================================================================
|
|
421
318
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
422
319
|
// ====================================================================
|
|
423
320
|
async fetchRecommendationCreateData() {
|
|
424
321
|
if (!this.activePredictiveAlgorithms.length) {
|
|
425
|
-
if (
|
|
426
|
-
await
|
|
322
|
+
if (m) {
|
|
323
|
+
await m;
|
|
427
324
|
return;
|
|
428
325
|
}
|
|
429
|
-
|
|
326
|
+
m = (async () => {
|
|
430
327
|
const {
|
|
431
328
|
activePredictiveAlgorithms: t,
|
|
432
329
|
languages: e,
|
|
433
330
|
currencies: r
|
|
434
|
-
} = await
|
|
331
|
+
} = await h.fetchRecommendationCreateData();
|
|
435
332
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
436
|
-
const
|
|
437
|
-
|
|
333
|
+
const n = this.blockStates[this.currentRecommendationId];
|
|
334
|
+
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
438
335
|
}
|
|
439
336
|
this.currencyList = r;
|
|
440
337
|
})();
|
|
441
338
|
try {
|
|
442
|
-
await
|
|
339
|
+
await m;
|
|
443
340
|
} finally {
|
|
444
|
-
|
|
341
|
+
m = null;
|
|
445
342
|
}
|
|
446
343
|
}
|
|
447
344
|
},
|
|
448
345
|
async fetchRecommendationFilters() {
|
|
449
346
|
if (!Object.keys(this.filterList).length) {
|
|
450
|
-
if (
|
|
451
|
-
await
|
|
347
|
+
if (u) {
|
|
348
|
+
await u;
|
|
452
349
|
return;
|
|
453
350
|
}
|
|
454
|
-
|
|
455
|
-
const t = await
|
|
351
|
+
u = (async () => {
|
|
352
|
+
const t = await h.fetchRecommendationFilters();
|
|
456
353
|
this.filterList = t;
|
|
457
354
|
})();
|
|
458
355
|
try {
|
|
459
|
-
await
|
|
356
|
+
await u;
|
|
460
357
|
} finally {
|
|
461
|
-
|
|
358
|
+
u = null;
|
|
462
359
|
}
|
|
463
360
|
}
|
|
464
361
|
},
|
|
@@ -473,59 +370,59 @@ const z = () => ({
|
|
|
473
370
|
deleteFilterGroup(t) {
|
|
474
371
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
475
372
|
return;
|
|
476
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
477
|
-
e.recommendationConfigs.filters = r.map((
|
|
478
|
-
...
|
|
479
|
-
filterGroup:
|
|
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), c = new Map(n.map((i, o) => [i, o + 1]));
|
|
374
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
375
|
+
...i,
|
|
376
|
+
filterGroup: c.get(i.filterGroup) ?? i.filterGroup
|
|
480
377
|
}));
|
|
481
378
|
},
|
|
482
379
|
updateFilter(t) {
|
|
483
380
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
484
381
|
return;
|
|
485
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
382
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
486
383
|
if (r !== -1) {
|
|
487
|
-
const
|
|
488
|
-
|
|
384
|
+
const n = [...e.recommendationConfigs.filters];
|
|
385
|
+
n[r] = {
|
|
489
386
|
...t,
|
|
490
|
-
isValid:
|
|
491
|
-
}, e.recommendationConfigs.filters =
|
|
387
|
+
isValid: x(t)
|
|
388
|
+
}, e.recommendationConfigs.filters = n;
|
|
492
389
|
}
|
|
493
390
|
},
|
|
494
391
|
deleteFilter(t) {
|
|
495
392
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
496
393
|
return;
|
|
497
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
394
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
498
395
|
if (r !== -1) {
|
|
499
|
-
let
|
|
500
|
-
if (
|
|
501
|
-
let
|
|
502
|
-
|
|
396
|
+
let n = [...e.recommendationConfigs.filters];
|
|
397
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
398
|
+
let i = 1;
|
|
399
|
+
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
503
400
|
} else {
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
...
|
|
507
|
-
filterGroup: o.get(
|
|
401
|
+
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
|
|
402
|
+
n = n.map((s) => ({
|
|
403
|
+
...s,
|
|
404
|
+
filterGroup: o.get(s.filterGroup) ?? s.filterGroup
|
|
508
405
|
}));
|
|
509
406
|
}
|
|
510
|
-
e.recommendationConfigs.filters =
|
|
407
|
+
e.recommendationConfigs.filters = n;
|
|
511
408
|
}
|
|
512
409
|
},
|
|
513
410
|
addFilter(t) {
|
|
514
411
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
515
412
|
return;
|
|
516
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters],
|
|
413
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
|
|
517
414
|
(o) => o.filterGroup === t.filterGroup
|
|
518
|
-
).length + 1,
|
|
519
|
-
|
|
415
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
416
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
520
417
|
...t,
|
|
521
|
-
filterNumber:
|
|
418
|
+
filterNumber: c
|
|
522
419
|
}) : r.push({
|
|
523
420
|
...t,
|
|
524
|
-
filterNumber:
|
|
421
|
+
filterNumber: c
|
|
525
422
|
}), e.recommendationConfigs.filters = r;
|
|
526
423
|
},
|
|
527
424
|
generateFilterQuery() {
|
|
528
|
-
return
|
|
425
|
+
return b(this.recommendationConfigs.filters);
|
|
529
426
|
},
|
|
530
427
|
/**
|
|
531
428
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -533,93 +430,55 @@ const z = () => ({
|
|
|
533
430
|
* every block's recommendationConfigs across user edits.
|
|
534
431
|
*/
|
|
535
432
|
hasInvalidBlock() {
|
|
536
|
-
return Object.values(this.blockStates).some((t) => !
|
|
433
|
+
return Object.values(this.blockStates).some((t) => !L(t.recommendationConfigs, this));
|
|
537
434
|
},
|
|
538
435
|
// ====================================================================
|
|
539
436
|
// Per-Block Product Fetching
|
|
540
437
|
// ====================================================================
|
|
541
438
|
async fetchRecommendationProducts() {
|
|
542
439
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
543
|
-
if (
|
|
544
|
-
await
|
|
440
|
+
if (d) {
|
|
441
|
+
await d;
|
|
545
442
|
return;
|
|
546
443
|
}
|
|
547
|
-
|
|
444
|
+
d = this._doFetchProducts();
|
|
548
445
|
try {
|
|
549
|
-
await
|
|
446
|
+
await d;
|
|
550
447
|
} finally {
|
|
551
|
-
|
|
448
|
+
d = null;
|
|
552
449
|
}
|
|
553
450
|
}
|
|
554
451
|
},
|
|
555
452
|
async _doFetchProducts() {
|
|
556
453
|
var p;
|
|
557
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
558
|
-
if (s("reusableRecommendationStrategy") && r.strategyId) {
|
|
559
|
-
await this._doFetchStrategyProducts(t);
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
const n = r.filters.filter((u) => u.isValid), o = I(n), a = ((p = y().find((u) => u.key === r.strategy)) == null ? void 0 : p.path) || "", c = parseInt(r.size) || 6, l = {
|
|
454
|
+
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 = {
|
|
563
455
|
locale: r.language,
|
|
564
456
|
currency: r.currencySettings.value,
|
|
565
|
-
partnerName:
|
|
457
|
+
partnerName: o.partnerName,
|
|
566
458
|
size: r.size,
|
|
567
459
|
details: !0,
|
|
568
|
-
campaignId:
|
|
460
|
+
campaignId: o.variationId
|
|
569
461
|
};
|
|
570
|
-
r.strategy === "manualMerchandising" ?
|
|
571
|
-
|
|
572
|
-
|
|
462
|
+
r.strategy === "manualMerchandising" ? a.productId = N(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
463
|
+
a,
|
|
464
|
+
v(o.partnerName, r.strategy)
|
|
573
465
|
);
|
|
574
|
-
let
|
|
466
|
+
let f;
|
|
575
467
|
try {
|
|
576
|
-
|
|
468
|
+
f = await h.fetchRecommendationProducts(i, a);
|
|
577
469
|
} catch {
|
|
578
|
-
|
|
470
|
+
f = [];
|
|
579
471
|
}
|
|
580
|
-
this.
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
* strategy, resolution error) falls back to placeholder products.
|
|
587
|
-
*/
|
|
588
|
-
async _doFetchStrategyProducts(t) {
|
|
589
|
-
const { recommendationConfigs: e } = this.blockStates[t];
|
|
590
|
-
let r = [], i = parseInt(e.size) || 6;
|
|
591
|
-
try {
|
|
592
|
-
this.strategies.length || await this.fetchStrategies();
|
|
593
|
-
const s = this.strategies.find(
|
|
594
|
-
(n) => String(n.strategy_id) === e.strategyId
|
|
595
|
-
);
|
|
596
|
-
if (s) {
|
|
597
|
-
i = parseInt(String(s.size ?? "")) || i;
|
|
598
|
-
const n = e.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(s, n)).replaceAll("{locale}", e.language).replaceAll("{currency}", n), c = a.indexOf("?"), l = c === -1 ? a : a.slice(0, c), m = (c === -1 ? "" : a.slice(c + 1)).split("&").filter((u) => u && !u.startsWith("user_id=")), p = m.length ? `${l}?${m.join("&")}` : l;
|
|
599
|
-
r = await d.fetchRecommendationProductsByUrl(p);
|
|
600
|
-
}
|
|
601
|
-
} catch {
|
|
602
|
-
r = [];
|
|
472
|
+
if (this.blockStates[t]) {
|
|
473
|
+
const l = f.length > 0 ? f : S(s);
|
|
474
|
+
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
475
|
+
...l,
|
|
476
|
+
...S(s - l.length)
|
|
477
|
+
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
603
478
|
}
|
|
604
|
-
this._setBlockProducts(t, r, i);
|
|
605
|
-
},
|
|
606
|
-
/**
|
|
607
|
-
* Writes products to a block's state, padded/clipped to exactly `size`:
|
|
608
|
-
* in-place content updates compare the DOM element count against
|
|
609
|
-
* products.length, and a longer list makes the renderer extend its slot
|
|
610
|
-
* grid, which resets migrator-applied styles.
|
|
611
|
-
*/
|
|
612
|
-
_setBlockProducts(t, e, r) {
|
|
613
|
-
if (!this.blockStates[t])
|
|
614
|
-
return;
|
|
615
|
-
const i = e.length > 0 ? e : b(r);
|
|
616
|
-
this.blockStates[t].recommendationProducts = [
|
|
617
|
-
...i.slice(0, r),
|
|
618
|
-
...b(Math.max(0, r - i.length))
|
|
619
|
-
];
|
|
620
479
|
}
|
|
621
480
|
}
|
|
622
481
|
});
|
|
623
482
|
export {
|
|
624
|
-
|
|
483
|
+
H as useRecommendationExtensionStore
|
|
625
484
|
};
|