@useinsider/guido 3.12.0-beta.b73c720 → 3.12.0-beta.bec0e55
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 +8 -13
- package/dist/components/Guido.vue.js +6 -6
- package/dist/components/Guido.vue2.js +49 -50
- 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/composables/usePreviewInteractionGuard.js +36 -11
- package/dist/composables/useRecommendation.js +51 -82
- package/dist/composables/useRecommendationPreview.js +61 -60
- package/dist/config/migrator/recommendationMigrator.js +4 -7
- package/dist/enums/date.js +3 -4
- package/dist/enums/extensions/recommendationBlock.js +22 -28
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +11 -12
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +109 -123
- package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +1 -1
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +102 -256
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -24
- 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/services/recommendationApi.js +27 -65
- package/dist/src/@types/config/schemas.d.ts +0 -10
- package/dist/src/composables/useConfig.d.ts +0 -2
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
- package/dist/src/composables/useRecommendation.d.ts +0 -2
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -10
- 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 +1 -3
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -606
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -7
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +1 -3
- 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/services/recommendationApi.d.ts +1 -7
- package/dist/src/stores/config.d.ts +0 -18
- package/dist/src/utils/genericUtil.d.ts +0 -9
- package/dist/src/utils/urlSchemes.d.ts +6 -0
- package/dist/static/styles/base.css.js +0 -15
- package/dist/utils/dateUtil.js +10 -23
- package/dist/utils/genericUtil.js +1 -10
- package/dist/utils/templatePreparation.js +58 -62
- package/dist/utils/urlSchemes.js +4 -0
- package/package.json +1 -1
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +0 -36
- package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +0 -244
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +0 -18
- package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +0 -42
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +0 -20
- package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +0 -18
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +0 -20
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +0 -60
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +0 -19
- package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +0 -19
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +0 -22
- package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +0 -29
- package/dist/composables/useStrategyFilters.js +0 -16
- package/dist/enums/extensions/filteringV2.js +0 -8
- package/dist/enums/extensions/strategyDetail.js +0 -148
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -146
- package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +0 -97
- package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +0 -10
- package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +0 -2
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +0 -43
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +0 -29
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +0 -40
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +0 -38
- package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +0 -51
- package/dist/src/composables/useStrategyFilters.d.ts +0 -24
- package/dist/src/enums/extensions/filteringV2.d.ts +0 -72
- package/dist/src/enums/extensions/strategyDetail.d.ts +0 -90
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -61
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +0 -50
- package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +0 -34
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useConfigStore as v } from "../../../../stores/config.js";
|
|
6
|
-
import { defineStore as L } from "pinia";
|
|
1
|
+
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as F } from "pinia";
|
|
7
5
|
import "../constants/selectors.js";
|
|
8
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
9
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
10
|
-
import { getDefaultProducts as
|
|
11
|
-
import { generateCompleteFilterQuery as
|
|
12
|
-
import { getPartnerRecommendationParams as
|
|
13
|
-
import { isFilterValid as
|
|
14
|
-
import { isConfigValid as
|
|
15
|
-
const
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
function C() {
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as P, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
|
|
7
|
+
import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
|
|
8
|
+
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
9
|
+
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
10
|
+
import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
|
|
11
|
+
import { isFilterValid as N } from "../validation/filterSchema.js";
|
|
12
|
+
import { isConfigValid as x } from "../validation/requiredFields.js";
|
|
13
|
+
const h = y();
|
|
14
|
+
let m = null, u = null, d = null;
|
|
15
|
+
function k() {
|
|
19
16
|
return {
|
|
20
|
-
cardsInRow:
|
|
17
|
+
cardsInRow: D,
|
|
21
18
|
currencySettings: {
|
|
22
19
|
name: "USD",
|
|
23
20
|
value: "USD",
|
|
@@ -31,14 +28,13 @@ function C() {
|
|
|
31
28
|
productIds: [],
|
|
32
29
|
id: 1,
|
|
33
30
|
language: "en_US",
|
|
34
|
-
mobileCardsInRow:
|
|
31
|
+
mobileCardsInRow: P,
|
|
35
32
|
mobileLayoutEnabled: !1,
|
|
36
33
|
orientation: "grid",
|
|
37
34
|
recommendedProducts: [],
|
|
38
35
|
sendProductRequestFlag: !1,
|
|
39
36
|
shuffleProducts: !1,
|
|
40
37
|
strategy: "mostPopular",
|
|
41
|
-
strategyId: "",
|
|
42
38
|
textTrimming: !0,
|
|
43
39
|
unresponsive: !1,
|
|
44
40
|
size: "6",
|
|
@@ -47,35 +43,28 @@ function C() {
|
|
|
47
43
|
priceHideIfSameAsDiscounted: !1
|
|
48
44
|
};
|
|
49
45
|
}
|
|
50
|
-
function
|
|
46
|
+
function I() {
|
|
51
47
|
return {
|
|
52
|
-
recommendationConfigs:
|
|
48
|
+
recommendationConfigs: k(),
|
|
53
49
|
recommendationProducts: [],
|
|
54
50
|
filterStatus: !1,
|
|
55
51
|
filterSelectionDrawerStatus: !1,
|
|
56
|
-
strategyDetailDrawerStatus: !1,
|
|
57
52
|
filterGroup: 1,
|
|
58
53
|
isInitialized: !1,
|
|
59
54
|
filterSnapshot: null
|
|
60
55
|
};
|
|
61
56
|
}
|
|
62
|
-
const
|
|
57
|
+
const L = () => ({
|
|
63
58
|
recommendationCampaignUrls: {},
|
|
64
59
|
activePredictiveAlgorithms: [],
|
|
65
60
|
languages: {},
|
|
66
61
|
currencyList: [],
|
|
67
62
|
filterList: {},
|
|
68
|
-
strategies: [],
|
|
69
|
-
strategiesLoading: !1,
|
|
70
|
-
strategyCampaigns: [],
|
|
71
|
-
strategyCampaignsLoading: !1,
|
|
72
|
-
strategyCampaignsFetchedFor: null,
|
|
73
|
-
strategyUrlTemplates: {},
|
|
74
63
|
blockStates: {},
|
|
75
64
|
currentRecommendationId: null,
|
|
76
65
|
configVersion: 0
|
|
77
|
-
}),
|
|
78
|
-
state: () =>
|
|
66
|
+
}), $ = F("guidoRecommendationExtension", {
|
|
67
|
+
state: () => L(),
|
|
79
68
|
getters: {
|
|
80
69
|
// ====================================================================
|
|
81
70
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -85,7 +74,7 @@ const B = () => ({
|
|
|
85
74
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
86
75
|
*/
|
|
87
76
|
recommendationConfigs(t) {
|
|
88
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
77
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
|
|
89
78
|
},
|
|
90
79
|
/**
|
|
91
80
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -99,12 +88,6 @@ const B = () => ({
|
|
|
99
88
|
filterSelectionDrawerStatus(t) {
|
|
100
89
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
101
90
|
},
|
|
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
|
-
},
|
|
108
91
|
/**
|
|
109
92
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
110
93
|
*/
|
|
@@ -136,55 +119,14 @@ const B = () => ({
|
|
|
136
119
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
137
120
|
},
|
|
138
121
|
getActivePredictiveAlgorithms: (t) => {
|
|
139
|
-
const e =
|
|
140
|
-
return t.activePredictiveAlgorithms.filter((
|
|
141
|
-
r.push(...e.filter((
|
|
142
|
-
}), r.map((
|
|
143
|
-
text:
|
|
144
|
-
value:
|
|
122
|
+
const e = g(), r = [];
|
|
123
|
+
return t.activePredictiveAlgorithms.filter((n) => !w.includes(n)).forEach((n) => {
|
|
124
|
+
r.push(...e.filter((c) => c.id === n));
|
|
125
|
+
}), r.map((n) => ({
|
|
126
|
+
text: n.name,
|
|
127
|
+
value: n.key
|
|
145
128
|
}));
|
|
146
129
|
},
|
|
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
|
-
},
|
|
188
130
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
189
131
|
text: r,
|
|
190
132
|
value: e
|
|
@@ -196,7 +138,7 @@ const B = () => ({
|
|
|
196
138
|
getFilterList() {
|
|
197
139
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
198
140
|
let e;
|
|
199
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
141
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
200
142
|
text: t.displayName,
|
|
201
143
|
value: e,
|
|
202
144
|
type: t.attributeType
|
|
@@ -218,7 +160,7 @@ const B = () => ({
|
|
|
218
160
|
setCurrentBlock(t) {
|
|
219
161
|
this.blockStates[t] || (this.blockStates = {
|
|
220
162
|
...this.blockStates,
|
|
221
|
-
[t]:
|
|
163
|
+
[t]: I()
|
|
222
164
|
}), this.currentRecommendationId = t;
|
|
223
165
|
},
|
|
224
166
|
/**
|
|
@@ -228,13 +170,13 @@ const B = () => ({
|
|
|
228
170
|
removeBlockState(t) {
|
|
229
171
|
const e = t.toString();
|
|
230
172
|
if (this.recommendationCampaignUrls[e]) {
|
|
231
|
-
const
|
|
232
|
-
delete
|
|
173
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
174
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
233
175
|
}
|
|
234
176
|
const r = { ...this.blockStates };
|
|
235
177
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
236
|
-
const
|
|
237
|
-
this.currentRecommendationId =
|
|
178
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
179
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
238
180
|
}
|
|
239
181
|
},
|
|
240
182
|
/**
|
|
@@ -250,10 +192,10 @@ const B = () => ({
|
|
|
250
192
|
[e]: o
|
|
251
193
|
};
|
|
252
194
|
}
|
|
253
|
-
const
|
|
254
|
-
|
|
195
|
+
const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
|
|
196
|
+
i && (this.recommendationCampaignUrls = {
|
|
255
197
|
...this.recommendationCampaignUrls,
|
|
256
|
-
[
|
|
198
|
+
[c]: i
|
|
257
199
|
});
|
|
258
200
|
},
|
|
259
201
|
/**
|
|
@@ -278,7 +220,7 @@ const B = () => ({
|
|
|
278
220
|
* `isInitialized`) alone.
|
|
279
221
|
*/
|
|
280
222
|
seedBlockUrlConfig(t, e) {
|
|
281
|
-
const r = (o, s) => o === "." || o === "," || o === " " ? o : s,
|
|
223
|
+
const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
|
|
282
224
|
name: e.currencyCode,
|
|
283
225
|
value: e.currencyCode,
|
|
284
226
|
symbol: e.currencyCode,
|
|
@@ -286,20 +228,19 @@ const B = () => ({
|
|
|
286
228
|
decimalCount: String(e.currencyDecimalCount),
|
|
287
229
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
288
230
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
...
|
|
231
|
+
}, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
|
|
232
|
+
i.recommendationConfigs = {
|
|
233
|
+
...i.recommendationConfigs,
|
|
292
234
|
strategy: e.strategy,
|
|
293
|
-
strategyId: e.strategyId,
|
|
294
235
|
language: e.language,
|
|
295
236
|
size: e.size,
|
|
296
237
|
productIds: e.productIds,
|
|
297
238
|
filters: e.filters,
|
|
298
239
|
shuffleProducts: e.shuffleProducts,
|
|
299
|
-
currencySettings:
|
|
300
|
-
},
|
|
240
|
+
currencySettings: n
|
|
241
|
+
}, c && (this.blockStates = {
|
|
301
242
|
...this.blockStates,
|
|
302
|
-
[t]:
|
|
243
|
+
[t]: i
|
|
303
244
|
});
|
|
304
245
|
},
|
|
305
246
|
/**
|
|
@@ -318,18 +259,18 @@ const B = () => ({
|
|
|
318
259
|
...t.currencySettings || {}
|
|
319
260
|
}
|
|
320
261
|
};
|
|
321
|
-
const { triggerRefetch:
|
|
322
|
-
|
|
262
|
+
const { triggerRefetch: n = !0 } = e;
|
|
263
|
+
n && this.configVersion++;
|
|
323
264
|
},
|
|
324
265
|
/**
|
|
325
266
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
326
267
|
*/
|
|
327
268
|
createDefaultFilter(t, e) {
|
|
328
|
-
const [r] = this.getFilterList, [
|
|
269
|
+
const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
|
|
329
270
|
return {
|
|
330
271
|
type: "standardFilter",
|
|
331
272
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
332
|
-
operator: (
|
|
273
|
+
operator: (n == null ? void 0 : n.value) ?? "",
|
|
333
274
|
innerGroupOperator: "*",
|
|
334
275
|
outerGroupOperator: "*",
|
|
335
276
|
filterNumber: e,
|
|
@@ -362,72 +303,6 @@ const B = () => ({
|
|
|
362
303
|
const t = this.blockStates[this.currentRecommendationId];
|
|
363
304
|
t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
|
|
364
305
|
},
|
|
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
|
-
},
|
|
431
306
|
/**
|
|
432
307
|
* Cancels the filter selection drawer and reverts filters
|
|
433
308
|
* to the snapshot taken when the drawer was opened.
|
|
@@ -443,72 +318,43 @@ const B = () => ({
|
|
|
443
318
|
// ====================================================================
|
|
444
319
|
async fetchRecommendationCreateData() {
|
|
445
320
|
if (!this.activePredictiveAlgorithms.length) {
|
|
446
|
-
if (
|
|
447
|
-
await
|
|
321
|
+
if (m) {
|
|
322
|
+
await m;
|
|
448
323
|
return;
|
|
449
324
|
}
|
|
450
|
-
|
|
325
|
+
m = (async () => {
|
|
451
326
|
const {
|
|
452
327
|
activePredictiveAlgorithms: t,
|
|
453
328
|
languages: e,
|
|
454
329
|
currencies: r
|
|
455
|
-
} = await
|
|
330
|
+
} = await h.fetchRecommendationCreateData();
|
|
456
331
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
457
|
-
const
|
|
458
|
-
|
|
332
|
+
const n = this.blockStates[this.currentRecommendationId];
|
|
333
|
+
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
459
334
|
}
|
|
460
335
|
this.currencyList = r;
|
|
461
336
|
})();
|
|
462
337
|
try {
|
|
463
|
-
await
|
|
338
|
+
await m;
|
|
464
339
|
} finally {
|
|
465
|
-
|
|
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;
|
|
340
|
+
m = null;
|
|
495
341
|
}
|
|
496
342
|
}
|
|
497
343
|
},
|
|
498
344
|
async fetchRecommendationFilters() {
|
|
499
345
|
if (!Object.keys(this.filterList).length) {
|
|
500
|
-
if (
|
|
501
|
-
await
|
|
346
|
+
if (u) {
|
|
347
|
+
await u;
|
|
502
348
|
return;
|
|
503
349
|
}
|
|
504
|
-
|
|
505
|
-
const t = await
|
|
350
|
+
u = (async () => {
|
|
351
|
+
const t = await h.fetchRecommendationFilters();
|
|
506
352
|
this.filterList = t;
|
|
507
353
|
})();
|
|
508
354
|
try {
|
|
509
|
-
await
|
|
355
|
+
await u;
|
|
510
356
|
} finally {
|
|
511
|
-
|
|
357
|
+
u = null;
|
|
512
358
|
}
|
|
513
359
|
}
|
|
514
360
|
},
|
|
@@ -523,59 +369,59 @@ const B = () => ({
|
|
|
523
369
|
deleteFilterGroup(t) {
|
|
524
370
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
525
371
|
return;
|
|
526
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
527
|
-
e.recommendationConfigs.filters = r.map((
|
|
528
|
-
...
|
|
529
|
-
filterGroup:
|
|
372
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
|
|
373
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
374
|
+
...i,
|
|
375
|
+
filterGroup: c.get(i.filterGroup) ?? i.filterGroup
|
|
530
376
|
}));
|
|
531
377
|
},
|
|
532
378
|
updateFilter(t) {
|
|
533
379
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
534
380
|
return;
|
|
535
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
381
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
536
382
|
if (r !== -1) {
|
|
537
|
-
const
|
|
538
|
-
|
|
383
|
+
const n = [...e.recommendationConfigs.filters];
|
|
384
|
+
n[r] = {
|
|
539
385
|
...t,
|
|
540
|
-
isValid:
|
|
541
|
-
}, e.recommendationConfigs.filters =
|
|
386
|
+
isValid: N(t)
|
|
387
|
+
}, e.recommendationConfigs.filters = n;
|
|
542
388
|
}
|
|
543
389
|
},
|
|
544
390
|
deleteFilter(t) {
|
|
545
391
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
546
392
|
return;
|
|
547
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
393
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
548
394
|
if (r !== -1) {
|
|
549
|
-
let
|
|
550
|
-
if (
|
|
551
|
-
let
|
|
552
|
-
|
|
395
|
+
let n = [...e.recommendationConfigs.filters];
|
|
396
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
397
|
+
let i = 1;
|
|
398
|
+
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
553
399
|
} else {
|
|
554
|
-
const
|
|
555
|
-
|
|
400
|
+
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
|
|
401
|
+
n = n.map((s) => ({
|
|
556
402
|
...s,
|
|
557
403
|
filterGroup: o.get(s.filterGroup) ?? s.filterGroup
|
|
558
404
|
}));
|
|
559
405
|
}
|
|
560
|
-
e.recommendationConfigs.filters =
|
|
406
|
+
e.recommendationConfigs.filters = n;
|
|
561
407
|
}
|
|
562
408
|
},
|
|
563
409
|
addFilter(t) {
|
|
564
410
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
565
411
|
return;
|
|
566
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters],
|
|
412
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
|
|
567
413
|
(o) => o.filterGroup === t.filterGroup
|
|
568
|
-
).length + 1,
|
|
569
|
-
|
|
414
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
415
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
570
416
|
...t,
|
|
571
|
-
filterNumber:
|
|
417
|
+
filterNumber: c
|
|
572
418
|
}) : r.push({
|
|
573
419
|
...t,
|
|
574
|
-
filterNumber:
|
|
420
|
+
filterNumber: c
|
|
575
421
|
}), e.recommendationConfigs.filters = r;
|
|
576
422
|
},
|
|
577
423
|
generateFilterQuery() {
|
|
578
|
-
return
|
|
424
|
+
return b(this.recommendationConfigs.filters);
|
|
579
425
|
},
|
|
580
426
|
/**
|
|
581
427
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -583,28 +429,28 @@ const B = () => ({
|
|
|
583
429
|
* every block's recommendationConfigs across user edits.
|
|
584
430
|
*/
|
|
585
431
|
hasInvalidBlock() {
|
|
586
|
-
return Object.values(this.blockStates).some((t) => !
|
|
432
|
+
return Object.values(this.blockStates).some((t) => !x(t.recommendationConfigs, this));
|
|
587
433
|
},
|
|
588
434
|
// ====================================================================
|
|
589
435
|
// Per-Block Product Fetching
|
|
590
436
|
// ====================================================================
|
|
591
437
|
async fetchRecommendationProducts() {
|
|
592
438
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
593
|
-
if (
|
|
594
|
-
await
|
|
439
|
+
if (d) {
|
|
440
|
+
await d;
|
|
595
441
|
return;
|
|
596
442
|
}
|
|
597
|
-
|
|
443
|
+
d = this._doFetchProducts();
|
|
598
444
|
try {
|
|
599
|
-
await
|
|
445
|
+
await d;
|
|
600
446
|
} finally {
|
|
601
|
-
|
|
447
|
+
d = null;
|
|
602
448
|
}
|
|
603
449
|
}
|
|
604
450
|
},
|
|
605
451
|
async _doFetchProducts() {
|
|
606
|
-
var
|
|
607
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
452
|
+
var p;
|
|
453
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
|
|
608
454
|
locale: r.language,
|
|
609
455
|
currency: r.currencySettings.value,
|
|
610
456
|
partnerName: o.partnerName,
|
|
@@ -612,26 +458,26 @@ const B = () => ({
|
|
|
612
458
|
details: !0,
|
|
613
459
|
campaignId: o.variationId
|
|
614
460
|
};
|
|
615
|
-
r.strategy === "manualMerchandising" ?
|
|
616
|
-
|
|
617
|
-
|
|
461
|
+
r.strategy === "manualMerchandising" ? a.productId = r.productIds.join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
462
|
+
a,
|
|
463
|
+
v(o.partnerName, r.strategy)
|
|
618
464
|
);
|
|
619
|
-
let
|
|
465
|
+
let f;
|
|
620
466
|
try {
|
|
621
|
-
|
|
467
|
+
f = await h.fetchRecommendationProducts(i, a);
|
|
622
468
|
} catch {
|
|
623
|
-
|
|
469
|
+
f = [];
|
|
624
470
|
}
|
|
625
471
|
if (this.blockStates[t]) {
|
|
626
|
-
const l =
|
|
472
|
+
const l = f.length > 0 ? f : S(s);
|
|
627
473
|
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
628
474
|
...l,
|
|
629
|
-
...
|
|
475
|
+
...S(s - l.length)
|
|
630
476
|
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
631
477
|
}
|
|
632
478
|
}
|
|
633
479
|
}
|
|
634
480
|
});
|
|
635
481
|
export {
|
|
636
|
-
|
|
482
|
+
$ as useRecommendationExtensionStore
|
|
637
483
|
};
|
|
@@ -9,38 +9,26 @@ const l = [
|
|
|
9
9
|
getValue: (e) => e.currencySettings.value,
|
|
10
10
|
getAvailableOptions: (e) => e.currencyList.map((n) => n.text),
|
|
11
11
|
canBeEmpty: !0
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
// Required only behind the feature flag: with the flag off the block is still
|
|
15
|
-
// driven by its algorithm, so an empty strategyId is the normal state and must
|
|
16
|
-
// not block the save.
|
|
17
|
-
//
|
|
18
|
-
// Deliberately no `getAvailableOptions`: a strategy the partner deleted in
|
|
19
|
-
// Smart Recommender would then fail validation and strand an already-saved
|
|
20
|
-
// template. The panel surfaces that case instead (see `strategy.ts`).
|
|
21
|
-
key: "strategy",
|
|
22
|
-
getValue: (e) => e.strategyId,
|
|
23
|
-
condition: (e, n) => n.isRrsEnabled
|
|
24
12
|
}
|
|
25
|
-
],
|
|
26
|
-
function c(e, n,
|
|
27
|
-
return
|
|
28
|
-
var
|
|
29
|
-
if (t.condition && !t.condition(e
|
|
13
|
+
], o = "newsletter.recommendation-fill-required-fields";
|
|
14
|
+
function c(e, n, i = l) {
|
|
15
|
+
return i.filter((t) => {
|
|
16
|
+
var u;
|
|
17
|
+
if (t.condition && !t.condition(e))
|
|
30
18
|
return !1;
|
|
31
|
-
const
|
|
32
|
-
if (t.canBeEmpty && (
|
|
19
|
+
const r = (u = t.getAvailableOptions) == null ? void 0 : u.call(t, n);
|
|
20
|
+
if (t.canBeEmpty && (r == null ? void 0 : r.length) === 0)
|
|
33
21
|
return !1;
|
|
34
|
-
const
|
|
35
|
-
return
|
|
22
|
+
const a = t.getValue(e);
|
|
23
|
+
return a ? r !== void 0 && !r.includes(a) : !0;
|
|
36
24
|
}).map((t) => t.key);
|
|
37
25
|
}
|
|
38
|
-
function
|
|
26
|
+
function s(e, n) {
|
|
39
27
|
return c(e, n).length === 0;
|
|
40
28
|
}
|
|
41
29
|
export {
|
|
42
30
|
l as REQUIRED_RECOMMENDATION_FIELDS,
|
|
43
|
-
|
|
31
|
+
o as RecommendationRequiredFieldsKey,
|
|
44
32
|
c as getInvalidFields,
|
|
45
|
-
|
|
33
|
+
s as isConfigValid
|
|
46
34
|
};
|
|
@@ -5,9 +5,10 @@ const s = {
|
|
|
5
5
|
PAGE_TYPE: "data-unsubscribe-page-type",
|
|
6
6
|
PAGE_LIST: "data-unsubscribe-page-list",
|
|
7
7
|
BLOCK_ID: "data-unsubscribe-block-id"
|
|
8
|
-
}, c = ".unsubscribe-block-v2";
|
|
8
|
+
}, c = ".unsubscribe-block-v2", u = 'a[data-unsubscribe-link="true"], a.unsubscribe-link';
|
|
9
9
|
export {
|
|
10
10
|
b as DATA_ATTRIBUTES,
|
|
11
11
|
c as UNSUBSCRIBE_BLOCK_SELECTOR,
|
|
12
|
-
s as UNSUBSCRIBE_EVENTS
|
|
12
|
+
s as UNSUBSCRIBE_EVENTS,
|
|
13
|
+
u as UNSUBSCRIBE_LINK_SELECTOR
|
|
13
14
|
};
|