@useinsider/guido 3.17.0-beta.6255bfc → 3.17.0-beta.668ca65
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 +0 -5
- package/dist/components/Guido.vue.js +8 -8
- package/dist/components/Guido.vue2.js +76 -73
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -10
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +75 -36
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +62 -0
- package/dist/composables/useRecommendation.js +29 -30
- package/dist/config/migrator/recommendation/settingsMapper.js +0 -2
- package/dist/config/migrator/recommendationMigrator.js +0 -1
- package/dist/enums/date.js +5 -4
- package/dist/enums/extensions/recommendationBlock.js +0 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +0 -2
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +27 -45
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -18
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +111 -166
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +11 -17
- package/dist/src/@types/config/schemas.d.ts +0 -10
- package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/enums/date.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -5
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -7
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -14
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -56
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -5
- package/dist/src/mock/api/recommendation-strategies.d.ts +0 -61
- package/dist/src/services/recommendationApi.d.ts +1 -1
- package/dist/src/stores/save-as-template.d.ts +4 -3
- package/dist/static/assets/icons/line-delete.svg.js +2 -2
- package/dist/static/assets/icons/line-plus.svg.js +2 -2
- package/dist/static/styles/components/recommendation-strategy.css.js +2 -35
- package/dist/utils/dateUtil.js +18 -24
- package/dist/utils/templatePreparation.js +0 -2
- package/package.json +2 -2
- package/dist/src/utils/strategyInfoBox.d.ts +0 -22
- package/dist/utils/strategyInfoBox.js +0 -37
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { defineStore as F } from "pinia";
|
|
1
|
+
import { getRecommendationFeedSourceMaps as I, getOperatorOptions as G, PriceAttributes as D } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as F } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as v } from "pinia";
|
|
6
5
|
import "../constants/selectors.js";
|
|
7
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
8
|
-
import { DEFAULT_NODE_CONFIG as
|
|
9
|
-
import { getDefaultProducts as
|
|
10
|
-
import { generateCompleteFilterQuery as
|
|
11
|
-
import { getPartnerRecommendationParams as
|
|
12
|
-
import { sanitizeProductIds as
|
|
13
|
-
import { isFilterValid as
|
|
14
|
-
import { isConfigValid as
|
|
15
|
-
const
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
|
|
7
|
+
import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
|
|
8
|
+
import { getDefaultProducts as k } from "../templates/utils.js";
|
|
9
|
+
import { generateCompleteFilterQuery as R } from "../utils/filterUtil.js";
|
|
10
|
+
import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
|
|
11
|
+
import { sanitizeProductIds as A } from "../utils/productIds.js";
|
|
12
|
+
import { isFilterValid as B } from "../validation/filterSchema.js";
|
|
13
|
+
import { isConfigValid as z } from "../validation/requiredFields.js";
|
|
14
|
+
const m = P();
|
|
16
15
|
let f = null, g = null, h = null, S = null;
|
|
17
|
-
|
|
16
|
+
const p = /* @__PURE__ */ new Map();
|
|
17
|
+
function w() {
|
|
18
18
|
return {
|
|
19
|
-
cardsInRow:
|
|
19
|
+
cardsInRow: U,
|
|
20
20
|
currencySettings: {
|
|
21
21
|
name: "USD",
|
|
22
22
|
value: "USD",
|
|
@@ -30,7 +30,7 @@ function R() {
|
|
|
30
30
|
productIds: [],
|
|
31
31
|
id: 1,
|
|
32
32
|
language: "en_US",
|
|
33
|
-
mobileCardsInRow:
|
|
33
|
+
mobileCardsInRow: _,
|
|
34
34
|
mobileLayoutEnabled: !1,
|
|
35
35
|
orientation: "grid",
|
|
36
36
|
recommendedProducts: [],
|
|
@@ -46,9 +46,9 @@ function R() {
|
|
|
46
46
|
priceHideIfSameAsDiscounted: !1
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function C() {
|
|
50
50
|
return {
|
|
51
|
-
recommendationConfigs:
|
|
51
|
+
recommendationConfigs: w(),
|
|
52
52
|
recommendationProducts: [],
|
|
53
53
|
filterStatus: !1,
|
|
54
54
|
filterSelectionDrawerStatus: !1,
|
|
@@ -58,7 +58,7 @@ function k() {
|
|
|
58
58
|
filterSnapshot: null
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
const
|
|
61
|
+
const O = () => ({
|
|
62
62
|
recommendationCampaignUrls: {},
|
|
63
63
|
activePredictiveAlgorithms: [],
|
|
64
64
|
languages: {},
|
|
@@ -70,8 +70,8 @@ const z = () => ({
|
|
|
70
70
|
blockStates: {},
|
|
71
71
|
currentRecommendationId: null,
|
|
72
72
|
configVersion: 0
|
|
73
|
-
}), Y =
|
|
74
|
-
state: () =>
|
|
73
|
+
}), Y = v("guidoRecommendationExtension", {
|
|
74
|
+
state: () => O(),
|
|
75
75
|
getters: {
|
|
76
76
|
// ====================================================================
|
|
77
77
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -81,7 +81,7 @@ const z = () => ({
|
|
|
81
81
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
82
82
|
*/
|
|
83
83
|
recommendationConfigs(t) {
|
|
84
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
84
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
|
|
85
85
|
},
|
|
86
86
|
/**
|
|
87
87
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -95,16 +95,9 @@ const z = () => ({
|
|
|
95
95
|
filterSelectionDrawerStatus(t) {
|
|
96
96
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
97
97
|
},
|
|
98
|
-
/**
|
|
99
|
-
* Proxy getter: delegates to blockStates[currentRecommendationId].assignStrategyDrawerStatus
|
|
100
|
-
*/
|
|
101
98
|
assignStrategyDrawerStatus(t) {
|
|
102
99
|
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
|
|
103
100
|
},
|
|
104
|
-
/**
|
|
105
|
-
* The current block's assigned strategy record from the listing,
|
|
106
|
-
* or null when nothing is assigned / the strategy is no longer listed.
|
|
107
|
-
*/
|
|
108
101
|
assignedStrategy(t) {
|
|
109
102
|
const { strategyId: e } = this.recommendationConfigs;
|
|
110
103
|
return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
|
|
@@ -140,12 +133,12 @@ const z = () => ({
|
|
|
140
133
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
141
134
|
},
|
|
142
135
|
getActivePredictiveAlgorithms: (t) => {
|
|
143
|
-
const e =
|
|
144
|
-
return t.activePredictiveAlgorithms.filter((
|
|
145
|
-
r.push(...e.filter((s) => s.id ===
|
|
146
|
-
}), r.map((
|
|
147
|
-
text:
|
|
148
|
-
value:
|
|
136
|
+
const e = I(), r = [];
|
|
137
|
+
return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
|
|
138
|
+
r.push(...e.filter((s) => s.id === n));
|
|
139
|
+
}), r.map((n) => ({
|
|
140
|
+
text: n.name,
|
|
141
|
+
value: n.key
|
|
149
142
|
}));
|
|
150
143
|
},
|
|
151
144
|
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
@@ -159,7 +152,7 @@ const z = () => ({
|
|
|
159
152
|
getFilterList() {
|
|
160
153
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
161
154
|
let e;
|
|
162
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
155
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : D.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
163
156
|
text: t.displayName,
|
|
164
157
|
value: e,
|
|
165
158
|
type: t.attributeType
|
|
@@ -181,7 +174,7 @@ const z = () => ({
|
|
|
181
174
|
setCurrentBlock(t) {
|
|
182
175
|
this.blockStates[t] || (this.blockStates = {
|
|
183
176
|
...this.blockStates,
|
|
184
|
-
[t]:
|
|
177
|
+
[t]: C()
|
|
185
178
|
}), this.currentRecommendationId = t;
|
|
186
179
|
},
|
|
187
180
|
/**
|
|
@@ -191,13 +184,13 @@ const z = () => ({
|
|
|
191
184
|
removeBlockState(t) {
|
|
192
185
|
const e = t.toString();
|
|
193
186
|
if (this.recommendationCampaignUrls[e]) {
|
|
194
|
-
const
|
|
195
|
-
delete
|
|
187
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
188
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
196
189
|
}
|
|
197
190
|
const r = { ...this.blockStates };
|
|
198
191
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
199
|
-
const
|
|
200
|
-
this.currentRecommendationId =
|
|
192
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
193
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
201
194
|
}
|
|
202
195
|
},
|
|
203
196
|
/**
|
|
@@ -213,10 +206,10 @@ const z = () => ({
|
|
|
213
206
|
[e]: o
|
|
214
207
|
};
|
|
215
208
|
}
|
|
216
|
-
const
|
|
217
|
-
|
|
209
|
+
const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
|
|
210
|
+
i && (this.recommendationCampaignUrls = {
|
|
218
211
|
...this.recommendationCampaignUrls,
|
|
219
|
-
[s]:
|
|
212
|
+
[s]: i
|
|
220
213
|
});
|
|
221
214
|
},
|
|
222
215
|
/**
|
|
@@ -241,7 +234,7 @@ const z = () => ({
|
|
|
241
234
|
* `isInitialized`) alone.
|
|
242
235
|
*/
|
|
243
236
|
seedBlockUrlConfig(t, e) {
|
|
244
|
-
const r = (o,
|
|
237
|
+
const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
|
|
245
238
|
name: e.currencyCode,
|
|
246
239
|
value: e.currencyCode,
|
|
247
240
|
symbol: e.currencyCode,
|
|
@@ -249,9 +242,9 @@ const z = () => ({
|
|
|
249
242
|
decimalCount: String(e.currencyDecimalCount),
|
|
250
243
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
251
244
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
252
|
-
}, s = !this.blockStates[t],
|
|
253
|
-
|
|
254
|
-
...
|
|
245
|
+
}, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
|
|
246
|
+
i.recommendationConfigs = {
|
|
247
|
+
...i.recommendationConfigs,
|
|
255
248
|
strategy: e.strategy,
|
|
256
249
|
strategyId: e.strategyId,
|
|
257
250
|
language: e.language,
|
|
@@ -259,10 +252,10 @@ const z = () => ({
|
|
|
259
252
|
productIds: e.productIds,
|
|
260
253
|
filters: e.filters,
|
|
261
254
|
shuffleProducts: e.shuffleProducts,
|
|
262
|
-
currencySettings:
|
|
255
|
+
currencySettings: n
|
|
263
256
|
}, s && (this.blockStates = {
|
|
264
257
|
...this.blockStates,
|
|
265
|
-
[t]:
|
|
258
|
+
[t]: i
|
|
266
259
|
});
|
|
267
260
|
},
|
|
268
261
|
/**
|
|
@@ -281,18 +274,18 @@ const z = () => ({
|
|
|
281
274
|
...t.currencySettings || {}
|
|
282
275
|
}
|
|
283
276
|
};
|
|
284
|
-
const { triggerRefetch:
|
|
285
|
-
|
|
277
|
+
const { triggerRefetch: n = !0 } = e;
|
|
278
|
+
n && this.configVersion++;
|
|
286
279
|
},
|
|
287
280
|
/**
|
|
288
281
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
289
282
|
*/
|
|
290
283
|
createDefaultFilter(t, e) {
|
|
291
|
-
const [r] = this.getFilterList, [
|
|
284
|
+
const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
|
|
292
285
|
return {
|
|
293
286
|
type: "standardFilter",
|
|
294
287
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
295
|
-
operator: (
|
|
288
|
+
operator: (n == null ? void 0 : n.value) ?? "",
|
|
296
289
|
innerGroupOperator: "*",
|
|
297
290
|
outerGroupOperator: "*",
|
|
298
291
|
filterNumber: e,
|
|
@@ -335,25 +328,12 @@ const z = () => ({
|
|
|
335
328
|
const t = this.blockStates[this.currentRecommendationId];
|
|
336
329
|
t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
|
|
337
330
|
},
|
|
338
|
-
// ====================================================================
|
|
339
|
-
// Reusable Recommendation Strategy (SD-149105)
|
|
340
|
-
// ====================================================================
|
|
341
|
-
/**
|
|
342
|
-
* Opens the Assign Strategy drawer for the current block.
|
|
343
|
-
* Selection state lives in the drawer component until Assign is
|
|
344
|
-
* pressed, so closing without assigning needs no snapshot/revert.
|
|
345
|
-
*/
|
|
346
331
|
openAssignStrategyDrawer() {
|
|
347
332
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !0);
|
|
348
333
|
},
|
|
349
334
|
closeAssignStrategyDrawer() {
|
|
350
335
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
|
|
351
336
|
},
|
|
352
|
-
/**
|
|
353
|
-
* Fetches the active + EMAIL strategy listing. Always fetches fresh
|
|
354
|
-
* (dead-strategy detection and post-create refresh need freshness);
|
|
355
|
-
* only concurrent in-flight calls share one request.
|
|
356
|
-
*/
|
|
357
337
|
async fetchStrategies() {
|
|
358
338
|
if (S) {
|
|
359
339
|
await S;
|
|
@@ -362,7 +342,7 @@ const z = () => ({
|
|
|
362
342
|
S = (async () => {
|
|
363
343
|
this.strategiesLoading = !0;
|
|
364
344
|
try {
|
|
365
|
-
this.strategies = await
|
|
345
|
+
this.strategies = await m.fetchRecommendationStrategies();
|
|
366
346
|
} finally {
|
|
367
347
|
this.strategiesLoading = !1;
|
|
368
348
|
}
|
|
@@ -373,49 +353,24 @@ const z = () => ({
|
|
|
373
353
|
S = null;
|
|
374
354
|
}
|
|
375
355
|
},
|
|
376
|
-
/**
|
|
377
|
-
* Resolves a strategy's recommendation endpoint template via
|
|
378
|
-
* endpoint-generate, cached per strategy id + revision + currency.
|
|
379
|
-
* Failures throw and are NOT cached, so the next attempt retries.
|
|
380
|
-
*
|
|
381
|
-
* `full_path` bakes in the algorithm path and `size=` as they were when
|
|
382
|
-
* generated, so the revision keys the cache — and a record with no
|
|
383
|
-
* revision is not cached at all, since its key could never change.
|
|
384
|
-
* Currency joins the key because it is sent in the request body, so two
|
|
385
|
-
* currencies can resolve to different paths for the same revision.
|
|
386
|
-
*/
|
|
387
356
|
async resolveStrategyUrlTemplate(t, e) {
|
|
388
|
-
const r = typeof t.updated_at == "string" ? t.updated_at : "",
|
|
357
|
+
const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
|
|
389
358
|
if (s)
|
|
390
359
|
return s;
|
|
391
|
-
const { full_path:
|
|
392
|
-
return i && (this.strategyUrlTemplates = {
|
|
360
|
+
const { full_path: i = "" } = await m.generateStrategyEndpoint(t, e) ?? {};
|
|
361
|
+
return n && i && (this.strategyUrlTemplates = {
|
|
393
362
|
...this.strategyUrlTemplates,
|
|
394
|
-
[
|
|
395
|
-
}),
|
|
363
|
+
[n]: i
|
|
364
|
+
}), i;
|
|
396
365
|
},
|
|
397
|
-
/**
|
|
398
|
-
* Assigns a strategy to the current block. The config write is
|
|
399
|
-
* synchronous (before any await) so a block switch cannot misdirect
|
|
400
|
-
* it; the configVersion bump persists it to node config and triggers
|
|
401
|
-
* the product refetch via the coordinator control's subscription.
|
|
402
|
-
*/
|
|
403
366
|
assignStrategy(t) {
|
|
404
367
|
this.patchCurrentBlockConfig({
|
|
405
368
|
strategyId: String(t.strategy_id),
|
|
406
369
|
...t.size !== void 0 ? { size: String(t.size) } : {}
|
|
407
370
|
});
|
|
408
371
|
},
|
|
409
|
-
/**
|
|
410
|
-
* Clears the current block's strategy; it falls back to the per-block
|
|
411
|
-
* algorithm settings.
|
|
412
|
-
*
|
|
413
|
-
* `size` goes back to the default rather than staying on the removed
|
|
414
|
-
* strategy's count: with Number of Products hidden in RRS mode, a block
|
|
415
|
-
* left on that count would have no UI to correct it.
|
|
416
|
-
*/
|
|
417
372
|
removeStrategy() {
|
|
418
|
-
this.patchCurrentBlockConfig({ strategyId: "", size:
|
|
373
|
+
this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
|
|
419
374
|
},
|
|
420
375
|
// ====================================================================
|
|
421
376
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
@@ -431,10 +386,10 @@ const z = () => ({
|
|
|
431
386
|
activePredictiveAlgorithms: t,
|
|
432
387
|
languages: e,
|
|
433
388
|
currencies: r
|
|
434
|
-
} = await
|
|
389
|
+
} = await m.fetchRecommendationCreateData();
|
|
435
390
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
436
|
-
const
|
|
437
|
-
|
|
391
|
+
const n = this.blockStates[this.currentRecommendationId];
|
|
392
|
+
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
438
393
|
}
|
|
439
394
|
this.currencyList = r;
|
|
440
395
|
})();
|
|
@@ -452,7 +407,7 @@ const z = () => ({
|
|
|
452
407
|
return;
|
|
453
408
|
}
|
|
454
409
|
g = (async () => {
|
|
455
|
-
const t = await
|
|
410
|
+
const t = await m.fetchRecommendationFilters();
|
|
456
411
|
this.filterList = t;
|
|
457
412
|
})();
|
|
458
413
|
try {
|
|
@@ -473,41 +428,41 @@ const z = () => ({
|
|
|
473
428
|
deleteFilterGroup(t) {
|
|
474
429
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
475
430
|
return;
|
|
476
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((
|
|
477
|
-
e.recommendationConfigs.filters = r.map((
|
|
478
|
-
...
|
|
479
|
-
filterGroup: s.get(
|
|
431
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), s = new Map(n.map((i, o) => [i, o + 1]));
|
|
432
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
433
|
+
...i,
|
|
434
|
+
filterGroup: s.get(i.filterGroup) ?? i.filterGroup
|
|
480
435
|
}));
|
|
481
436
|
},
|
|
482
437
|
updateFilter(t) {
|
|
483
438
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
484
439
|
return;
|
|
485
|
-
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((
|
|
440
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
486
441
|
if (r !== -1) {
|
|
487
|
-
const
|
|
488
|
-
|
|
442
|
+
const n = [...e.recommendationConfigs.filters];
|
|
443
|
+
n[r] = {
|
|
489
444
|
...t,
|
|
490
|
-
isValid:
|
|
491
|
-
}, e.recommendationConfigs.filters =
|
|
445
|
+
isValid: B(t)
|
|
446
|
+
}, e.recommendationConfigs.filters = n;
|
|
492
447
|
}
|
|
493
448
|
},
|
|
494
449
|
deleteFilter(t) {
|
|
495
450
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
496
451
|
return;
|
|
497
|
-
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((
|
|
452
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
498
453
|
if (r !== -1) {
|
|
499
|
-
let
|
|
500
|
-
if (
|
|
501
|
-
let
|
|
502
|
-
|
|
454
|
+
let n = [...e.recommendationConfigs.filters];
|
|
455
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
456
|
+
let i = 1;
|
|
457
|
+
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
503
458
|
} else {
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
...
|
|
507
|
-
filterGroup: o.get(
|
|
459
|
+
const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
|
|
460
|
+
n = n.map((c) => ({
|
|
461
|
+
...c,
|
|
462
|
+
filterGroup: o.get(c.filterGroup) ?? c.filterGroup
|
|
508
463
|
}));
|
|
509
464
|
}
|
|
510
|
-
e.recommendationConfigs.filters =
|
|
465
|
+
e.recommendationConfigs.filters = n;
|
|
511
466
|
}
|
|
512
467
|
},
|
|
513
468
|
addFilter(t) {
|
|
@@ -515,8 +470,8 @@ const z = () => ({
|
|
|
515
470
|
return;
|
|
516
471
|
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
|
|
517
472
|
(o) => o.filterGroup === t.filterGroup
|
|
518
|
-
).length + 1,
|
|
519
|
-
|
|
473
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
474
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
520
475
|
...t,
|
|
521
476
|
filterNumber: s
|
|
522
477
|
}) : r.push({
|
|
@@ -525,7 +480,7 @@ const z = () => ({
|
|
|
525
480
|
}), e.recommendationConfigs.filters = r;
|
|
526
481
|
},
|
|
527
482
|
generateFilterQuery() {
|
|
528
|
-
return
|
|
483
|
+
return R(this.recommendationConfigs.filters);
|
|
529
484
|
},
|
|
530
485
|
/**
|
|
531
486
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -533,7 +488,7 @@ const z = () => ({
|
|
|
533
488
|
* every block's recommendationConfigs across user edits.
|
|
534
489
|
*/
|
|
535
490
|
hasInvalidBlock() {
|
|
536
|
-
return Object.values(this.blockStates).some((t) => !
|
|
491
|
+
return Object.values(this.blockStates).some((t) => !z(t.recommendationConfigs, this));
|
|
537
492
|
},
|
|
538
493
|
// ====================================================================
|
|
539
494
|
// Per-Block Product Fetching
|
|
@@ -553,69 +508,59 @@ const z = () => ({
|
|
|
553
508
|
}
|
|
554
509
|
},
|
|
555
510
|
async _doFetchProducts() {
|
|
556
|
-
var
|
|
557
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e,
|
|
558
|
-
if (
|
|
511
|
+
var d;
|
|
512
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
|
|
513
|
+
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
559
514
|
await this._doFetchStrategyProducts(t);
|
|
560
515
|
return;
|
|
561
516
|
}
|
|
562
|
-
const
|
|
517
|
+
const s = r.filters.filter((u) => u.isValid), i = R(s), o = ((d = I().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
|
|
563
518
|
locale: r.language,
|
|
564
519
|
currency: r.currencySettings.value,
|
|
565
|
-
partnerName:
|
|
520
|
+
partnerName: n.partnerName,
|
|
566
521
|
size: r.size,
|
|
567
522
|
details: !0,
|
|
568
|
-
campaignId:
|
|
523
|
+
campaignId: n.variationId
|
|
569
524
|
};
|
|
570
|
-
r.strategy === "manualMerchandising" ?
|
|
571
|
-
|
|
572
|
-
|
|
525
|
+
r.strategy === "manualMerchandising" ? a.productId = A(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
526
|
+
a,
|
|
527
|
+
x(n.partnerName, r.strategy)
|
|
573
528
|
);
|
|
574
|
-
let
|
|
529
|
+
let l;
|
|
575
530
|
try {
|
|
576
|
-
|
|
531
|
+
l = await m.fetchRecommendationProducts(o, a);
|
|
577
532
|
} catch {
|
|
578
|
-
|
|
533
|
+
l = [];
|
|
579
534
|
}
|
|
580
|
-
this._setBlockProducts(t,
|
|
535
|
+
this._setBlockProducts(t, l, c);
|
|
581
536
|
},
|
|
582
|
-
/**
|
|
583
|
-
* Fetches products for a strategy-backed block: listing lookup →
|
|
584
|
-
* endpoint-generate template → fill {locale}/{currency}, drop
|
|
585
|
-
* {user_id} (resolved at send time) → fetch. Any failure (dead
|
|
586
|
-
* strategy, resolution error) falls back to placeholder products.
|
|
587
|
-
*/
|
|
588
537
|
async _doFetchStrategyProducts(t) {
|
|
589
|
-
const
|
|
590
|
-
|
|
538
|
+
const e = (p.get(t) ?? 0) + 1;
|
|
539
|
+
p.set(t, e);
|
|
540
|
+
const { recommendationConfigs: r } = this.blockStates[t];
|
|
541
|
+
let n = [], s = parseInt(r.size) || 6;
|
|
591
542
|
try {
|
|
592
|
-
|
|
593
|
-
const
|
|
594
|
-
(
|
|
543
|
+
await this.fetchStrategies();
|
|
544
|
+
const i = this.strategies.find(
|
|
545
|
+
(o) => String(o.strategy_id) === r.strategyId
|
|
595
546
|
);
|
|
596
|
-
if (
|
|
597
|
-
|
|
598
|
-
const
|
|
599
|
-
|
|
547
|
+
if (i) {
|
|
548
|
+
s = parseInt(String(i.size ?? "")) || s;
|
|
549
|
+
const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((b) => b && !b.startsWith("user_id=")), y = u.length ? `${d}?${u.join("&")}` : d;
|
|
550
|
+
y && (n = await m.fetchRecommendationProductsByUrl(y));
|
|
600
551
|
}
|
|
601
552
|
} catch {
|
|
602
|
-
|
|
553
|
+
n = [];
|
|
603
554
|
}
|
|
604
|
-
this._setBlockProducts(t,
|
|
555
|
+
p.get(t) === e && this._setBlockProducts(t, n, s);
|
|
605
556
|
},
|
|
606
|
-
/**
|
|
607
|
-
* Writes products to a block's state, padded/clipped to exactly `size`:
|
|
608
|
-
* in-place content updates compare the DOM element count against
|
|
609
|
-
* products.length, and a longer list makes the renderer extend its slot
|
|
610
|
-
* grid, which resets migrator-applied styles.
|
|
611
|
-
*/
|
|
612
557
|
_setBlockProducts(t, e, r) {
|
|
613
558
|
if (!this.blockStates[t])
|
|
614
559
|
return;
|
|
615
|
-
const
|
|
560
|
+
const n = e.length > 0 ? e : k(r);
|
|
616
561
|
this.blockStates[t].recommendationProducts = [
|
|
617
|
-
...
|
|
618
|
-
...
|
|
562
|
+
...n.slice(0, r),
|
|
563
|
+
...k(Math.max(0, r - n.length))
|
|
619
564
|
];
|
|
620
565
|
}
|
|
621
566
|
}
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";.gap-16[data-v-
|
|
1
|
+
@charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-e6f99d29]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-e6f99d29]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-e6f99d29]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-d3080c55]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-d3080c55] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useHttp as
|
|
2
|
-
import { URLS as m, QUERY_PARAMS as
|
|
3
|
-
const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]",
|
|
1
|
+
import { useHttp as l } from "../composables/useHttp.js";
|
|
2
|
+
import { URLS as m, QUERY_PARAMS as u } from "../enums/extensions/recommendationBlock.js";
|
|
3
|
+
const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]", R = (c) => c.reduce(
|
|
4
4
|
(s, r, i) => (s[i] = {
|
|
5
5
|
attributeName: r.attributeName,
|
|
6
6
|
attributeJs: r.attributeJs,
|
|
@@ -11,7 +11,7 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
11
11
|
}, s),
|
|
12
12
|
{}
|
|
13
13
|
), _ = () => {
|
|
14
|
-
const { get: c, post: s } =
|
|
14
|
+
const { get: c, post: s } = l(), { get: r } = l({ headers: {} }), i = "6KcLM9TwheVB1mgK";
|
|
15
15
|
return {
|
|
16
16
|
fetchRecommendationCreateData: async () => {
|
|
17
17
|
try {
|
|
@@ -25,7 +25,7 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
25
25
|
const { data: e } = await c(
|
|
26
26
|
m.PRODUCT_ATTRIBUTES_PATH
|
|
27
27
|
), o = Array.isArray(e) ? e : (e == null ? void 0 : e.data) ?? [];
|
|
28
|
-
return
|
|
28
|
+
return R(o);
|
|
29
29
|
} catch (e) {
|
|
30
30
|
throw console.error("fetchRecommendationFilters error:", e), e;
|
|
31
31
|
}
|
|
@@ -34,7 +34,7 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
34
34
|
var t;
|
|
35
35
|
try {
|
|
36
36
|
const n = new URLSearchParams(Object.entries(o));
|
|
37
|
-
n.set(
|
|
37
|
+
n.set(u.CLIENT_ID, i);
|
|
38
38
|
const d = decodeURIComponent(n.toString());
|
|
39
39
|
console.debug("🏁 Recommendation API Query:", d);
|
|
40
40
|
const a = await r(
|
|
@@ -48,12 +48,12 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
48
48
|
fetchRecommendationProductsByUrl: async (e) => {
|
|
49
49
|
var o;
|
|
50
50
|
try {
|
|
51
|
-
const t = new RegExp(`[?&]${
|
|
51
|
+
const t = new RegExp(`[?&]${u.CLIENT_ID}=`).test(e), n = e.includes("?") ? "&" : "?", d = t ? e : `${e}${n}${u.CLIENT_ID}=${i}`, a = await r(
|
|
52
52
|
d
|
|
53
53
|
);
|
|
54
54
|
return ((o = a == null ? void 0 : a.data) == null ? void 0 : o.data) ?? [];
|
|
55
55
|
} catch (t) {
|
|
56
|
-
|
|
56
|
+
return console.error("fetchRecommendationProductsByUrl error:", t), [];
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
fetchRecommendationStrategies: async () => {
|
|
@@ -63,7 +63,7 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
63
63
|
);
|
|
64
64
|
return Array.isArray(e) ? e : (e == null ? void 0 : e.data) ?? [];
|
|
65
65
|
} catch (e) {
|
|
66
|
-
|
|
66
|
+
return console.error("fetchRecommendationStrategies error:", e), [];
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
69
|
generateStrategyEndpoint: async (e, o) => {
|
|
@@ -71,11 +71,7 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
71
71
|
const { data: t } = await s(
|
|
72
72
|
`${m.RECOMMENDATION_STRATEGIES_PATH}/endpoint-generate`,
|
|
73
73
|
{
|
|
74
|
-
// Email designs have no campaign yet; backend only needs it
|
|
75
|
-
// for previewer flows.
|
|
76
74
|
campaignId: 0,
|
|
77
|
-
// Deliberately empty: page types are a web-surface concept
|
|
78
|
-
// and an email has no page context to send.
|
|
79
75
|
pageTypes: [],
|
|
80
76
|
isPreviewer: !1,
|
|
81
77
|
strategy: e,
|
|
@@ -83,11 +79,9 @@ const y = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~
|
|
|
83
79
|
currency: o
|
|
84
80
|
}
|
|
85
81
|
);
|
|
86
|
-
|
|
87
|
-
throw new Error("Unexpected endpoint-generate response shape");
|
|
88
|
-
return "full_path" in t ? t : t.data;
|
|
82
|
+
return !t || typeof t != "object" || !("full_path" in t || "data" in t) ? (console.error("generateStrategyEndpoint unexpected response shape:", t), null) : "full_path" in t ? t : t.data;
|
|
89
83
|
} catch (t) {
|
|
90
|
-
|
|
84
|
+
return console.error("generateStrategyEndpoint error:", t), null;
|
|
91
85
|
}
|
|
92
86
|
}
|
|
93
87
|
};
|