@useinsider/guido 3.12.0-beta.00cbb4c → 3.12.0-beta.19da4fb
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 +9 -4
- package/dist/components/Guido.vue.js +8 -8
- package/dist/components/Guido.vue2.js +58 -56
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +38 -0
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +271 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue2.js +16 -0
- package/dist/components/organisms/extensions/recommendation/StrategyPicker.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/StrategyPicker.vue2.js +80 -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/components/organisms/header/ViewOptions.vue.js +3 -3
- package/dist/components/organisms/header/version-history/ViewOptions.vue.js +1 -1
- package/dist/composables/usePreviewInteractionGuard.js +36 -11
- package/dist/composables/useRecommendation.js +82 -51
- package/dist/composables/useRecommendationPreview.js +61 -60
- package/dist/composables/useStrategyFilters.js +16 -0
- package/dist/config/migrator/recommendationMigrator.js +7 -4
- package/dist/enums/date.js +4 -3
- package/dist/enums/extensions/filteringV2.js +1024 -0
- package/dist/enums/extensions/recommendationBlock.js +43 -29
- package/dist/enums/extensions/strategyDetail.js +148 -0
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +137 -119
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +57 -0
- package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +392 -112
- package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
- package/dist/extensions/Blocks/Recommendation/utils/strategyInfoBox.js +24 -0
- package/dist/extensions/Blocks/Recommendation/utils/strategyNavigation.js +8 -0
- package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +95 -0
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -10
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
- package/dist/extensions/Blocks/controlFactories.js +125 -75
- package/dist/guido.css +1 -1
- package/dist/node_modules/@vueuse/core/index.js +48 -0
- package/dist/node_modules/@vueuse/shared/index.js +57 -27
- package/dist/services/recommendationApi.js +86 -29
- package/dist/services/stripoApi.js +18 -18
- 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/StrategyInfoBox.vue.d.ts +26 -0
- package/dist/src/components/organisms/extensions/recommendation/StrategyPicker.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/usePreviewInteractionGuard.d.ts +1 -1
- 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 +21 -0
- package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +10 -4
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +16 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +894 -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/strategyInfoBox.d.ts +33 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyNavigation.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +8 -1
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
- package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
- package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
- package/dist/src/services/recommendationApi.d.ts +8 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/utils/genericUtil.d.ts +9 -0
- package/dist/src/utils/urlSchemes.d.ts +6 -0
- package/dist/static/styles/base.css.js +25 -0
- package/dist/static/styles/components/base-input.css.js +6 -7
- package/dist/utils/dateUtil.js +23 -10
- package/dist/utils/genericUtil.js +10 -1
- package/dist/utils/templatePreparation.js +70 -57
- package/dist/utils/urlSchemes.js +4 -0
- package/package.json +2 -2
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { useConfig as P } from "../../../../composables/useConfig.js";
|
|
2
|
+
import { useTranslations as u } from "../../../../composables/useTranslations.js";
|
|
3
|
+
import { getRecommendationFeedSourceMaps as C, getOperatorOptions as G, PriceAttributes as v } from "../../../../enums/extensions/recommendationBlock.js";
|
|
4
|
+
import { ToasterTypeOptions as f } from "../../../../enums/toaster.js";
|
|
5
|
+
import { useRecommendationApi as U } from "../../../../services/recommendationApi.js";
|
|
6
|
+
import { useConfigStore as L } from "../../../../stores/config.js";
|
|
7
|
+
import { useToasterStore as g } from "../../../../stores/toaster.js";
|
|
8
|
+
import { defineStore as T } from "pinia";
|
|
5
9
|
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
|
-
|
|
10
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as N, DEFAULT_CARDS_IN_ROW as x } from "../constants/layout.js";
|
|
11
|
+
import { EXCLUDED_ALGORITHM_IDS as B } from "../constants/defaultConfig.js";
|
|
12
|
+
import { getDefaultProducts as I } from "../templates/utils.js";
|
|
13
|
+
import { generateCompleteFilterQuery as w } from "../utils/filterUtil.js";
|
|
14
|
+
import { getPartnerRecommendationParams as _ } from "../utils/partnerCustomizations.js";
|
|
15
|
+
import { isFilterValid as V } from "../validation/filterSchema.js";
|
|
16
|
+
import { isConfigValid as O } from "../validation/requiredFields.js";
|
|
17
|
+
const m = U();
|
|
18
|
+
let h = null, p = null, S = null, d = null, k = 0;
|
|
19
|
+
const y = {};
|
|
20
|
+
function F() {
|
|
16
21
|
return {
|
|
17
|
-
cardsInRow:
|
|
22
|
+
cardsInRow: x,
|
|
18
23
|
currencySettings: {
|
|
19
24
|
name: "USD",
|
|
20
25
|
value: "USD",
|
|
@@ -28,13 +33,14 @@ function k() {
|
|
|
28
33
|
productIds: [],
|
|
29
34
|
id: 1,
|
|
30
35
|
language: "en_US",
|
|
31
|
-
mobileCardsInRow:
|
|
36
|
+
mobileCardsInRow: N,
|
|
32
37
|
mobileLayoutEnabled: !1,
|
|
33
38
|
orientation: "grid",
|
|
34
39
|
recommendedProducts: [],
|
|
35
40
|
sendProductRequestFlag: !1,
|
|
36
41
|
shuffleProducts: !1,
|
|
37
42
|
strategy: "mostPopular",
|
|
43
|
+
strategyId: "",
|
|
38
44
|
textTrimming: !0,
|
|
39
45
|
unresponsive: !1,
|
|
40
46
|
size: "6",
|
|
@@ -43,28 +49,38 @@ function k() {
|
|
|
43
49
|
priceHideIfSameAsDiscounted: !1
|
|
44
50
|
};
|
|
45
51
|
}
|
|
46
|
-
function
|
|
52
|
+
function D() {
|
|
47
53
|
return {
|
|
48
|
-
recommendationConfigs:
|
|
54
|
+
recommendationConfigs: F(),
|
|
49
55
|
recommendationProducts: [],
|
|
50
56
|
filterStatus: !1,
|
|
51
57
|
filterSelectionDrawerStatus: !1,
|
|
58
|
+
strategyDetailDrawerStatus: !1,
|
|
52
59
|
filterGroup: 1,
|
|
53
60
|
isInitialized: !1,
|
|
54
61
|
filterSnapshot: null
|
|
55
62
|
};
|
|
56
63
|
}
|
|
57
|
-
const
|
|
64
|
+
const A = () => ({
|
|
58
65
|
recommendationCampaignUrls: {},
|
|
59
66
|
activePredictiveAlgorithms: [],
|
|
60
67
|
languages: {},
|
|
61
68
|
currencyList: [],
|
|
62
69
|
filterList: {},
|
|
70
|
+
strategies: [],
|
|
71
|
+
strategiesLoading: !1,
|
|
72
|
+
strategyCampaigns: [],
|
|
73
|
+
strategyCampaignsLoading: !1,
|
|
74
|
+
strategyCampaignsFetchedFor: null,
|
|
75
|
+
strategyUrlTemplates: {},
|
|
76
|
+
strategyPickerVisible: !1,
|
|
77
|
+
strategyPickerVersion: 0,
|
|
78
|
+
strategyDuplicating: !1,
|
|
63
79
|
blockStates: {},
|
|
64
80
|
currentRecommendationId: null,
|
|
65
81
|
configVersion: 0
|
|
66
|
-
}),
|
|
67
|
-
state: () =>
|
|
82
|
+
}), rt = T("guidoRecommendationExtension", {
|
|
83
|
+
state: () => A(),
|
|
68
84
|
getters: {
|
|
69
85
|
// ====================================================================
|
|
70
86
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -74,7 +90,7 @@ const L = () => ({
|
|
|
74
90
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
75
91
|
*/
|
|
76
92
|
recommendationConfigs(t) {
|
|
77
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
93
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : F();
|
|
78
94
|
},
|
|
79
95
|
/**
|
|
80
96
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -88,6 +104,12 @@ const L = () => ({
|
|
|
88
104
|
filterSelectionDrawerStatus(t) {
|
|
89
105
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
90
106
|
},
|
|
107
|
+
/**
|
|
108
|
+
* Proxy getter: delegates to blockStates[currentRecommendationId].strategyDetailDrawerStatus
|
|
109
|
+
*/
|
|
110
|
+
strategyDetailDrawerStatus(t) {
|
|
111
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].strategyDetailDrawerStatus : !1;
|
|
112
|
+
},
|
|
91
113
|
/**
|
|
92
114
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
93
115
|
*/
|
|
@@ -119,14 +141,62 @@ const L = () => ({
|
|
|
119
141
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
120
142
|
},
|
|
121
143
|
getActivePredictiveAlgorithms: (t) => {
|
|
122
|
-
const e =
|
|
123
|
-
return t.activePredictiveAlgorithms.filter((
|
|
124
|
-
r.push(...e.filter((
|
|
125
|
-
}), r.map((
|
|
126
|
-
text:
|
|
127
|
-
value:
|
|
144
|
+
const e = C(), r = [];
|
|
145
|
+
return t.activePredictiveAlgorithms.filter((i) => !B.includes(i)).forEach((i) => {
|
|
146
|
+
r.push(...e.filter((a) => a.id === i));
|
|
147
|
+
}), r.map((i) => ({
|
|
148
|
+
text: i.name,
|
|
149
|
+
value: i.key
|
|
128
150
|
}));
|
|
129
151
|
},
|
|
152
|
+
/**
|
|
153
|
+
* Reusable Recommendation Strategies as dropdown options.
|
|
154
|
+
*
|
|
155
|
+
* Unlike algorithms, strategy ids come straight from Smart Recommender —
|
|
156
|
+
* there is no local id→key table to join against.
|
|
157
|
+
*/
|
|
158
|
+
getStrategyOptions: (t) => t.strategies.map((e) => ({
|
|
159
|
+
text: e.name,
|
|
160
|
+
value: String(e.strategy_id)
|
|
161
|
+
})),
|
|
162
|
+
/**
|
|
163
|
+
* The current block's selected strategy, or null when none is selected
|
|
164
|
+
* or the selected id is no longer in the listing.
|
|
165
|
+
*
|
|
166
|
+
* A null return with a non-empty `strategyId` means the strategy was
|
|
167
|
+
* deleted in Smart Recommender after this block was configured — the
|
|
168
|
+
* panel flags that rather than silently clearing the selection.
|
|
169
|
+
*/
|
|
170
|
+
getSelectedStrategy() {
|
|
171
|
+
const { strategyId: t } = this.recommendationConfigs;
|
|
172
|
+
return t ? this.strategies.find((e) => String(e.strategy_id) === t) ?? null : null;
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* Whether the RRS feature is enabled for this editor.
|
|
176
|
+
*
|
|
177
|
+
* Read through a getter so `hasInvalidBlock` can pass the store straight to
|
|
178
|
+
* the required-field descriptors, which need the flag to decide whether a
|
|
179
|
+
* missing strategy blocks the save.
|
|
180
|
+
*/
|
|
181
|
+
isRrsEnabled() {
|
|
182
|
+
return P().isFeatureEnabled("reusableRecommendationStrategy");
|
|
183
|
+
},
|
|
184
|
+
/** Strategy ids currently offered for email, for the save-time deleted-strategy check. */
|
|
185
|
+
strategyIds: (t) => t.strategies.map((e) => String(e.strategy_id)),
|
|
186
|
+
/**
|
|
187
|
+
* Whether the listing is trustworthy enough to judge an assigned id against.
|
|
188
|
+
* Mid-fetch it is empty, and every assigned id would look deleted.
|
|
189
|
+
*/
|
|
190
|
+
canValidateStrategy: (t) => !t.strategiesLoading && t.strategies.length > 0,
|
|
191
|
+
/**
|
|
192
|
+
* True when a strategy id is set but absent from the fetched listing.
|
|
193
|
+
*
|
|
194
|
+
* Guarded on the listing having loaded — mid-fetch every id looks missing.
|
|
195
|
+
*/
|
|
196
|
+
hasMissingStrategy() {
|
|
197
|
+
const { strategyId: t } = this.recommendationConfigs;
|
|
198
|
+
return !t || this.strategiesLoading || !this.strategies.length ? !1 : this.getSelectedStrategy === null;
|
|
199
|
+
},
|
|
130
200
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
131
201
|
text: r,
|
|
132
202
|
value: e
|
|
@@ -138,7 +208,7 @@ const L = () => ({
|
|
|
138
208
|
getFilterList() {
|
|
139
209
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
140
210
|
let e;
|
|
141
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
211
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
142
212
|
text: t.displayName,
|
|
143
213
|
value: e,
|
|
144
214
|
type: t.attributeType
|
|
@@ -160,7 +230,7 @@ const L = () => ({
|
|
|
160
230
|
setCurrentBlock(t) {
|
|
161
231
|
this.blockStates[t] || (this.blockStates = {
|
|
162
232
|
...this.blockStates,
|
|
163
|
-
[t]:
|
|
233
|
+
[t]: D()
|
|
164
234
|
}), this.currentRecommendationId = t;
|
|
165
235
|
},
|
|
166
236
|
/**
|
|
@@ -170,13 +240,13 @@ const L = () => ({
|
|
|
170
240
|
removeBlockState(t) {
|
|
171
241
|
const e = t.toString();
|
|
172
242
|
if (this.recommendationCampaignUrls[e]) {
|
|
173
|
-
const
|
|
174
|
-
delete
|
|
243
|
+
const i = { ...this.recommendationCampaignUrls };
|
|
244
|
+
delete i[e], this.recommendationCampaignUrls = i;
|
|
175
245
|
}
|
|
176
246
|
const r = { ...this.blockStates };
|
|
177
247
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
178
|
-
const
|
|
179
|
-
this.currentRecommendationId =
|
|
248
|
+
const i = Object.keys(this.blockStates).map(Number);
|
|
249
|
+
this.currentRecommendationId = i.length > 0 ? i[0] : null;
|
|
180
250
|
}
|
|
181
251
|
},
|
|
182
252
|
/**
|
|
@@ -186,16 +256,16 @@ const L = () => ({
|
|
|
186
256
|
cloneBlockState(t, e) {
|
|
187
257
|
const r = this.blockStates[t];
|
|
188
258
|
if (r) {
|
|
189
|
-
const
|
|
190
|
-
|
|
259
|
+
const s = structuredClone(r);
|
|
260
|
+
s.recommendationConfigs.id = e, this.blockStates = {
|
|
191
261
|
...this.blockStates,
|
|
192
|
-
[e]:
|
|
262
|
+
[e]: s
|
|
193
263
|
};
|
|
194
264
|
}
|
|
195
|
-
const
|
|
196
|
-
|
|
265
|
+
const i = t.toString(), a = e.toString(), n = this.recommendationCampaignUrls[i];
|
|
266
|
+
n && (this.recommendationCampaignUrls = {
|
|
197
267
|
...this.recommendationCampaignUrls,
|
|
198
|
-
[
|
|
268
|
+
[a]: n
|
|
199
269
|
});
|
|
200
270
|
},
|
|
201
271
|
/**
|
|
@@ -220,7 +290,7 @@ const L = () => ({
|
|
|
220
290
|
* `isInitialized`) alone.
|
|
221
291
|
*/
|
|
222
292
|
seedBlockUrlConfig(t, e) {
|
|
223
|
-
const r = (
|
|
293
|
+
const r = (s, o) => s === "." || s === "," || s === " " ? s : o, i = {
|
|
224
294
|
name: e.currencyCode,
|
|
225
295
|
value: e.currencyCode,
|
|
226
296
|
symbol: e.currencyCode,
|
|
@@ -228,19 +298,20 @@ const L = () => ({
|
|
|
228
298
|
decimalCount: String(e.currencyDecimalCount),
|
|
229
299
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
230
300
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
...
|
|
301
|
+
}, a = !this.blockStates[t], n = a ? D() : this.blockStates[t];
|
|
302
|
+
n.recommendationConfigs = {
|
|
303
|
+
...n.recommendationConfigs,
|
|
234
304
|
strategy: e.strategy,
|
|
305
|
+
strategyId: e.strategyId,
|
|
235
306
|
language: e.language,
|
|
236
307
|
size: e.size,
|
|
237
308
|
productIds: e.productIds,
|
|
238
309
|
filters: e.filters,
|
|
239
310
|
shuffleProducts: e.shuffleProducts,
|
|
240
|
-
currencySettings:
|
|
241
|
-
},
|
|
311
|
+
currencySettings: i
|
|
312
|
+
}, a && (this.blockStates = {
|
|
242
313
|
...this.blockStates,
|
|
243
|
-
[t]:
|
|
314
|
+
[t]: n
|
|
244
315
|
});
|
|
245
316
|
},
|
|
246
317
|
/**
|
|
@@ -259,18 +330,18 @@ const L = () => ({
|
|
|
259
330
|
...t.currencySettings || {}
|
|
260
331
|
}
|
|
261
332
|
};
|
|
262
|
-
const { triggerRefetch:
|
|
263
|
-
|
|
333
|
+
const { triggerRefetch: i = !0 } = e;
|
|
334
|
+
i && this.configVersion++;
|
|
264
335
|
},
|
|
265
336
|
/**
|
|
266
337
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
267
338
|
*/
|
|
268
339
|
createDefaultFilter(t, e) {
|
|
269
|
-
const [r] = this.getFilterList, [
|
|
340
|
+
const [r] = this.getFilterList, [i] = G(r == null ? void 0 : r.type);
|
|
270
341
|
return {
|
|
271
342
|
type: "standardFilter",
|
|
272
343
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
273
|
-
operator: (
|
|
344
|
+
operator: (i == null ? void 0 : i.value) ?? "",
|
|
274
345
|
innerGroupOperator: "*",
|
|
275
346
|
outerGroupOperator: "*",
|
|
276
347
|
filterNumber: e,
|
|
@@ -303,6 +374,176 @@ const L = () => ({
|
|
|
303
374
|
const t = this.blockStates[this.currentRecommendationId];
|
|
304
375
|
t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
|
|
305
376
|
},
|
|
377
|
+
/** The strategy control mounted (or re-rendered): let the overlay re-attach. */
|
|
378
|
+
showStrategyPicker() {
|
|
379
|
+
this.strategyPickerVisible = !0, this.strategyPickerVersion += 1;
|
|
380
|
+
},
|
|
381
|
+
/** The strategy control went away — hide the overlay with it. */
|
|
382
|
+
hideStrategyPicker() {
|
|
383
|
+
this.strategyPickerVisible = !1;
|
|
384
|
+
},
|
|
385
|
+
/**
|
|
386
|
+
* Assign a strategy to the current block.
|
|
387
|
+
*
|
|
388
|
+
* Only patches Pinia: the `configVersion` bump makes the main control persist
|
|
389
|
+
* `strategyId` into the block's node config (see `_persistStoreConfigToNode`),
|
|
390
|
+
* which is the same route filters take. Resolving the URL template here rather
|
|
391
|
+
* than at compile time matters — `buildCampaignUrl` is synchronous and would
|
|
392
|
+
* otherwise silently fall back to the algorithm URL.
|
|
393
|
+
*/
|
|
394
|
+
async selectStrategy(t) {
|
|
395
|
+
if (this.recommendationConfigs.strategyId === t)
|
|
396
|
+
return;
|
|
397
|
+
this.patchCurrentBlockConfig({ strategyId: t }, { triggerRefetch: !0 });
|
|
398
|
+
const e = await this.fetchStrategyUrlTemplate(t), r = this.strategies.find((i) => String(i.strategy_id) === t);
|
|
399
|
+
if (!e) {
|
|
400
|
+
g().showToaster({
|
|
401
|
+
type: f.Error,
|
|
402
|
+
message: u()("discovery-strategy.error-description")
|
|
403
|
+
});
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
g().showToaster({
|
|
407
|
+
type: f.Success,
|
|
408
|
+
message: u()("campaign-builder.variation-strategy-assign", {
|
|
409
|
+
strategyName: (r == null ? void 0 : r.name) ?? t
|
|
410
|
+
})
|
|
411
|
+
});
|
|
412
|
+
},
|
|
413
|
+
/**
|
|
414
|
+
* Duplicate the selected strategy and assign the copy to this block.
|
|
415
|
+
*
|
|
416
|
+
* Runs inline — the marketer never leaves the editor. Two things the web flow
|
|
417
|
+
* does that we deliberately skip: its follow-up `POST /{id}/assign` (that binds
|
|
418
|
+
* a strategy to a campaign *variation*, a concept email blocks do not have —
|
|
419
|
+
* here the assignment is the block's own config), and displaying the copy's
|
|
420
|
+
* name from the response, which only carries the new id. Hence the refetch.
|
|
421
|
+
*/
|
|
422
|
+
async duplicateAndAssignStrategy() {
|
|
423
|
+
const t = this.getSelectedStrategy;
|
|
424
|
+
if (!(!t || this.strategyDuplicating)) {
|
|
425
|
+
this.strategyDuplicating = !0;
|
|
426
|
+
try {
|
|
427
|
+
const e = await m.duplicateStrategy(String(t.strategy_id));
|
|
428
|
+
if (!e) {
|
|
429
|
+
g().showToaster({
|
|
430
|
+
type: f.Error,
|
|
431
|
+
message: u()("discovery-strategy.error-description")
|
|
432
|
+
});
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
await this.refreshRecommendationStrategies(), this.patchCurrentBlockConfig({ strategyId: e }, { triggerRefetch: !0 });
|
|
436
|
+
const r = await this.fetchStrategyUrlTemplate(e);
|
|
437
|
+
if (this.closeStrategyDrawer(), !r) {
|
|
438
|
+
g().showToaster({
|
|
439
|
+
type: f.Error,
|
|
440
|
+
message: u()("discovery-strategy.error-description")
|
|
441
|
+
});
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
g().showToaster({
|
|
445
|
+
type: f.Success,
|
|
446
|
+
message: u()("recommendation-strategies.duplicate-and-assign-text", {
|
|
447
|
+
strategyName: t.name
|
|
448
|
+
})
|
|
449
|
+
});
|
|
450
|
+
} finally {
|
|
451
|
+
this.strategyDuplicating = !1;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
/**
|
|
456
|
+
* Opens the RRS detail drawer for the current block.
|
|
457
|
+
*
|
|
458
|
+
* Unlike the filter drawer this takes no snapshot — the drawer is
|
|
459
|
+
* read-only, so there is nothing to revert on close.
|
|
460
|
+
*/
|
|
461
|
+
openStrategyDrawer() {
|
|
462
|
+
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !0);
|
|
463
|
+
},
|
|
464
|
+
/**
|
|
465
|
+
* Closes the RRS detail drawer for the current block and drops the campaign
|
|
466
|
+
* list, so reopening on a different strategy never flashes stale rows.
|
|
467
|
+
*/
|
|
468
|
+
closeStrategyDrawer() {
|
|
469
|
+
this.clearStrategyCampaigns(), !(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId]) && (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !1);
|
|
470
|
+
},
|
|
471
|
+
/** Drops the campaign list and lets the next open refetch. */
|
|
472
|
+
clearStrategyCampaigns() {
|
|
473
|
+
this.strategyCampaigns = [], this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = null, k += 1;
|
|
474
|
+
},
|
|
475
|
+
/**
|
|
476
|
+
* Resolve and cache a strategy's recommendation-URL template.
|
|
477
|
+
*
|
|
478
|
+
* Must be awaited before `buildCampaignUrl` runs for a strategy-driven block,
|
|
479
|
+
* because that builder is synchronous and can only read what is already
|
|
480
|
+
* cached. Safe to call repeatedly: a resolved id short-circuits, and
|
|
481
|
+
* concurrent callers for the same id share one request.
|
|
482
|
+
*
|
|
483
|
+
* Only a *settled* answer is cached. An id the server rejects caches as '',
|
|
484
|
+
* so the block falls back instead of retrying on every compile. A request
|
|
485
|
+
* that merely failed to complete leaves the key unset and resolves to false,
|
|
486
|
+
* so the next selection or save tries again — caching a network blip as "no
|
|
487
|
+
* URL" would strand the block on its old algorithm feed for the session while
|
|
488
|
+
* the panel still showed the strategy as assigned.
|
|
489
|
+
* @returns whether the strategy now has a USABLE url — not merely a cache
|
|
490
|
+
* entry. A rejected id caches as '' to stop the retry storm, but reporting
|
|
491
|
+
* that as success would let the caller confirm an assignment the compiled
|
|
492
|
+
* email cannot honour.
|
|
493
|
+
*/
|
|
494
|
+
async fetchStrategyUrlTemplate(t) {
|
|
495
|
+
if (!t)
|
|
496
|
+
return !1;
|
|
497
|
+
if (t in this.strategyUrlTemplates)
|
|
498
|
+
return !!this.strategyUrlTemplates[t];
|
|
499
|
+
const e = y[t];
|
|
500
|
+
if (e)
|
|
501
|
+
return await e, !!this.strategyUrlTemplates[t];
|
|
502
|
+
y[t] = (async () => {
|
|
503
|
+
try {
|
|
504
|
+
const r = await m.fetchStrategyRecommendationUrl(t);
|
|
505
|
+
this.strategyUrlTemplates = {
|
|
506
|
+
...this.strategyUrlTemplates,
|
|
507
|
+
[t]: (r == null ? void 0 : r.full_path) ?? ""
|
|
508
|
+
};
|
|
509
|
+
} catch (r) {
|
|
510
|
+
console.error("fetchStrategyUrlTemplate error:", r);
|
|
511
|
+
}
|
|
512
|
+
})();
|
|
513
|
+
try {
|
|
514
|
+
await y[t];
|
|
515
|
+
} finally {
|
|
516
|
+
delete y[t];
|
|
517
|
+
}
|
|
518
|
+
return !!this.strategyUrlTemplates[t];
|
|
519
|
+
},
|
|
520
|
+
/**
|
|
521
|
+
* Wait for every strategy-URL request still in flight.
|
|
522
|
+
*
|
|
523
|
+
* The compiler is synchronous: whatever is not cached by the time it runs
|
|
524
|
+
* compiles as the block's old algorithm URL. Selection and template hydrate
|
|
525
|
+
* both await their own request, but a save fired inside that round trip would
|
|
526
|
+
* still race — so the save path drains the queue first.
|
|
527
|
+
*/
|
|
528
|
+
async awaitPendingStrategyUrls() {
|
|
529
|
+
await Promise.all(Object.values(y).filter(Boolean));
|
|
530
|
+
},
|
|
531
|
+
/**
|
|
532
|
+
* Fetch the campaigns a strategy is used in, for the drawer's second tab.
|
|
533
|
+
*
|
|
534
|
+
* Lazy and once-per-strategy: the caller invokes this only while the drawer is
|
|
535
|
+
* open on that tab, and a repeat call for the same id is a no-op. A version
|
|
536
|
+
* counter discards a response that arrives after the user switched strategies,
|
|
537
|
+
* which would otherwise show one strategy's campaigns under another's name.
|
|
538
|
+
*/
|
|
539
|
+
async fetchStrategyCampaigns(t) {
|
|
540
|
+
if (!t || this.strategyCampaignsFetchedFor === t)
|
|
541
|
+
return;
|
|
542
|
+
const e = ++k;
|
|
543
|
+
this.strategyCampaignsLoading = !0;
|
|
544
|
+
const r = await m.fetchStrategyCampaigns(t, u());
|
|
545
|
+
e === k && (this.strategyCampaigns = r, this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = t);
|
|
546
|
+
},
|
|
306
547
|
/**
|
|
307
548
|
* Cancels the filter selection drawer and reverts filters
|
|
308
549
|
* to the snapshot taken when the drawer was opened.
|
|
@@ -318,43 +559,82 @@ const L = () => ({
|
|
|
318
559
|
// ====================================================================
|
|
319
560
|
async fetchRecommendationCreateData() {
|
|
320
561
|
if (!this.activePredictiveAlgorithms.length) {
|
|
321
|
-
if (
|
|
322
|
-
await
|
|
562
|
+
if (h) {
|
|
563
|
+
await h;
|
|
323
564
|
return;
|
|
324
565
|
}
|
|
325
|
-
|
|
566
|
+
h = (async () => {
|
|
326
567
|
const {
|
|
327
568
|
activePredictiveAlgorithms: t,
|
|
328
569
|
languages: e,
|
|
329
570
|
currencies: r
|
|
330
|
-
} = await
|
|
571
|
+
} = await m.fetchRecommendationCreateData();
|
|
331
572
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
332
|
-
const
|
|
333
|
-
|
|
573
|
+
const i = this.blockStates[this.currentRecommendationId];
|
|
574
|
+
i.filterStatus = !!i.recommendationConfigs.filters.length;
|
|
334
575
|
}
|
|
335
576
|
this.currencyList = r;
|
|
336
577
|
})();
|
|
337
578
|
try {
|
|
338
|
-
await
|
|
579
|
+
await h;
|
|
339
580
|
} finally {
|
|
340
|
-
|
|
581
|
+
h = null;
|
|
341
582
|
}
|
|
342
583
|
}
|
|
343
584
|
},
|
|
585
|
+
/**
|
|
586
|
+
* Fetch the partner's Reusable Recommendation Strategies for the EMAIL channel.
|
|
587
|
+
*
|
|
588
|
+
* Same cache-guard + in-flight dedupe shape as fetchRecommendationCreateData.
|
|
589
|
+
* A failure leaves `strategies` empty so the dropdown renders empty rather
|
|
590
|
+
* than blocking the panel — the block keeps working on its algorithm.
|
|
591
|
+
*/
|
|
592
|
+
async fetchRecommendationStrategies() {
|
|
593
|
+
if (!this.strategies.length) {
|
|
594
|
+
if (d) {
|
|
595
|
+
await d;
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
this.strategiesLoading = !0, d = (async () => {
|
|
599
|
+
try {
|
|
600
|
+
this.strategies = await m.fetchRecommendationStrategies();
|
|
601
|
+
} catch {
|
|
602
|
+
this.strategies = [];
|
|
603
|
+
} finally {
|
|
604
|
+
this.strategiesLoading = !1;
|
|
605
|
+
}
|
|
606
|
+
})();
|
|
607
|
+
try {
|
|
608
|
+
await d;
|
|
609
|
+
} finally {
|
|
610
|
+
d = null;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
/**
|
|
615
|
+
* Refetch the listing, ignoring the once-per-session cache.
|
|
616
|
+
*
|
|
617
|
+
* Needed after Duplicate and Assign: the copy exists server-side but not in
|
|
618
|
+
* `strategies`, so without this the panel would read the freshly assigned id
|
|
619
|
+
* back as a deleted strategy.
|
|
620
|
+
*/
|
|
621
|
+
async refreshRecommendationStrategies() {
|
|
622
|
+
this.strategies = [], d = null, await this.fetchRecommendationStrategies();
|
|
623
|
+
},
|
|
344
624
|
async fetchRecommendationFilters() {
|
|
345
625
|
if (!Object.keys(this.filterList).length) {
|
|
346
|
-
if (
|
|
347
|
-
await
|
|
626
|
+
if (p) {
|
|
627
|
+
await p;
|
|
348
628
|
return;
|
|
349
629
|
}
|
|
350
|
-
|
|
351
|
-
const t = await
|
|
630
|
+
p = (async () => {
|
|
631
|
+
const t = await m.fetchRecommendationFilters();
|
|
352
632
|
this.filterList = t;
|
|
353
633
|
})();
|
|
354
634
|
try {
|
|
355
|
-
await
|
|
635
|
+
await p;
|
|
356
636
|
} finally {
|
|
357
|
-
|
|
637
|
+
p = null;
|
|
358
638
|
}
|
|
359
639
|
}
|
|
360
640
|
},
|
|
@@ -369,59 +649,59 @@ const L = () => ({
|
|
|
369
649
|
deleteFilterGroup(t) {
|
|
370
650
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
371
651
|
return;
|
|
372
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
373
|
-
e.recommendationConfigs.filters = r.map((
|
|
374
|
-
...
|
|
375
|
-
filterGroup:
|
|
652
|
+
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, s) => n - s), a = new Map(i.map((n, s) => [n, s + 1]));
|
|
653
|
+
e.recommendationConfigs.filters = r.map((n) => ({
|
|
654
|
+
...n,
|
|
655
|
+
filterGroup: a.get(n.filterGroup) ?? n.filterGroup
|
|
376
656
|
}));
|
|
377
657
|
},
|
|
378
658
|
updateFilter(t) {
|
|
379
659
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
380
660
|
return;
|
|
381
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
661
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
|
|
382
662
|
if (r !== -1) {
|
|
383
|
-
const
|
|
384
|
-
|
|
663
|
+
const i = [...e.recommendationConfigs.filters];
|
|
664
|
+
i[r] = {
|
|
385
665
|
...t,
|
|
386
|
-
isValid:
|
|
387
|
-
}, e.recommendationConfigs.filters =
|
|
666
|
+
isValid: V(t)
|
|
667
|
+
}, e.recommendationConfigs.filters = i;
|
|
388
668
|
}
|
|
389
669
|
},
|
|
390
670
|
deleteFilter(t) {
|
|
391
671
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
392
672
|
return;
|
|
393
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
673
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
|
|
394
674
|
if (r !== -1) {
|
|
395
|
-
let
|
|
396
|
-
if (
|
|
397
|
-
let
|
|
398
|
-
|
|
675
|
+
let i = [...e.recommendationConfigs.filters];
|
|
676
|
+
if (i.splice(r, 1), i.some((n) => n.filterGroup === t.filterGroup)) {
|
|
677
|
+
let n = 1;
|
|
678
|
+
i = i.map((s) => s.filterGroup === t.filterGroup ? { ...s, filterNumber: n++ } : s);
|
|
399
679
|
} else {
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
...
|
|
403
|
-
filterGroup:
|
|
680
|
+
const n = [...new Set(i.map((o) => o.filterGroup))].sort((o, c) => o - c), s = new Map(n.map((o, c) => [o, c + 1]));
|
|
681
|
+
i = i.map((o) => ({
|
|
682
|
+
...o,
|
|
683
|
+
filterGroup: s.get(o.filterGroup) ?? o.filterGroup
|
|
404
684
|
}));
|
|
405
685
|
}
|
|
406
|
-
e.recommendationConfigs.filters =
|
|
686
|
+
e.recommendationConfigs.filters = i;
|
|
407
687
|
}
|
|
408
688
|
},
|
|
409
689
|
addFilter(t) {
|
|
410
690
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
411
691
|
return;
|
|
412
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters],
|
|
413
|
-
(
|
|
414
|
-
).length + 1,
|
|
415
|
-
|
|
692
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], a = r.filter(
|
|
693
|
+
(s) => s.filterGroup === t.filterGroup
|
|
694
|
+
).length + 1, n = r.findLastIndex((s) => s.filterGroup === t.filterGroup);
|
|
695
|
+
n !== -1 ? r.splice(n + 1, 0, {
|
|
416
696
|
...t,
|
|
417
|
-
filterNumber:
|
|
697
|
+
filterNumber: a
|
|
418
698
|
}) : r.push({
|
|
419
699
|
...t,
|
|
420
|
-
filterNumber:
|
|
700
|
+
filterNumber: a
|
|
421
701
|
}), e.recommendationConfigs.filters = r;
|
|
422
702
|
},
|
|
423
703
|
generateFilterQuery() {
|
|
424
|
-
return
|
|
704
|
+
return w(this.recommendationConfigs.filters);
|
|
425
705
|
},
|
|
426
706
|
/**
|
|
427
707
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -429,55 +709,55 @@ const L = () => ({
|
|
|
429
709
|
* every block's recommendationConfigs across user edits.
|
|
430
710
|
*/
|
|
431
711
|
hasInvalidBlock() {
|
|
432
|
-
return Object.values(this.blockStates).some((t) => !
|
|
712
|
+
return Object.values(this.blockStates).some((t) => !O(t.recommendationConfigs, this));
|
|
433
713
|
},
|
|
434
714
|
// ====================================================================
|
|
435
715
|
// Per-Block Product Fetching
|
|
436
716
|
// ====================================================================
|
|
437
717
|
async fetchRecommendationProducts() {
|
|
438
718
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
439
|
-
if (
|
|
440
|
-
await
|
|
719
|
+
if (S) {
|
|
720
|
+
await S;
|
|
441
721
|
return;
|
|
442
722
|
}
|
|
443
|
-
|
|
723
|
+
S = this._doFetchProducts();
|
|
444
724
|
try {
|
|
445
|
-
await
|
|
725
|
+
await S;
|
|
446
726
|
} finally {
|
|
447
|
-
|
|
727
|
+
S = null;
|
|
448
728
|
}
|
|
449
729
|
}
|
|
450
730
|
},
|
|
451
731
|
async _doFetchProducts() {
|
|
452
|
-
var
|
|
453
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
732
|
+
var R;
|
|
733
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, i = r.filters.filter((l) => l.isValid), a = w(i), n = ((R = C().find((l) => l.key === r.strategy)) == null ? void 0 : R.path) || "", s = L(), o = parseInt(r.size) || 6, c = {
|
|
454
734
|
locale: r.language,
|
|
455
735
|
currency: r.currencySettings.value,
|
|
456
|
-
partnerName:
|
|
736
|
+
partnerName: s.partnerName,
|
|
457
737
|
size: r.size,
|
|
458
738
|
details: !0,
|
|
459
|
-
campaignId:
|
|
739
|
+
campaignId: s.variationId
|
|
460
740
|
};
|
|
461
|
-
r.strategy === "manualMerchandising" ?
|
|
462
|
-
|
|
463
|
-
|
|
741
|
+
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(
|
|
742
|
+
c,
|
|
743
|
+
_(s.partnerName, r.strategy)
|
|
464
744
|
);
|
|
465
|
-
let
|
|
745
|
+
let b;
|
|
466
746
|
try {
|
|
467
|
-
|
|
747
|
+
b = await m.fetchRecommendationProducts(n, c);
|
|
468
748
|
} catch {
|
|
469
|
-
|
|
749
|
+
b = [];
|
|
470
750
|
}
|
|
471
751
|
if (this.blockStates[t]) {
|
|
472
|
-
const l =
|
|
473
|
-
l.length <
|
|
752
|
+
const l = b.length > 0 ? b : I(o);
|
|
753
|
+
l.length < o ? this.blockStates[t].recommendationProducts = [
|
|
474
754
|
...l,
|
|
475
|
-
...
|
|
476
|
-
] : l.length >
|
|
755
|
+
...I(o - l.length)
|
|
756
|
+
] : l.length > o ? this.blockStates[t].recommendationProducts = l.slice(0, o) : this.blockStates[t].recommendationProducts = l;
|
|
477
757
|
}
|
|
478
758
|
}
|
|
479
759
|
}
|
|
480
760
|
});
|
|
481
761
|
export {
|
|
482
|
-
|
|
762
|
+
rt as useRecommendationExtensionStore
|
|
483
763
|
};
|