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