@useinsider/guido 3.18.2-beta.dfce34a → 3.18.2-beta.ec1fd57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Guido.vue.js +3 -3
- package/dist/components/Guido.vue2.js +30 -30
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +11 -13
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +52 -76
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +37 -23
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
- package/dist/composables/useCustomInterfaceAppearance.js +46 -56
- package/dist/composables/useHtmlValidator.js +82 -87
- package/dist/composables/useRecommendation.js +35 -40
- package/dist/composables/useStripo.js +30 -30
- package/dist/config/migrator/itemsBlockMigrator.js +257 -167
- package/dist/enums/extensions/recommendationBlock.js +31 -38
- package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
- package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
- package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
- package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
- package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
- package/dist/extensions/Blocks/Items/template.js +219 -204
- package/dist/extensions/Blocks/Recommendation/block.js +42 -61
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +35 -40
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -84
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +140 -254
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +16 -26
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
- package/dist/guido.css +1 -1
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
- package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
- package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
- package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -9
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +2 -7
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -86
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
- package/dist/src/stores/onboarding.d.ts +0 -377
- package/dist/static/styles/components/recommendation-strategy.css.js +4 -34
- package/dist/stores/onboarding.js +36 -41
- package/dist/utils/pairProductVariables.js +71 -71
- package/dist/utils/templatePreparation.js +55 -55
- package/package.json +1 -1
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +0 -21
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +0 -47
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +0 -24
- package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -14
- package/dist/static/styles/components/skeleton.css.js +0 -23
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { getRecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import { defineStore as
|
|
1
|
+
import { getRecommendationFeedSourceMaps as b, getOperatorOptions as G, PriceAttributes as v } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as D } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as F } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
5
5
|
import "../constants/selectors.js";
|
|
6
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
7
|
-
import { DEFAULT_NODE_CONFIG as
|
|
8
|
-
import { getDefaultProducts as
|
|
9
|
-
import { generateCompleteFilterQuery as
|
|
10
|
-
import { getPartnerRecommendationParams as
|
|
11
|
-
import { sanitizeProductIds as
|
|
12
|
-
import { isFilterValid as
|
|
13
|
-
import {
|
|
14
|
-
const
|
|
15
|
-
let
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
function G() {
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
|
|
7
|
+
import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
|
|
8
|
+
import { getDefaultProducts as R } from "../templates/utils.js";
|
|
9
|
+
import { generateCompleteFilterQuery as k } from "../utils/filterUtil.js";
|
|
10
|
+
import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
|
|
11
|
+
import { sanitizeProductIds as A } from "../utils/productIds.js";
|
|
12
|
+
import { isFilterValid as B } from "../validation/filterSchema.js";
|
|
13
|
+
import { isConfigValid as M } from "../validation/requiredFields.js";
|
|
14
|
+
const u = D();
|
|
15
|
+
let f = null, g = null, h = null, S = null;
|
|
16
|
+
const p = /* @__PURE__ */ new Map();
|
|
17
|
+
function w() {
|
|
19
18
|
return {
|
|
20
|
-
cardsInRow:
|
|
19
|
+
cardsInRow: U,
|
|
21
20
|
currencySettings: {
|
|
22
21
|
name: "USD",
|
|
23
22
|
value: "USD",
|
|
@@ -31,17 +30,13 @@ function G() {
|
|
|
31
30
|
productIds: [],
|
|
32
31
|
id: 1,
|
|
33
32
|
language: "en_US",
|
|
34
|
-
mobileCardsInRow:
|
|
33
|
+
mobileCardsInRow: _,
|
|
35
34
|
mobileLayoutEnabled: !1,
|
|
36
35
|
orientation: "grid",
|
|
37
36
|
recommendedProducts: [],
|
|
38
37
|
sendProductRequestFlag: !1,
|
|
39
38
|
shuffleProducts: !1,
|
|
40
|
-
|
|
41
|
-
// that default is what reached buildCampaignUrl and baked a most-popular feed URL
|
|
42
|
-
// for a block the user never configured (SD-149916). Legacy blocks still get their real
|
|
43
|
-
// algorithm from the node-config sync or the save-time seed.
|
|
44
|
-
strategy: k().isFeatureEnabled("reusableRecommendationStrategy") ? "" : "mostPopular",
|
|
39
|
+
strategy: "mostPopular",
|
|
45
40
|
strategyId: "",
|
|
46
41
|
textTrimming: !0,
|
|
47
42
|
unresponsive: !1,
|
|
@@ -51,9 +46,9 @@ function G() {
|
|
|
51
46
|
priceHideIfSameAsDiscounted: !1
|
|
52
47
|
};
|
|
53
48
|
}
|
|
54
|
-
function
|
|
49
|
+
function C() {
|
|
55
50
|
return {
|
|
56
|
-
recommendationConfigs:
|
|
51
|
+
recommendationConfigs: w(),
|
|
57
52
|
recommendationProducts: [],
|
|
58
53
|
filterStatus: !1,
|
|
59
54
|
filterSelectionDrawerStatus: !1,
|
|
@@ -65,7 +60,7 @@ function P() {
|
|
|
65
60
|
syncedConfigFingerprint: null
|
|
66
61
|
};
|
|
67
62
|
}
|
|
68
|
-
const
|
|
63
|
+
const z = () => ({
|
|
69
64
|
recommendationCampaignUrls: {},
|
|
70
65
|
activePredictiveAlgorithms: [],
|
|
71
66
|
languages: {},
|
|
@@ -74,14 +69,11 @@ const $ = () => ({
|
|
|
74
69
|
strategies: [],
|
|
75
70
|
strategiesLoading: !1,
|
|
76
71
|
strategyUrlTemplates: {},
|
|
77
|
-
strategiesFetched: !1,
|
|
78
|
-
strategiesSettled: !1,
|
|
79
72
|
blockStates: {},
|
|
80
73
|
currentRecommendationId: null,
|
|
81
|
-
strategyPanelOpen: !1,
|
|
82
74
|
configVersion: 0
|
|
83
|
-
}),
|
|
84
|
-
state: () =>
|
|
75
|
+
}), Y = P("guidoRecommendationExtension", {
|
|
76
|
+
state: () => z(),
|
|
85
77
|
getters: {
|
|
86
78
|
// ====================================================================
|
|
87
79
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -91,7 +83,7 @@ const $ = () => ({
|
|
|
91
83
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
92
84
|
*/
|
|
93
85
|
recommendationConfigs(t) {
|
|
94
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
86
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
|
|
95
87
|
},
|
|
96
88
|
/**
|
|
97
89
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -146,12 +138,12 @@ const $ = () => ({
|
|
|
146
138
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
147
139
|
},
|
|
148
140
|
getActivePredictiveAlgorithms: (t) => {
|
|
149
|
-
const e =
|
|
150
|
-
return t.activePredictiveAlgorithms.filter((
|
|
151
|
-
r.push(...e.filter((s) => s.id ===
|
|
152
|
-
}), r.map((
|
|
153
|
-
text:
|
|
154
|
-
value:
|
|
141
|
+
const e = b(), r = [];
|
|
142
|
+
return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
|
|
143
|
+
r.push(...e.filter((s) => s.id === n));
|
|
144
|
+
}), r.map((n) => ({
|
|
145
|
+
text: n.name,
|
|
146
|
+
value: n.key
|
|
155
147
|
}));
|
|
156
148
|
},
|
|
157
149
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
@@ -165,7 +157,7 @@ const $ = () => ({
|
|
|
165
157
|
getFilterList() {
|
|
166
158
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
167
159
|
let e;
|
|
168
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
160
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
169
161
|
text: t.displayName,
|
|
170
162
|
value: e,
|
|
171
163
|
type: t.attributeType
|
|
@@ -187,7 +179,7 @@ const $ = () => ({
|
|
|
187
179
|
setCurrentBlock(t) {
|
|
188
180
|
this.blockStates[t] || (this.blockStates = {
|
|
189
181
|
...this.blockStates,
|
|
190
|
-
[t]:
|
|
182
|
+
[t]: C()
|
|
191
183
|
}), this.currentRecommendationId = t;
|
|
192
184
|
},
|
|
193
185
|
/**
|
|
@@ -197,36 +189,32 @@ const $ = () => ({
|
|
|
197
189
|
removeBlockState(t) {
|
|
198
190
|
const e = t.toString();
|
|
199
191
|
if (this.recommendationCampaignUrls[e]) {
|
|
200
|
-
const
|
|
201
|
-
delete
|
|
192
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
193
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
202
194
|
}
|
|
203
195
|
const r = { ...this.blockStates };
|
|
204
196
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
205
|
-
const
|
|
206
|
-
this.currentRecommendationId =
|
|
197
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
198
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
207
199
|
}
|
|
208
200
|
},
|
|
209
201
|
/**
|
|
210
202
|
* Deep-clones a block's state and mirrors its campaign URL under a new id.
|
|
211
203
|
* Invoked from `onCreated` when a duplicate is detected (SD-142352).
|
|
212
|
-
*
|
|
213
|
-
* The clone keeps the source's data but drops its "already fetched / already
|
|
214
|
-
* synced" claims for strategy blocks, so it fetches again like a fresh drop
|
|
215
|
-
* (SD-149916).
|
|
216
204
|
*/
|
|
217
205
|
cloneBlockState(t, e) {
|
|
218
206
|
const r = this.blockStates[t];
|
|
219
207
|
if (r) {
|
|
220
208
|
const o = structuredClone(r);
|
|
221
|
-
o.recommendationConfigs.id = e,
|
|
209
|
+
o.recommendationConfigs.id = e, this.blockStates = {
|
|
222
210
|
...this.blockStates,
|
|
223
211
|
[e]: o
|
|
224
212
|
};
|
|
225
213
|
}
|
|
226
|
-
const
|
|
227
|
-
|
|
214
|
+
const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
|
|
215
|
+
i && (this.recommendationCampaignUrls = {
|
|
228
216
|
...this.recommendationCampaignUrls,
|
|
229
|
-
[s]:
|
|
217
|
+
[s]: i
|
|
230
218
|
});
|
|
231
219
|
},
|
|
232
220
|
/**
|
|
@@ -251,7 +239,7 @@ const $ = () => ({
|
|
|
251
239
|
* `isInitialized`) alone.
|
|
252
240
|
*/
|
|
253
241
|
seedBlockUrlConfig(t, e) {
|
|
254
|
-
const r = (o,
|
|
242
|
+
const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
|
|
255
243
|
name: e.currencyCode,
|
|
256
244
|
value: e.currencyCode,
|
|
257
245
|
symbol: e.currencySymbol,
|
|
@@ -259,9 +247,9 @@ const $ = () => ({
|
|
|
259
247
|
decimalCount: String(e.currencyDecimalCount),
|
|
260
248
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
261
249
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
262
|
-
}, s = !this.blockStates[t],
|
|
263
|
-
|
|
264
|
-
...
|
|
250
|
+
}, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
|
|
251
|
+
i.recommendationConfigs = {
|
|
252
|
+
...i.recommendationConfigs,
|
|
265
253
|
strategy: e.strategy,
|
|
266
254
|
strategyId: e.strategyId,
|
|
267
255
|
language: e.language,
|
|
@@ -269,10 +257,10 @@ const $ = () => ({
|
|
|
269
257
|
productIds: e.productIds,
|
|
270
258
|
filters: e.filters,
|
|
271
259
|
shuffleProducts: e.shuffleProducts,
|
|
272
|
-
currencySettings:
|
|
260
|
+
currencySettings: n
|
|
273
261
|
}, s && (this.blockStates = {
|
|
274
262
|
...this.blockStates,
|
|
275
|
-
[t]:
|
|
263
|
+
[t]: i
|
|
276
264
|
});
|
|
277
265
|
},
|
|
278
266
|
/**
|
|
@@ -291,18 +279,18 @@ const $ = () => ({
|
|
|
291
279
|
...t.currencySettings || {}
|
|
292
280
|
}
|
|
293
281
|
};
|
|
294
|
-
const { triggerRefetch:
|
|
295
|
-
|
|
282
|
+
const { triggerRefetch: n = !0 } = e;
|
|
283
|
+
n && this.configVersion++;
|
|
296
284
|
},
|
|
297
285
|
/**
|
|
298
286
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
299
287
|
*/
|
|
300
288
|
createDefaultFilter(t, e) {
|
|
301
|
-
const [r] = this.getFilterList, [
|
|
289
|
+
const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
|
|
302
290
|
return {
|
|
303
291
|
type: "standardFilter",
|
|
304
292
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
305
|
-
operator: (
|
|
293
|
+
operator: (n == null ? void 0 : n.value) ?? "",
|
|
306
294
|
innerGroupOperator: "*",
|
|
307
295
|
outerGroupOperator: "*",
|
|
308
296
|
filterNumber: e,
|
|
@@ -358,112 +346,33 @@ const $ = () => ({
|
|
|
358
346
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
|
|
359
347
|
},
|
|
360
348
|
async fetchStrategies() {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
await R;
|
|
364
|
-
} catch {
|
|
365
|
-
}
|
|
366
|
-
if (this.strategiesFetched)
|
|
349
|
+
if (S) {
|
|
350
|
+
await S;
|
|
367
351
|
return;
|
|
368
|
-
|
|
352
|
+
}
|
|
353
|
+
S = (async () => {
|
|
369
354
|
this.strategiesLoading = !0;
|
|
370
355
|
try {
|
|
371
|
-
|
|
372
|
-
if (t !== b)
|
|
373
|
-
return;
|
|
374
|
-
this.strategies = r, this.strategiesFetched = !0;
|
|
356
|
+
this.strategies = await u.fetchRecommendationStrategies();
|
|
375
357
|
} finally {
|
|
376
|
-
this.strategiesLoading = !1
|
|
358
|
+
this.strategiesLoading = !1;
|
|
377
359
|
}
|
|
378
360
|
})();
|
|
379
|
-
R = e;
|
|
380
361
|
try {
|
|
381
|
-
await
|
|
362
|
+
await S;
|
|
382
363
|
} finally {
|
|
383
|
-
|
|
364
|
+
S = null;
|
|
384
365
|
}
|
|
385
366
|
},
|
|
386
|
-
/**
|
|
387
|
-
* Clears what a block inherited from the id it arrived holding, so the panel fetches for it.
|
|
388
|
-
* A re-dropped saved module can keep the source's id — and its "already fetched" entry —
|
|
389
|
-
* while the strategy's product count has moved on (SD-149916).
|
|
390
|
-
*/
|
|
391
|
-
resetArrivedBlock(t) {
|
|
392
|
-
const e = this.blockStates[t];
|
|
393
|
-
e != null && e.recommendationConfigs.strategyId && (e.isInitialized = !1, e.syncedConfigFingerprint = null, this.invalidateStrategies(), this.fetchStrategies().catch(() => {
|
|
394
|
-
}));
|
|
395
|
-
},
|
|
396
|
-
invalidateStrategies() {
|
|
397
|
-
this.strategiesFetched = !1, this.strategiesSettled = !1, b += 1;
|
|
398
|
-
},
|
|
399
|
-
/**
|
|
400
|
-
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
401
|
-
* the user comes back. `visibilitychange` only: a `focus` listener would also fire when
|
|
402
|
-
* focus merely returns from the Stripo canvas iframe to the panel, refetching and
|
|
403
|
-
* regenerating the canvas while the user never left the editor (SD-149916).
|
|
404
|
-
*
|
|
405
|
-
* Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
|
|
406
|
-
* strategy in it and come back again — a listener that disarmed on the first return would
|
|
407
|
-
* leave that one missing from the list. It disarms on the first return AFTER that tab is
|
|
408
|
-
* closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
|
|
409
|
-
* once the user actually opens a strategy page, so anyone who never does pays nothing.
|
|
410
|
-
* @returns whether a tab actually opened, so callers can skip work that assumes one did
|
|
411
|
-
*/
|
|
412
|
-
_armStrategyPageReturn(t) {
|
|
413
|
-
const e = window.open(t, "_blank");
|
|
414
|
-
if (!e)
|
|
415
|
-
return !1;
|
|
416
|
-
e.opener = null, l == null || l();
|
|
417
|
-
let r = !1;
|
|
418
|
-
const i = () => {
|
|
419
|
-
document.hidden || r || (e != null && e.closed && (l == null || l()), r = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
|
|
420
|
-
}).finally(() => {
|
|
421
|
-
r = !1;
|
|
422
|
-
}));
|
|
423
|
-
};
|
|
424
|
-
return document.addEventListener("visibilitychange", i), l = () => {
|
|
425
|
-
document.removeEventListener("visibilitychange", i), l = null;
|
|
426
|
-
}, !0;
|
|
427
|
-
},
|
|
428
|
-
/**
|
|
429
|
-
* Reloads the products of the block the user is on, so an edit made in the strategy tab
|
|
430
|
-
* lands on the canvas instead of waiting for the assign drawer to be reopened.
|
|
431
|
-
*
|
|
432
|
-
* Only the selected block: the canvas regeneration is driven off the active block's
|
|
433
|
-
* product array, so refreshing an unselected block would fetch without redrawing it.
|
|
434
|
-
*/
|
|
435
|
-
async _refreshAssignedStrategyProducts() {
|
|
436
|
-
var e;
|
|
437
|
-
const t = this.currentRecommendationId;
|
|
438
|
-
t === null || !((e = this.blockStates[t]) != null && e.recommendationConfigs.strategyId) || await this.fetchRecommendationProducts();
|
|
439
|
-
},
|
|
440
|
-
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
441
|
-
disposeStrategyPageReturn() {
|
|
442
|
-
l == null || l();
|
|
443
|
-
},
|
|
444
|
-
/**
|
|
445
|
-
* Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
|
|
446
|
-
* new strategy is offered; the user picks it themselves.
|
|
447
|
-
*/
|
|
448
|
-
openStrategyCreation() {
|
|
449
|
-
return this._armStrategyPageReturn(_.RECOMMENDATION_STRATEGY_CREATE_PATH);
|
|
450
|
-
},
|
|
451
|
-
/**
|
|
452
|
-
* Opens the strategy's edit page. Every return refreshes the list so the block reflects the
|
|
453
|
-
* edited configuration.
|
|
454
|
-
*/
|
|
455
|
-
openStrategyEdit(t) {
|
|
456
|
-
return this._armStrategyPageReturn(D(t));
|
|
457
|
-
},
|
|
458
367
|
async resolveStrategyUrlTemplate(t, e) {
|
|
459
|
-
const r = typeof t.updated_at == "string" ? t.updated_at : "",
|
|
368
|
+
const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
|
|
460
369
|
if (s)
|
|
461
370
|
return s;
|
|
462
|
-
const { full_path:
|
|
463
|
-
return
|
|
371
|
+
const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
|
|
372
|
+
return n && i && (this.strategyUrlTemplates = {
|
|
464
373
|
...this.strategyUrlTemplates,
|
|
465
|
-
[
|
|
466
|
-
}),
|
|
374
|
+
[n]: i
|
|
375
|
+
}), i;
|
|
467
376
|
},
|
|
468
377
|
assignStrategy(t) {
|
|
469
378
|
this.patchCurrentBlockConfig({
|
|
@@ -472,54 +381,50 @@ const $ = () => ({
|
|
|
472
381
|
});
|
|
473
382
|
},
|
|
474
383
|
removeStrategy() {
|
|
475
|
-
this.patchCurrentBlockConfig({
|
|
476
|
-
strategyId: "",
|
|
477
|
-
strategy: "",
|
|
478
|
-
size: x.size
|
|
479
|
-
});
|
|
384
|
+
this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
|
|
480
385
|
},
|
|
481
386
|
// ====================================================================
|
|
482
387
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
483
388
|
// ====================================================================
|
|
484
389
|
async fetchRecommendationCreateData() {
|
|
485
390
|
if (!this.activePredictiveAlgorithms.length) {
|
|
486
|
-
if (
|
|
487
|
-
await
|
|
391
|
+
if (f) {
|
|
392
|
+
await f;
|
|
488
393
|
return;
|
|
489
394
|
}
|
|
490
|
-
|
|
395
|
+
f = (async () => {
|
|
491
396
|
const {
|
|
492
397
|
activePredictiveAlgorithms: t,
|
|
493
398
|
languages: e,
|
|
494
399
|
currencies: r
|
|
495
|
-
} = await
|
|
400
|
+
} = await u.fetchRecommendationCreateData();
|
|
496
401
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
497
|
-
const
|
|
498
|
-
|
|
402
|
+
const n = this.blockStates[this.currentRecommendationId];
|
|
403
|
+
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
499
404
|
}
|
|
500
405
|
this.currencyList = r;
|
|
501
406
|
})();
|
|
502
407
|
try {
|
|
503
|
-
await
|
|
408
|
+
await f;
|
|
504
409
|
} finally {
|
|
505
|
-
|
|
410
|
+
f = null;
|
|
506
411
|
}
|
|
507
412
|
}
|
|
508
413
|
},
|
|
509
414
|
async fetchRecommendationFilters() {
|
|
510
415
|
if (!Object.keys(this.filterList).length) {
|
|
511
|
-
if (
|
|
512
|
-
await
|
|
416
|
+
if (g) {
|
|
417
|
+
await g;
|
|
513
418
|
return;
|
|
514
419
|
}
|
|
515
|
-
|
|
516
|
-
const t = await
|
|
420
|
+
g = (async () => {
|
|
421
|
+
const t = await u.fetchRecommendationFilters();
|
|
517
422
|
this.filterList = t;
|
|
518
423
|
})();
|
|
519
424
|
try {
|
|
520
|
-
await
|
|
425
|
+
await g;
|
|
521
426
|
} finally {
|
|
522
|
-
|
|
427
|
+
g = null;
|
|
523
428
|
}
|
|
524
429
|
}
|
|
525
430
|
},
|
|
@@ -534,41 +439,41 @@ const $ = () => ({
|
|
|
534
439
|
deleteFilterGroup(t) {
|
|
535
440
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
536
441
|
return;
|
|
537
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
538
|
-
e.recommendationConfigs.filters = r.map((
|
|
539
|
-
...
|
|
540
|
-
filterGroup: s.get(
|
|
442
|
+
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]));
|
|
443
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
444
|
+
...i,
|
|
445
|
+
filterGroup: s.get(i.filterGroup) ?? i.filterGroup
|
|
541
446
|
}));
|
|
542
447
|
},
|
|
543
448
|
updateFilter(t) {
|
|
544
449
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
545
450
|
return;
|
|
546
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
451
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
547
452
|
if (r !== -1) {
|
|
548
|
-
const
|
|
549
|
-
|
|
453
|
+
const n = [...e.recommendationConfigs.filters];
|
|
454
|
+
n[r] = {
|
|
550
455
|
...t,
|
|
551
|
-
isValid:
|
|
552
|
-
}, e.recommendationConfigs.filters =
|
|
456
|
+
isValid: B(t)
|
|
457
|
+
}, e.recommendationConfigs.filters = n;
|
|
553
458
|
}
|
|
554
459
|
},
|
|
555
460
|
deleteFilter(t) {
|
|
556
461
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
557
462
|
return;
|
|
558
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
463
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
559
464
|
if (r !== -1) {
|
|
560
|
-
let
|
|
561
|
-
if (
|
|
562
|
-
let
|
|
563
|
-
|
|
465
|
+
let n = [...e.recommendationConfigs.filters];
|
|
466
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
467
|
+
let i = 1;
|
|
468
|
+
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
564
469
|
} else {
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
...
|
|
568
|
-
filterGroup: o.get(
|
|
470
|
+
const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
|
|
471
|
+
n = n.map((c) => ({
|
|
472
|
+
...c,
|
|
473
|
+
filterGroup: o.get(c.filterGroup) ?? c.filterGroup
|
|
569
474
|
}));
|
|
570
475
|
}
|
|
571
|
-
e.recommendationConfigs.filters =
|
|
476
|
+
e.recommendationConfigs.filters = n;
|
|
572
477
|
}
|
|
573
478
|
},
|
|
574
479
|
addFilter(t) {
|
|
@@ -576,8 +481,8 @@ const $ = () => ({
|
|
|
576
481
|
return;
|
|
577
482
|
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
|
|
578
483
|
(o) => o.filterGroup === t.filterGroup
|
|
579
|
-
).length + 1,
|
|
580
|
-
|
|
484
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
485
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
581
486
|
...t,
|
|
582
487
|
filterNumber: s
|
|
583
488
|
}) : r.push({
|
|
@@ -586,7 +491,7 @@ const $ = () => ({
|
|
|
586
491
|
}), e.recommendationConfigs.filters = r;
|
|
587
492
|
},
|
|
588
493
|
generateFilterQuery() {
|
|
589
|
-
return
|
|
494
|
+
return k(this.recommendationConfigs.filters);
|
|
590
495
|
},
|
|
591
496
|
/**
|
|
592
497
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -594,102 +499,83 @@ const $ = () => ({
|
|
|
594
499
|
* every block's recommendationConfigs across user edits.
|
|
595
500
|
*/
|
|
596
501
|
hasInvalidBlock() {
|
|
597
|
-
return Object.values(this.blockStates).some((t) => !
|
|
598
|
-
},
|
|
599
|
-
/**
|
|
600
|
-
* Which required fields are missing across the design's blocks, so the save
|
|
601
|
-
* toaster can name the cause instead of always showing the generic message.
|
|
602
|
-
*/
|
|
603
|
-
invalidBlockFields() {
|
|
604
|
-
return Object.values(this.blockStates).flatMap((t) => V(t.recommendationConfigs, this));
|
|
502
|
+
return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
|
|
605
503
|
},
|
|
606
504
|
// ====================================================================
|
|
607
505
|
// Per-Block Product Fetching
|
|
608
506
|
// ====================================================================
|
|
609
507
|
async fetchRecommendationProducts() {
|
|
610
|
-
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
I = t, y = this._doFetchProducts();
|
|
622
|
-
try {
|
|
623
|
-
await y;
|
|
624
|
-
} finally {
|
|
625
|
-
I === t && (y = null, I = "");
|
|
508
|
+
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
509
|
+
if (h) {
|
|
510
|
+
await h;
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
h = this._doFetchProducts();
|
|
514
|
+
try {
|
|
515
|
+
await h;
|
|
516
|
+
} finally {
|
|
517
|
+
h = null;
|
|
518
|
+
}
|
|
626
519
|
}
|
|
627
520
|
},
|
|
628
521
|
async _doFetchProducts() {
|
|
629
|
-
var
|
|
630
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
631
|
-
if (r.strategyId &&
|
|
522
|
+
var d;
|
|
523
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
|
|
524
|
+
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
632
525
|
await this._doFetchStrategyProducts(t);
|
|
633
526
|
return;
|
|
634
527
|
}
|
|
635
|
-
const s = (
|
|
636
|
-
g.set(t, s);
|
|
637
|
-
const n = parseInt(r.size) || 6;
|
|
638
|
-
if (!r.strategy) {
|
|
639
|
-
this._setBlockProducts(t, [], n);
|
|
640
|
-
return;
|
|
641
|
-
}
|
|
642
|
-
const o = r.filters.filter((d) => d.isValid), a = w(o), u = ((h = v().find((d) => d.key === r.strategy)) == null ? void 0 : h.path) || "", c = {
|
|
528
|
+
const s = r.filters.filter((m) => m.isValid), i = k(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
|
|
643
529
|
locale: r.language,
|
|
644
530
|
currency: r.currencySettings.value,
|
|
645
|
-
partnerName:
|
|
531
|
+
partnerName: n.partnerName,
|
|
646
532
|
size: r.size,
|
|
647
533
|
details: !0,
|
|
648
|
-
campaignId:
|
|
534
|
+
campaignId: n.variationId
|
|
649
535
|
};
|
|
650
|
-
r.strategy === "manualMerchandising" ?
|
|
651
|
-
|
|
652
|
-
|
|
536
|
+
r.strategy === "manualMerchandising" ? a.productId = A(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(
|
|
537
|
+
a,
|
|
538
|
+
x(n.partnerName, r.strategy)
|
|
653
539
|
);
|
|
654
|
-
let
|
|
540
|
+
let l;
|
|
655
541
|
try {
|
|
656
|
-
|
|
542
|
+
l = await u.fetchRecommendationProducts(o, a);
|
|
657
543
|
} catch {
|
|
658
|
-
|
|
544
|
+
l = [];
|
|
659
545
|
}
|
|
660
|
-
|
|
546
|
+
this._setBlockProducts(t, l, c);
|
|
661
547
|
},
|
|
662
548
|
async _doFetchStrategyProducts(t) {
|
|
663
|
-
const e = (
|
|
664
|
-
|
|
549
|
+
const e = (p.get(t) ?? 0) + 1;
|
|
550
|
+
p.set(t, e);
|
|
665
551
|
const { recommendationConfigs: r } = this.blockStates[t];
|
|
666
|
-
let
|
|
552
|
+
let n = [], s = parseInt(r.size) || 6;
|
|
667
553
|
try {
|
|
668
554
|
await this.fetchStrategies();
|
|
669
|
-
const
|
|
555
|
+
const i = this.strategies.find(
|
|
670
556
|
(o) => String(o.strategy_id) === r.strategyId
|
|
671
557
|
);
|
|
672
|
-
if (
|
|
673
|
-
s = parseInt(String(
|
|
674
|
-
const o = r.currencySettings.value,
|
|
675
|
-
|
|
558
|
+
if (i) {
|
|
559
|
+
s = parseInt(String(i.size ?? "")) || s;
|
|
560
|
+
const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = m.length ? `${d}?${m.join("&")}` : d;
|
|
561
|
+
y && (n = await u.fetchRecommendationProductsByUrl(y));
|
|
676
562
|
}
|
|
677
563
|
} catch {
|
|
678
|
-
|
|
564
|
+
n = [];
|
|
679
565
|
}
|
|
680
|
-
|
|
566
|
+
p.get(t) === e && this._setBlockProducts(t, n, s);
|
|
681
567
|
},
|
|
682
568
|
_setBlockProducts(t, e, r) {
|
|
683
569
|
if (!this.blockStates[t])
|
|
684
570
|
return;
|
|
685
|
-
const
|
|
571
|
+
const n = e.length > 0 ? e : R(r);
|
|
686
572
|
this.blockStates[t].recommendationProducts = [
|
|
687
|
-
...
|
|
688
|
-
...
|
|
573
|
+
...n.slice(0, r),
|
|
574
|
+
...R(Math.max(0, r - n.length))
|
|
689
575
|
];
|
|
690
576
|
}
|
|
691
577
|
}
|
|
692
578
|
});
|
|
693
579
|
export {
|
|
694
|
-
|
|
580
|
+
Y as useRecommendationExtensionStore
|
|
695
581
|
};
|