@useinsider/guido 3.12.0-beta.98baf2f → 3.12.0-beta.b73c720
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/@types/config/schemas.js +13 -8
- package/dist/components/Guido.vue.js +6 -6
- package/dist/components/Guido.vue2.js +50 -49
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +36 -0
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +244 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +18 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +42 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +18 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +60 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +19 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +19 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +22 -0
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +29 -0
- package/dist/composables/useRecommendation.js +82 -51
- package/dist/composables/useStrategyFilters.js +16 -0
- package/dist/composables/useStripoEventHandler.js +9 -12
- package/dist/config/migrator/recommendationMigrator.js +7 -4
- package/dist/enums/date.js +4 -3
- package/dist/enums/extensions/filteringV2.js +8 -0
- package/dist/enums/extensions/recommendationBlock.js +28 -22
- package/dist/enums/extensions/strategyDetail.js +148 -0
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +123 -109
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +146 -0
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +1 -1
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +256 -102
- package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
- package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +10 -0
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -12
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +65 -27
- package/dist/services/stripoApi.js +27 -28
- package/dist/src/@types/config/schemas.d.ts +10 -0
- package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +43 -0
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +29 -0
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +40 -0
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +38 -0
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +51 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useRecommendation.d.ts +2 -0
- package/dist/src/composables/useStrategyFilters.d.ts +24 -0
- package/dist/src/enums/extensions/filteringV2.d.ts +72 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +10 -0
- package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +61 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +606 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +50 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +3 -1
- package/dist/src/services/recommendationApi.d.ts +7 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/utils/genericUtil.d.ts +9 -0
- package/dist/static/styles/base.css.js +15 -0
- package/dist/utils/dateUtil.js +23 -10
- package/dist/utils/genericUtil.js +10 -1
- package/dist/utils/templatePreparation.js +62 -58
- package/package.json +1 -1
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { useConfig as D } from "../../../../composables/useConfig.js";
|
|
2
|
+
import { useTranslations as F } from "../../../../composables/useTranslations.js";
|
|
3
|
+
import { getRecommendationFeedSourceMaps as y, getOperatorOptions as w, PriceAttributes as G } from "../../../../enums/extensions/recommendationBlock.js";
|
|
4
|
+
import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
|
|
5
|
+
import { useConfigStore as v } from "../../../../stores/config.js";
|
|
6
|
+
import { defineStore as L } from "pinia";
|
|
5
7
|
import "../constants/selectors.js";
|
|
6
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
7
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
8
|
-
import { getDefaultProducts as
|
|
9
|
-
import { generateCompleteFilterQuery as
|
|
10
|
-
import { getPartnerRecommendationParams as
|
|
11
|
-
import { isFilterValid as
|
|
12
|
-
import { isConfigValid as
|
|
13
|
-
const
|
|
14
|
-
let
|
|
15
|
-
|
|
8
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as U, DEFAULT_CARDS_IN_ROW as N } from "../constants/layout.js";
|
|
9
|
+
import { EXCLUDED_ALGORITHM_IDS as x } from "../constants/defaultConfig.js";
|
|
10
|
+
import { getDefaultProducts as I } from "../templates/utils.js";
|
|
11
|
+
import { generateCompleteFilterQuery as R } from "../utils/filterUtil.js";
|
|
12
|
+
import { getPartnerRecommendationParams as _ } from "../utils/partnerCustomizations.js";
|
|
13
|
+
import { isFilterValid as O } from "../validation/filterSchema.js";
|
|
14
|
+
import { isConfigValid as A } from "../validation/requiredFields.js";
|
|
15
|
+
const m = P();
|
|
16
|
+
let u = null, d = null, f = null, g = null, S = 0;
|
|
17
|
+
const p = {};
|
|
18
|
+
function C() {
|
|
16
19
|
return {
|
|
17
|
-
cardsInRow:
|
|
20
|
+
cardsInRow: N,
|
|
18
21
|
currencySettings: {
|
|
19
22
|
name: "USD",
|
|
20
23
|
value: "USD",
|
|
@@ -28,13 +31,14 @@ function k() {
|
|
|
28
31
|
productIds: [],
|
|
29
32
|
id: 1,
|
|
30
33
|
language: "en_US",
|
|
31
|
-
mobileCardsInRow:
|
|
34
|
+
mobileCardsInRow: U,
|
|
32
35
|
mobileLayoutEnabled: !1,
|
|
33
36
|
orientation: "grid",
|
|
34
37
|
recommendedProducts: [],
|
|
35
38
|
sendProductRequestFlag: !1,
|
|
36
39
|
shuffleProducts: !1,
|
|
37
40
|
strategy: "mostPopular",
|
|
41
|
+
strategyId: "",
|
|
38
42
|
textTrimming: !0,
|
|
39
43
|
unresponsive: !1,
|
|
40
44
|
size: "6",
|
|
@@ -43,28 +47,35 @@ function k() {
|
|
|
43
47
|
priceHideIfSameAsDiscounted: !1
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
|
-
function
|
|
50
|
+
function k() {
|
|
47
51
|
return {
|
|
48
|
-
recommendationConfigs:
|
|
52
|
+
recommendationConfigs: C(),
|
|
49
53
|
recommendationProducts: [],
|
|
50
54
|
filterStatus: !1,
|
|
51
55
|
filterSelectionDrawerStatus: !1,
|
|
56
|
+
strategyDetailDrawerStatus: !1,
|
|
52
57
|
filterGroup: 1,
|
|
53
58
|
isInitialized: !1,
|
|
54
59
|
filterSnapshot: null
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
|
-
const
|
|
62
|
+
const B = () => ({
|
|
58
63
|
recommendationCampaignUrls: {},
|
|
59
64
|
activePredictiveAlgorithms: [],
|
|
60
65
|
languages: {},
|
|
61
66
|
currencyList: [],
|
|
62
67
|
filterList: {},
|
|
68
|
+
strategies: [],
|
|
69
|
+
strategiesLoading: !1,
|
|
70
|
+
strategyCampaigns: [],
|
|
71
|
+
strategyCampaignsLoading: !1,
|
|
72
|
+
strategyCampaignsFetchedFor: null,
|
|
73
|
+
strategyUrlTemplates: {},
|
|
63
74
|
blockStates: {},
|
|
64
75
|
currentRecommendationId: null,
|
|
65
76
|
configVersion: 0
|
|
66
|
-
}),
|
|
67
|
-
state: () =>
|
|
77
|
+
}), Y = L("guidoRecommendationExtension", {
|
|
78
|
+
state: () => B(),
|
|
68
79
|
getters: {
|
|
69
80
|
// ====================================================================
|
|
70
81
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -74,7 +85,7 @@ const L = () => ({
|
|
|
74
85
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
75
86
|
*/
|
|
76
87
|
recommendationConfigs(t) {
|
|
77
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
88
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : C();
|
|
78
89
|
},
|
|
79
90
|
/**
|
|
80
91
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -88,6 +99,12 @@ const L = () => ({
|
|
|
88
99
|
filterSelectionDrawerStatus(t) {
|
|
89
100
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
90
101
|
},
|
|
102
|
+
/**
|
|
103
|
+
* Proxy getter: delegates to blockStates[currentRecommendationId].strategyDetailDrawerStatus
|
|
104
|
+
*/
|
|
105
|
+
strategyDetailDrawerStatus(t) {
|
|
106
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].strategyDetailDrawerStatus : !1;
|
|
107
|
+
},
|
|
91
108
|
/**
|
|
92
109
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
93
110
|
*/
|
|
@@ -119,14 +136,55 @@ const L = () => ({
|
|
|
119
136
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
120
137
|
},
|
|
121
138
|
getActivePredictiveAlgorithms: (t) => {
|
|
122
|
-
const e =
|
|
123
|
-
return t.activePredictiveAlgorithms.filter((
|
|
124
|
-
r.push(...e.filter((
|
|
125
|
-
}), r.map((
|
|
126
|
-
text:
|
|
127
|
-
value:
|
|
139
|
+
const e = y(), r = [];
|
|
140
|
+
return t.activePredictiveAlgorithms.filter((i) => !x.includes(i)).forEach((i) => {
|
|
141
|
+
r.push(...e.filter((a) => a.id === i));
|
|
142
|
+
}), r.map((i) => ({
|
|
143
|
+
text: i.name,
|
|
144
|
+
value: i.key
|
|
128
145
|
}));
|
|
129
146
|
},
|
|
147
|
+
/**
|
|
148
|
+
* Reusable Recommendation Strategies as dropdown options.
|
|
149
|
+
*
|
|
150
|
+
* Unlike algorithms, strategy ids come straight from Smart Recommender —
|
|
151
|
+
* there is no local id→key table to join against.
|
|
152
|
+
*/
|
|
153
|
+
getStrategyOptions: (t) => t.strategies.map((e) => ({
|
|
154
|
+
text: e.name,
|
|
155
|
+
value: String(e.strategy_id)
|
|
156
|
+
})),
|
|
157
|
+
/**
|
|
158
|
+
* The current block's selected strategy, or null when none is selected
|
|
159
|
+
* or the selected id is no longer in the listing.
|
|
160
|
+
*
|
|
161
|
+
* A null return with a non-empty `strategyId` means the strategy was
|
|
162
|
+
* deleted in Smart Recommender after this block was configured — the
|
|
163
|
+
* panel flags that rather than silently clearing the selection.
|
|
164
|
+
*/
|
|
165
|
+
getSelectedStrategy() {
|
|
166
|
+
const { strategyId: t } = this.recommendationConfigs;
|
|
167
|
+
return t ? this.strategies.find((e) => String(e.strategy_id) === t) ?? null : null;
|
|
168
|
+
},
|
|
169
|
+
/**
|
|
170
|
+
* Whether the RRS feature is enabled for this editor.
|
|
171
|
+
*
|
|
172
|
+
* Read through a getter so `hasInvalidBlock` can pass the store straight to
|
|
173
|
+
* the required-field descriptors, which need the flag to decide whether a
|
|
174
|
+
* missing strategy blocks the save.
|
|
175
|
+
*/
|
|
176
|
+
isRrsEnabled() {
|
|
177
|
+
return D().isFeatureEnabled("reusableRecommendationStrategy");
|
|
178
|
+
},
|
|
179
|
+
/**
|
|
180
|
+
* True when a strategy id is set but absent from the fetched listing.
|
|
181
|
+
*
|
|
182
|
+
* Guarded on the listing having loaded — mid-fetch every id looks missing.
|
|
183
|
+
*/
|
|
184
|
+
hasMissingStrategy() {
|
|
185
|
+
const { strategyId: t } = this.recommendationConfigs;
|
|
186
|
+
return !t || this.strategiesLoading || !this.strategies.length ? !1 : this.getSelectedStrategy === null;
|
|
187
|
+
},
|
|
130
188
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
131
189
|
text: r,
|
|
132
190
|
value: e
|
|
@@ -138,7 +196,7 @@ const L = () => ({
|
|
|
138
196
|
getFilterList() {
|
|
139
197
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
140
198
|
let e;
|
|
141
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
199
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : G.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
142
200
|
text: t.displayName,
|
|
143
201
|
value: e,
|
|
144
202
|
type: t.attributeType
|
|
@@ -160,7 +218,7 @@ const L = () => ({
|
|
|
160
218
|
setCurrentBlock(t) {
|
|
161
219
|
this.blockStates[t] || (this.blockStates = {
|
|
162
220
|
...this.blockStates,
|
|
163
|
-
[t]:
|
|
221
|
+
[t]: k()
|
|
164
222
|
}), this.currentRecommendationId = t;
|
|
165
223
|
},
|
|
166
224
|
/**
|
|
@@ -170,13 +228,13 @@ const L = () => ({
|
|
|
170
228
|
removeBlockState(t) {
|
|
171
229
|
const e = t.toString();
|
|
172
230
|
if (this.recommendationCampaignUrls[e]) {
|
|
173
|
-
const
|
|
174
|
-
delete
|
|
231
|
+
const i = { ...this.recommendationCampaignUrls };
|
|
232
|
+
delete i[e], this.recommendationCampaignUrls = i;
|
|
175
233
|
}
|
|
176
234
|
const r = { ...this.blockStates };
|
|
177
235
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
178
|
-
const
|
|
179
|
-
this.currentRecommendationId =
|
|
236
|
+
const i = Object.keys(this.blockStates).map(Number);
|
|
237
|
+
this.currentRecommendationId = i.length > 0 ? i[0] : null;
|
|
180
238
|
}
|
|
181
239
|
},
|
|
182
240
|
/**
|
|
@@ -192,10 +250,10 @@ const L = () => ({
|
|
|
192
250
|
[e]: o
|
|
193
251
|
};
|
|
194
252
|
}
|
|
195
|
-
const
|
|
196
|
-
|
|
253
|
+
const i = t.toString(), a = e.toString(), n = this.recommendationCampaignUrls[i];
|
|
254
|
+
n && (this.recommendationCampaignUrls = {
|
|
197
255
|
...this.recommendationCampaignUrls,
|
|
198
|
-
[
|
|
256
|
+
[a]: n
|
|
199
257
|
});
|
|
200
258
|
},
|
|
201
259
|
/**
|
|
@@ -220,7 +278,7 @@ const L = () => ({
|
|
|
220
278
|
* `isInitialized`) alone.
|
|
221
279
|
*/
|
|
222
280
|
seedBlockUrlConfig(t, e) {
|
|
223
|
-
const r = (o, s) => o === "." || o === "," || o === " " ? o : s,
|
|
281
|
+
const r = (o, s) => o === "." || o === "," || o === " " ? o : s, i = {
|
|
224
282
|
name: e.currencyCode,
|
|
225
283
|
value: e.currencyCode,
|
|
226
284
|
symbol: e.currencyCode,
|
|
@@ -228,19 +286,20 @@ const L = () => ({
|
|
|
228
286
|
decimalCount: String(e.currencyDecimalCount),
|
|
229
287
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
230
288
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
...
|
|
289
|
+
}, a = !this.blockStates[t], n = a ? k() : this.blockStates[t];
|
|
290
|
+
n.recommendationConfigs = {
|
|
291
|
+
...n.recommendationConfigs,
|
|
234
292
|
strategy: e.strategy,
|
|
293
|
+
strategyId: e.strategyId,
|
|
235
294
|
language: e.language,
|
|
236
295
|
size: e.size,
|
|
237
296
|
productIds: e.productIds,
|
|
238
297
|
filters: e.filters,
|
|
239
298
|
shuffleProducts: e.shuffleProducts,
|
|
240
|
-
currencySettings:
|
|
241
|
-
},
|
|
299
|
+
currencySettings: i
|
|
300
|
+
}, a && (this.blockStates = {
|
|
242
301
|
...this.blockStates,
|
|
243
|
-
[t]:
|
|
302
|
+
[t]: n
|
|
244
303
|
});
|
|
245
304
|
},
|
|
246
305
|
/**
|
|
@@ -259,18 +318,18 @@ const L = () => ({
|
|
|
259
318
|
...t.currencySettings || {}
|
|
260
319
|
}
|
|
261
320
|
};
|
|
262
|
-
const { triggerRefetch:
|
|
263
|
-
|
|
321
|
+
const { triggerRefetch: i = !0 } = e;
|
|
322
|
+
i && this.configVersion++;
|
|
264
323
|
},
|
|
265
324
|
/**
|
|
266
325
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
267
326
|
*/
|
|
268
327
|
createDefaultFilter(t, e) {
|
|
269
|
-
const [r] = this.getFilterList, [
|
|
328
|
+
const [r] = this.getFilterList, [i] = w(r == null ? void 0 : r.type);
|
|
270
329
|
return {
|
|
271
330
|
type: "standardFilter",
|
|
272
331
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
273
|
-
operator: (
|
|
332
|
+
operator: (i == null ? void 0 : i.value) ?? "",
|
|
274
333
|
innerGroupOperator: "*",
|
|
275
334
|
outerGroupOperator: "*",
|
|
276
335
|
filterNumber: e,
|
|
@@ -303,6 +362,72 @@ const L = () => ({
|
|
|
303
362
|
const t = this.blockStates[this.currentRecommendationId];
|
|
304
363
|
t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
|
|
305
364
|
},
|
|
365
|
+
/**
|
|
366
|
+
* Opens the RRS detail drawer for the current block.
|
|
367
|
+
*
|
|
368
|
+
* Unlike the filter drawer this takes no snapshot — the drawer is
|
|
369
|
+
* read-only, so there is nothing to revert on close.
|
|
370
|
+
*/
|
|
371
|
+
openStrategyDrawer() {
|
|
372
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !0);
|
|
373
|
+
},
|
|
374
|
+
/**
|
|
375
|
+
* Closes the RRS detail drawer for the current block and drops the campaign
|
|
376
|
+
* list, so reopening on a different strategy never flashes stale rows.
|
|
377
|
+
*/
|
|
378
|
+
closeStrategyDrawer() {
|
|
379
|
+
this.clearStrategyCampaigns(), !(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId]) && (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !1);
|
|
380
|
+
},
|
|
381
|
+
/** Drops the campaign list and lets the next open refetch. */
|
|
382
|
+
clearStrategyCampaigns() {
|
|
383
|
+
this.strategyCampaigns = [], this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = null, S += 1;
|
|
384
|
+
},
|
|
385
|
+
/**
|
|
386
|
+
* Resolve and cache a strategy's recommendation-URL template.
|
|
387
|
+
*
|
|
388
|
+
* Must be awaited before `buildCampaignUrl` runs for a strategy-driven block,
|
|
389
|
+
* because that builder is synchronous and can only read what is already
|
|
390
|
+
* cached. Safe to call repeatedly: a cached id (including one cached as the
|
|
391
|
+
* empty string after a failure) short-circuits, and concurrent callers for
|
|
392
|
+
* the same id share one request.
|
|
393
|
+
*/
|
|
394
|
+
async fetchStrategyUrlTemplate(t) {
|
|
395
|
+
if (!t || t in this.strategyUrlTemplates)
|
|
396
|
+
return;
|
|
397
|
+
const e = p[t];
|
|
398
|
+
if (e) {
|
|
399
|
+
await e;
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
p[t] = (async () => {
|
|
403
|
+
const r = await m.fetchStrategyRecommendationUrl(t);
|
|
404
|
+
this.strategyUrlTemplates = {
|
|
405
|
+
...this.strategyUrlTemplates,
|
|
406
|
+
[t]: (r == null ? void 0 : r.full_path) ?? ""
|
|
407
|
+
};
|
|
408
|
+
})();
|
|
409
|
+
try {
|
|
410
|
+
await p[t];
|
|
411
|
+
} finally {
|
|
412
|
+
delete p[t];
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
/**
|
|
416
|
+
* Fetch the campaigns a strategy is used in, for the drawer's second tab.
|
|
417
|
+
*
|
|
418
|
+
* Lazy and once-per-strategy: the caller invokes this only while the drawer is
|
|
419
|
+
* open on that tab, and a repeat call for the same id is a no-op. A version
|
|
420
|
+
* counter discards a response that arrives after the user switched strategies,
|
|
421
|
+
* which would otherwise show one strategy's campaigns under another's name.
|
|
422
|
+
*/
|
|
423
|
+
async fetchStrategyCampaigns(t) {
|
|
424
|
+
if (!t || this.strategyCampaignsFetchedFor === t)
|
|
425
|
+
return;
|
|
426
|
+
const e = ++S;
|
|
427
|
+
this.strategyCampaignsLoading = !0;
|
|
428
|
+
const r = await m.fetchStrategyCampaigns(t, F());
|
|
429
|
+
e === S && (this.strategyCampaigns = r, this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = t);
|
|
430
|
+
},
|
|
306
431
|
/**
|
|
307
432
|
* Cancels the filter selection drawer and reverts filters
|
|
308
433
|
* to the snapshot taken when the drawer was opened.
|
|
@@ -318,43 +443,72 @@ const L = () => ({
|
|
|
318
443
|
// ====================================================================
|
|
319
444
|
async fetchRecommendationCreateData() {
|
|
320
445
|
if (!this.activePredictiveAlgorithms.length) {
|
|
321
|
-
if (
|
|
322
|
-
await
|
|
446
|
+
if (u) {
|
|
447
|
+
await u;
|
|
323
448
|
return;
|
|
324
449
|
}
|
|
325
|
-
|
|
450
|
+
u = (async () => {
|
|
326
451
|
const {
|
|
327
452
|
activePredictiveAlgorithms: t,
|
|
328
453
|
languages: e,
|
|
329
454
|
currencies: r
|
|
330
|
-
} = await
|
|
455
|
+
} = await m.fetchRecommendationCreateData();
|
|
331
456
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
332
|
-
const
|
|
333
|
-
|
|
457
|
+
const i = this.blockStates[this.currentRecommendationId];
|
|
458
|
+
i.filterStatus = !!i.recommendationConfigs.filters.length;
|
|
334
459
|
}
|
|
335
460
|
this.currencyList = r;
|
|
336
461
|
})();
|
|
337
462
|
try {
|
|
338
|
-
await
|
|
463
|
+
await u;
|
|
339
464
|
} finally {
|
|
340
|
-
|
|
465
|
+
u = null;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
/**
|
|
470
|
+
* Fetch the partner's Reusable Recommendation Strategies for the EMAIL channel.
|
|
471
|
+
*
|
|
472
|
+
* Same cache-guard + in-flight dedupe shape as fetchRecommendationCreateData.
|
|
473
|
+
* A failure leaves `strategies` empty so the dropdown renders empty rather
|
|
474
|
+
* than blocking the panel — the block keeps working on its algorithm.
|
|
475
|
+
*/
|
|
476
|
+
async fetchRecommendationStrategies() {
|
|
477
|
+
if (!this.strategies.length) {
|
|
478
|
+
if (g) {
|
|
479
|
+
await g;
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
this.strategiesLoading = !0, g = (async () => {
|
|
483
|
+
try {
|
|
484
|
+
this.strategies = await m.fetchRecommendationStrategies();
|
|
485
|
+
} catch {
|
|
486
|
+
this.strategies = [];
|
|
487
|
+
} finally {
|
|
488
|
+
this.strategiesLoading = !1;
|
|
489
|
+
}
|
|
490
|
+
})();
|
|
491
|
+
try {
|
|
492
|
+
await g;
|
|
493
|
+
} finally {
|
|
494
|
+
g = null;
|
|
341
495
|
}
|
|
342
496
|
}
|
|
343
497
|
},
|
|
344
498
|
async fetchRecommendationFilters() {
|
|
345
499
|
if (!Object.keys(this.filterList).length) {
|
|
346
|
-
if (
|
|
347
|
-
await
|
|
500
|
+
if (d) {
|
|
501
|
+
await d;
|
|
348
502
|
return;
|
|
349
503
|
}
|
|
350
|
-
|
|
351
|
-
const t = await
|
|
504
|
+
d = (async () => {
|
|
505
|
+
const t = await m.fetchRecommendationFilters();
|
|
352
506
|
this.filterList = t;
|
|
353
507
|
})();
|
|
354
508
|
try {
|
|
355
|
-
await
|
|
509
|
+
await d;
|
|
356
510
|
} finally {
|
|
357
|
-
|
|
511
|
+
d = null;
|
|
358
512
|
}
|
|
359
513
|
}
|
|
360
514
|
},
|
|
@@ -369,59 +523,59 @@ const L = () => ({
|
|
|
369
523
|
deleteFilterGroup(t) {
|
|
370
524
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
371
525
|
return;
|
|
372
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
373
|
-
e.recommendationConfigs.filters = r.map((
|
|
374
|
-
...
|
|
375
|
-
filterGroup:
|
|
526
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((n) => n.filterGroup !== t), i = [...new Set(r.map((n) => n.filterGroup))].sort((n, o) => n - o), a = new Map(i.map((n, o) => [n, o + 1]));
|
|
527
|
+
e.recommendationConfigs.filters = r.map((n) => ({
|
|
528
|
+
...n,
|
|
529
|
+
filterGroup: a.get(n.filterGroup) ?? n.filterGroup
|
|
376
530
|
}));
|
|
377
531
|
},
|
|
378
532
|
updateFilter(t) {
|
|
379
533
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
380
534
|
return;
|
|
381
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
535
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
|
|
382
536
|
if (r !== -1) {
|
|
383
|
-
const
|
|
384
|
-
|
|
537
|
+
const i = [...e.recommendationConfigs.filters];
|
|
538
|
+
i[r] = {
|
|
385
539
|
...t,
|
|
386
|
-
isValid:
|
|
387
|
-
}, e.recommendationConfigs.filters =
|
|
540
|
+
isValid: O(t)
|
|
541
|
+
}, e.recommendationConfigs.filters = i;
|
|
388
542
|
}
|
|
389
543
|
},
|
|
390
544
|
deleteFilter(t) {
|
|
391
545
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
392
546
|
return;
|
|
393
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
547
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
|
|
394
548
|
if (r !== -1) {
|
|
395
|
-
let
|
|
396
|
-
if (
|
|
397
|
-
let
|
|
398
|
-
|
|
549
|
+
let i = [...e.recommendationConfigs.filters];
|
|
550
|
+
if (i.splice(r, 1), i.some((n) => n.filterGroup === t.filterGroup)) {
|
|
551
|
+
let n = 1;
|
|
552
|
+
i = i.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: n++ } : o);
|
|
399
553
|
} else {
|
|
400
|
-
const
|
|
401
|
-
|
|
554
|
+
const n = [...new Set(i.map((s) => s.filterGroup))].sort((s, c) => s - c), o = new Map(n.map((s, c) => [s, c + 1]));
|
|
555
|
+
i = i.map((s) => ({
|
|
402
556
|
...s,
|
|
403
557
|
filterGroup: o.get(s.filterGroup) ?? s.filterGroup
|
|
404
558
|
}));
|
|
405
559
|
}
|
|
406
|
-
e.recommendationConfigs.filters =
|
|
560
|
+
e.recommendationConfigs.filters = i;
|
|
407
561
|
}
|
|
408
562
|
},
|
|
409
563
|
addFilter(t) {
|
|
410
564
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
411
565
|
return;
|
|
412
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters],
|
|
566
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], a = r.filter(
|
|
413
567
|
(o) => o.filterGroup === t.filterGroup
|
|
414
|
-
).length + 1,
|
|
415
|
-
|
|
568
|
+
).length + 1, n = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
569
|
+
n !== -1 ? r.splice(n + 1, 0, {
|
|
416
570
|
...t,
|
|
417
|
-
filterNumber:
|
|
571
|
+
filterNumber: a
|
|
418
572
|
}) : r.push({
|
|
419
573
|
...t,
|
|
420
|
-
filterNumber:
|
|
574
|
+
filterNumber: a
|
|
421
575
|
}), e.recommendationConfigs.filters = r;
|
|
422
576
|
},
|
|
423
577
|
generateFilterQuery() {
|
|
424
|
-
return
|
|
578
|
+
return R(this.recommendationConfigs.filters);
|
|
425
579
|
},
|
|
426
580
|
/**
|
|
427
581
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -429,28 +583,28 @@ const L = () => ({
|
|
|
429
583
|
* every block's recommendationConfigs across user edits.
|
|
430
584
|
*/
|
|
431
585
|
hasInvalidBlock() {
|
|
432
|
-
return Object.values(this.blockStates).some((t) => !
|
|
586
|
+
return Object.values(this.blockStates).some((t) => !A(t.recommendationConfigs, this));
|
|
433
587
|
},
|
|
434
588
|
// ====================================================================
|
|
435
589
|
// Per-Block Product Fetching
|
|
436
590
|
// ====================================================================
|
|
437
591
|
async fetchRecommendationProducts() {
|
|
438
592
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
439
|
-
if (
|
|
440
|
-
await
|
|
593
|
+
if (f) {
|
|
594
|
+
await f;
|
|
441
595
|
return;
|
|
442
596
|
}
|
|
443
|
-
|
|
597
|
+
f = this._doFetchProducts();
|
|
444
598
|
try {
|
|
445
|
-
await
|
|
599
|
+
await f;
|
|
446
600
|
} finally {
|
|
447
|
-
|
|
601
|
+
f = null;
|
|
448
602
|
}
|
|
449
603
|
}
|
|
450
604
|
},
|
|
451
605
|
async _doFetchProducts() {
|
|
452
|
-
var
|
|
453
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
606
|
+
var b;
|
|
607
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, i = r.filters.filter((l) => l.isValid), a = R(i), n = ((b = y().find((l) => l.key === r.strategy)) == null ? void 0 : b.path) || "", o = v(), s = parseInt(r.size) || 6, c = {
|
|
454
608
|
locale: r.language,
|
|
455
609
|
currency: r.currencySettings.value,
|
|
456
610
|
partnerName: o.partnerName,
|
|
@@ -458,26 +612,26 @@ const L = () => ({
|
|
|
458
612
|
details: !0,
|
|
459
613
|
campaignId: o.variationId
|
|
460
614
|
};
|
|
461
|
-
r.strategy === "manualMerchandising" ?
|
|
462
|
-
|
|
463
|
-
|
|
615
|
+
r.strategy === "manualMerchandising" ? c.productId = r.productIds.join(",") : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), a && (c.filter = a), r.shuffleProducts && (c.shuffle = !0), Object.assign(
|
|
616
|
+
c,
|
|
617
|
+
_(o.partnerName, r.strategy)
|
|
464
618
|
);
|
|
465
|
-
let
|
|
619
|
+
let h;
|
|
466
620
|
try {
|
|
467
|
-
|
|
621
|
+
h = await m.fetchRecommendationProducts(n, c);
|
|
468
622
|
} catch {
|
|
469
|
-
|
|
623
|
+
h = [];
|
|
470
624
|
}
|
|
471
625
|
if (this.blockStates[t]) {
|
|
472
|
-
const l =
|
|
626
|
+
const l = h.length > 0 ? h : I(s);
|
|
473
627
|
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
474
628
|
...l,
|
|
475
|
-
...
|
|
629
|
+
...I(s - l.length)
|
|
476
630
|
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
477
631
|
}
|
|
478
632
|
}
|
|
479
633
|
}
|
|
480
634
|
});
|
|
481
635
|
export {
|
|
482
|
-
|
|
636
|
+
Y as useRecommendationExtensionStore
|
|
483
637
|
};
|