@useinsider/guido 3.18.2-beta.d3f87c7 → 3.18.2-beta.ec1fd57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Guido.vue.js +3 -3
- package/dist/components/Guido.vue2.js +30 -30
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +11 -13
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +51 -70
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +37 -23
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
- package/dist/composables/useCustomInterfaceAppearance.js +46 -56
- package/dist/composables/useHtmlValidator.js +82 -87
- package/dist/composables/useRecommendation.js +35 -40
- package/dist/composables/useStripo.js +30 -30
- package/dist/config/migrator/itemsBlockMigrator.js +257 -167
- package/dist/enums/extensions/recommendationBlock.js +31 -38
- package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
- package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
- package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
- package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
- package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
- package/dist/extensions/Blocks/Items/template.js +219 -204
- package/dist/extensions/Blocks/Recommendation/block.js +39 -43
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +35 -40
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -84
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +90 -189
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +16 -26
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
- package/dist/guido.css +1 -1
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
- package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
- package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
- package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -9
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +2 -7
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -75
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
- package/dist/src/stores/onboarding.d.ts +0 -377
- package/dist/static/styles/components/recommendation-strategy.css.js +4 -34
- package/dist/stores/onboarding.js +36 -41
- package/dist/utils/pairProductVariables.js +71 -71
- package/dist/utils/templatePreparation.js +55 -55
- package/package.json +1 -1
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +0 -21
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +0 -47
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +0 -24
- package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -14
- package/dist/static/styles/components/skeleton.css.js +0 -23
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { getRecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import { defineStore as
|
|
1
|
+
import { getRecommendationFeedSourceMaps as b, getOperatorOptions as G, PriceAttributes as v } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as D } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as F } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
5
5
|
import "../constants/selectors.js";
|
|
6
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
7
|
-
import { DEFAULT_NODE_CONFIG as
|
|
8
|
-
import { getDefaultProducts as
|
|
9
|
-
import { generateCompleteFilterQuery as
|
|
10
|
-
import { getPartnerRecommendationParams as
|
|
11
|
-
import { sanitizeProductIds as
|
|
12
|
-
import { isFilterValid as
|
|
13
|
-
import {
|
|
14
|
-
const
|
|
15
|
-
let
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
function G() {
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
|
|
7
|
+
import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
|
|
8
|
+
import { getDefaultProducts as R } from "../templates/utils.js";
|
|
9
|
+
import { generateCompleteFilterQuery as k } from "../utils/filterUtil.js";
|
|
10
|
+
import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
|
|
11
|
+
import { sanitizeProductIds as A } from "../utils/productIds.js";
|
|
12
|
+
import { isFilterValid as B } from "../validation/filterSchema.js";
|
|
13
|
+
import { isConfigValid as M } from "../validation/requiredFields.js";
|
|
14
|
+
const u = D();
|
|
15
|
+
let f = null, g = null, h = null, S = null;
|
|
16
|
+
const p = /* @__PURE__ */ new Map();
|
|
17
|
+
function w() {
|
|
19
18
|
return {
|
|
20
|
-
cardsInRow:
|
|
19
|
+
cardsInRow: U,
|
|
21
20
|
currencySettings: {
|
|
22
21
|
name: "USD",
|
|
23
22
|
value: "USD",
|
|
@@ -31,17 +30,13 @@ function G() {
|
|
|
31
30
|
productIds: [],
|
|
32
31
|
id: 1,
|
|
33
32
|
language: "en_US",
|
|
34
|
-
mobileCardsInRow:
|
|
33
|
+
mobileCardsInRow: _,
|
|
35
34
|
mobileLayoutEnabled: !1,
|
|
36
35
|
orientation: "grid",
|
|
37
36
|
recommendedProducts: [],
|
|
38
37
|
sendProductRequestFlag: !1,
|
|
39
38
|
shuffleProducts: !1,
|
|
40
|
-
|
|
41
|
-
// that default is what reached buildCampaignUrl and baked a most-popular feed URL
|
|
42
|
-
// for a block the user never configured (SD-149916). Legacy blocks still get their real
|
|
43
|
-
// algorithm from the node-config sync or the save-time seed.
|
|
44
|
-
strategy: P().isFeatureEnabled("reusableRecommendationStrategy") ? "" : "mostPopular",
|
|
39
|
+
strategy: "mostPopular",
|
|
45
40
|
strategyId: "",
|
|
46
41
|
textTrimming: !0,
|
|
47
42
|
unresponsive: !1,
|
|
@@ -51,9 +46,9 @@ function G() {
|
|
|
51
46
|
priceHideIfSameAsDiscounted: !1
|
|
52
47
|
};
|
|
53
48
|
}
|
|
54
|
-
function
|
|
49
|
+
function C() {
|
|
55
50
|
return {
|
|
56
|
-
recommendationConfigs:
|
|
51
|
+
recommendationConfigs: w(),
|
|
57
52
|
recommendationProducts: [],
|
|
58
53
|
filterStatus: !1,
|
|
59
54
|
filterSelectionDrawerStatus: !1,
|
|
@@ -65,7 +60,7 @@ function w() {
|
|
|
65
60
|
syncedConfigFingerprint: null
|
|
66
61
|
};
|
|
67
62
|
}
|
|
68
|
-
const
|
|
63
|
+
const z = () => ({
|
|
69
64
|
recommendationCampaignUrls: {},
|
|
70
65
|
activePredictiveAlgorithms: [],
|
|
71
66
|
languages: {},
|
|
@@ -74,14 +69,11 @@ const $ = () => ({
|
|
|
74
69
|
strategies: [],
|
|
75
70
|
strategiesLoading: !1,
|
|
76
71
|
strategyUrlTemplates: {},
|
|
77
|
-
strategiesFetched: !1,
|
|
78
|
-
strategiesSettled: !1,
|
|
79
72
|
blockStates: {},
|
|
80
73
|
currentRecommendationId: null,
|
|
81
|
-
strategyPanelOpen: !1,
|
|
82
74
|
configVersion: 0
|
|
83
|
-
}),
|
|
84
|
-
state: () =>
|
|
75
|
+
}), Y = P("guidoRecommendationExtension", {
|
|
76
|
+
state: () => z(),
|
|
85
77
|
getters: {
|
|
86
78
|
// ====================================================================
|
|
87
79
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -91,7 +83,7 @@ const $ = () => ({
|
|
|
91
83
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
92
84
|
*/
|
|
93
85
|
recommendationConfigs(t) {
|
|
94
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
86
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
|
|
95
87
|
},
|
|
96
88
|
/**
|
|
97
89
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -146,8 +138,8 @@ const $ = () => ({
|
|
|
146
138
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
147
139
|
},
|
|
148
140
|
getActivePredictiveAlgorithms: (t) => {
|
|
149
|
-
const e =
|
|
150
|
-
return t.activePredictiveAlgorithms.filter((n) => !
|
|
141
|
+
const e = b(), r = [];
|
|
142
|
+
return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
|
|
151
143
|
r.push(...e.filter((s) => s.id === n));
|
|
152
144
|
}), r.map((n) => ({
|
|
153
145
|
text: n.name,
|
|
@@ -165,7 +157,7 @@ const $ = () => ({
|
|
|
165
157
|
getFilterList() {
|
|
166
158
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
167
159
|
let e;
|
|
168
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
160
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
169
161
|
text: t.displayName,
|
|
170
162
|
value: e,
|
|
171
163
|
type: t.attributeType
|
|
@@ -187,7 +179,7 @@ const $ = () => ({
|
|
|
187
179
|
setCurrentBlock(t) {
|
|
188
180
|
this.blockStates[t] || (this.blockStates = {
|
|
189
181
|
...this.blockStates,
|
|
190
|
-
[t]:
|
|
182
|
+
[t]: C()
|
|
191
183
|
}), this.currentRecommendationId = t;
|
|
192
184
|
},
|
|
193
185
|
/**
|
|
@@ -247,7 +239,7 @@ const $ = () => ({
|
|
|
247
239
|
* `isInitialized`) alone.
|
|
248
240
|
*/
|
|
249
241
|
seedBlockUrlConfig(t, e) {
|
|
250
|
-
const r = (o,
|
|
242
|
+
const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
|
|
251
243
|
name: e.currencyCode,
|
|
252
244
|
value: e.currencyCode,
|
|
253
245
|
symbol: e.currencySymbol,
|
|
@@ -255,7 +247,7 @@ const $ = () => ({
|
|
|
255
247
|
decimalCount: String(e.currencyDecimalCount),
|
|
256
248
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
257
249
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
258
|
-
}, s = !this.blockStates[t], i = s ?
|
|
250
|
+
}, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
|
|
259
251
|
i.recommendationConfigs = {
|
|
260
252
|
...i.recommendationConfigs,
|
|
261
253
|
strategy: e.strategy,
|
|
@@ -294,7 +286,7 @@ const $ = () => ({
|
|
|
294
286
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
295
287
|
*/
|
|
296
288
|
createDefaultFilter(t, e) {
|
|
297
|
-
const [r] = this.getFilterList, [n] =
|
|
289
|
+
const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
|
|
298
290
|
return {
|
|
299
291
|
type: "standardFilter",
|
|
300
292
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
@@ -354,97 +346,29 @@ const $ = () => ({
|
|
|
354
346
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
|
|
355
347
|
},
|
|
356
348
|
async fetchStrategies() {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
await R;
|
|
360
|
-
} catch {
|
|
361
|
-
}
|
|
362
|
-
if (this.strategiesFetched)
|
|
349
|
+
if (S) {
|
|
350
|
+
await S;
|
|
363
351
|
return;
|
|
364
|
-
|
|
352
|
+
}
|
|
353
|
+
S = (async () => {
|
|
365
354
|
this.strategiesLoading = !0;
|
|
366
355
|
try {
|
|
367
|
-
|
|
368
|
-
if (t !== b)
|
|
369
|
-
return;
|
|
370
|
-
this.strategies = r, this.strategiesFetched = !0;
|
|
356
|
+
this.strategies = await u.fetchRecommendationStrategies();
|
|
371
357
|
} finally {
|
|
372
|
-
this.strategiesLoading = !1
|
|
358
|
+
this.strategiesLoading = !1;
|
|
373
359
|
}
|
|
374
360
|
})();
|
|
375
|
-
R = e;
|
|
376
361
|
try {
|
|
377
|
-
await
|
|
362
|
+
await S;
|
|
378
363
|
} finally {
|
|
379
|
-
|
|
364
|
+
S = null;
|
|
380
365
|
}
|
|
381
366
|
},
|
|
382
|
-
invalidateStrategies() {
|
|
383
|
-
this.strategiesFetched = !1, this.strategiesSettled = !1, b += 1;
|
|
384
|
-
},
|
|
385
|
-
/**
|
|
386
|
-
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
387
|
-
* the user comes back. `visibilitychange` only: a `focus` listener would also fire when
|
|
388
|
-
* focus merely returns from the Stripo canvas iframe to the panel, refetching and
|
|
389
|
-
* regenerating the canvas while the user never left the editor (SD-149916).
|
|
390
|
-
*
|
|
391
|
-
* Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
|
|
392
|
-
* strategy in it and come back again — a listener that disarmed on the first return would
|
|
393
|
-
* leave that one missing from the list. It disarms on the first return AFTER that tab is
|
|
394
|
-
* closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
|
|
395
|
-
* once the user actually opens a strategy page, so anyone who never does pays nothing.
|
|
396
|
-
*/
|
|
397
|
-
_armStrategyPageReturn(t) {
|
|
398
|
-
const e = window.open(t, "_blank");
|
|
399
|
-
if (!e)
|
|
400
|
-
return;
|
|
401
|
-
e.opener = null, l == null || l();
|
|
402
|
-
let r = !1;
|
|
403
|
-
const n = () => {
|
|
404
|
-
document.hidden || r || (e != null && e.closed && (l == null || l()), r = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
|
|
405
|
-
}).finally(() => {
|
|
406
|
-
r = !1;
|
|
407
|
-
}));
|
|
408
|
-
};
|
|
409
|
-
document.addEventListener("visibilitychange", n), l = () => {
|
|
410
|
-
document.removeEventListener("visibilitychange", n), l = null;
|
|
411
|
-
};
|
|
412
|
-
},
|
|
413
|
-
/**
|
|
414
|
-
* Reloads the products of the block the user is on, so an edit made in the strategy tab
|
|
415
|
-
* lands on the canvas instead of waiting for the assign drawer to be reopened.
|
|
416
|
-
*
|
|
417
|
-
* Only the selected block: the canvas regeneration is driven off the active block's
|
|
418
|
-
* product array, so refreshing an unselected block would fetch without redrawing it.
|
|
419
|
-
*/
|
|
420
|
-
async _refreshAssignedStrategyProducts() {
|
|
421
|
-
var e;
|
|
422
|
-
const t = this.currentRecommendationId;
|
|
423
|
-
t === null || !((e = this.blockStates[t]) != null && e.recommendationConfigs.strategyId) || await this.fetchRecommendationProducts();
|
|
424
|
-
},
|
|
425
|
-
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
426
|
-
disposeStrategyPageReturn() {
|
|
427
|
-
l == null || l();
|
|
428
|
-
},
|
|
429
|
-
/**
|
|
430
|
-
* Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
|
|
431
|
-
* new strategy is offered; the user picks it themselves.
|
|
432
|
-
*/
|
|
433
|
-
openStrategyCreation() {
|
|
434
|
-
this._armStrategyPageReturn(_.RECOMMENDATION_STRATEGY_CREATE_PATH);
|
|
435
|
-
},
|
|
436
|
-
/**
|
|
437
|
-
* Opens the strategy's edit page. Every return refreshes the list so the block reflects the
|
|
438
|
-
* edited configuration.
|
|
439
|
-
*/
|
|
440
|
-
openStrategyEdit(t) {
|
|
441
|
-
this._armStrategyPageReturn(D(t));
|
|
442
|
-
},
|
|
443
367
|
async resolveStrategyUrlTemplate(t, e) {
|
|
444
368
|
const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
|
|
445
369
|
if (s)
|
|
446
370
|
return s;
|
|
447
|
-
const { full_path: i = "" } = await
|
|
371
|
+
const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
|
|
448
372
|
return n && i && (this.strategyUrlTemplates = {
|
|
449
373
|
...this.strategyUrlTemplates,
|
|
450
374
|
[n]: i
|
|
@@ -457,27 +381,23 @@ const $ = () => ({
|
|
|
457
381
|
});
|
|
458
382
|
},
|
|
459
383
|
removeStrategy() {
|
|
460
|
-
this.patchCurrentBlockConfig({
|
|
461
|
-
strategyId: "",
|
|
462
|
-
strategy: "",
|
|
463
|
-
size: B.size
|
|
464
|
-
});
|
|
384
|
+
this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
|
|
465
385
|
},
|
|
466
386
|
// ====================================================================
|
|
467
387
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
468
388
|
// ====================================================================
|
|
469
389
|
async fetchRecommendationCreateData() {
|
|
470
390
|
if (!this.activePredictiveAlgorithms.length) {
|
|
471
|
-
if (
|
|
472
|
-
await
|
|
391
|
+
if (f) {
|
|
392
|
+
await f;
|
|
473
393
|
return;
|
|
474
394
|
}
|
|
475
|
-
|
|
395
|
+
f = (async () => {
|
|
476
396
|
const {
|
|
477
397
|
activePredictiveAlgorithms: t,
|
|
478
398
|
languages: e,
|
|
479
399
|
currencies: r
|
|
480
|
-
} = await
|
|
400
|
+
} = await u.fetchRecommendationCreateData();
|
|
481
401
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
482
402
|
const n = this.blockStates[this.currentRecommendationId];
|
|
483
403
|
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
@@ -485,26 +405,26 @@ const $ = () => ({
|
|
|
485
405
|
this.currencyList = r;
|
|
486
406
|
})();
|
|
487
407
|
try {
|
|
488
|
-
await
|
|
408
|
+
await f;
|
|
489
409
|
} finally {
|
|
490
|
-
|
|
410
|
+
f = null;
|
|
491
411
|
}
|
|
492
412
|
}
|
|
493
413
|
},
|
|
494
414
|
async fetchRecommendationFilters() {
|
|
495
415
|
if (!Object.keys(this.filterList).length) {
|
|
496
|
-
if (
|
|
497
|
-
await
|
|
416
|
+
if (g) {
|
|
417
|
+
await g;
|
|
498
418
|
return;
|
|
499
419
|
}
|
|
500
|
-
|
|
501
|
-
const t = await
|
|
420
|
+
g = (async () => {
|
|
421
|
+
const t = await u.fetchRecommendationFilters();
|
|
502
422
|
this.filterList = t;
|
|
503
423
|
})();
|
|
504
424
|
try {
|
|
505
|
-
await
|
|
425
|
+
await g;
|
|
506
426
|
} finally {
|
|
507
|
-
|
|
427
|
+
g = null;
|
|
508
428
|
}
|
|
509
429
|
}
|
|
510
430
|
},
|
|
@@ -533,7 +453,7 @@ const $ = () => ({
|
|
|
533
453
|
const n = [...e.recommendationConfigs.filters];
|
|
534
454
|
n[r] = {
|
|
535
455
|
...t,
|
|
536
|
-
isValid:
|
|
456
|
+
isValid: B(t)
|
|
537
457
|
}, e.recommendationConfigs.filters = n;
|
|
538
458
|
}
|
|
539
459
|
},
|
|
@@ -547,10 +467,10 @@ const $ = () => ({
|
|
|
547
467
|
let i = 1;
|
|
548
468
|
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
549
469
|
} else {
|
|
550
|
-
const i = [...new Set(n.map((
|
|
551
|
-
n = n.map((
|
|
552
|
-
...
|
|
553
|
-
filterGroup: o.get(
|
|
470
|
+
const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
|
|
471
|
+
n = n.map((c) => ({
|
|
472
|
+
...c,
|
|
473
|
+
filterGroup: o.get(c.filterGroup) ?? c.filterGroup
|
|
554
474
|
}));
|
|
555
475
|
}
|
|
556
476
|
e.recommendationConfigs.filters = n;
|
|
@@ -571,7 +491,7 @@ const $ = () => ({
|
|
|
571
491
|
}), e.recommendationConfigs.filters = r;
|
|
572
492
|
},
|
|
573
493
|
generateFilterQuery() {
|
|
574
|
-
return
|
|
494
|
+
return k(this.recommendationConfigs.filters);
|
|
575
495
|
},
|
|
576
496
|
/**
|
|
577
497
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -579,52 +499,33 @@ const $ = () => ({
|
|
|
579
499
|
* every block's recommendationConfigs across user edits.
|
|
580
500
|
*/
|
|
581
501
|
hasInvalidBlock() {
|
|
582
|
-
return Object.values(this.blockStates).some((t) => !
|
|
583
|
-
},
|
|
584
|
-
/**
|
|
585
|
-
* Which required fields are missing across the design's blocks, so the save
|
|
586
|
-
* toaster can name the cause instead of always showing the generic message.
|
|
587
|
-
*/
|
|
588
|
-
invalidBlockFields() {
|
|
589
|
-
return Object.values(this.blockStates).flatMap((t) => V(t.recommendationConfigs, this));
|
|
502
|
+
return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
|
|
590
503
|
},
|
|
591
504
|
// ====================================================================
|
|
592
505
|
// Per-Block Product Fetching
|
|
593
506
|
// ====================================================================
|
|
594
507
|
async fetchRecommendationProducts() {
|
|
595
|
-
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
I = t, y = this._doFetchProducts();
|
|
607
|
-
try {
|
|
608
|
-
await y;
|
|
609
|
-
} finally {
|
|
610
|
-
I === t && (y = null, I = "");
|
|
508
|
+
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
509
|
+
if (h) {
|
|
510
|
+
await h;
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
h = this._doFetchProducts();
|
|
514
|
+
try {
|
|
515
|
+
await h;
|
|
516
|
+
} finally {
|
|
517
|
+
h = null;
|
|
518
|
+
}
|
|
611
519
|
}
|
|
612
520
|
},
|
|
613
521
|
async _doFetchProducts() {
|
|
614
|
-
var
|
|
615
|
-
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n =
|
|
522
|
+
var d;
|
|
523
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
|
|
616
524
|
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
617
525
|
await this._doFetchStrategyProducts(t);
|
|
618
526
|
return;
|
|
619
527
|
}
|
|
620
|
-
const s = (
|
|
621
|
-
h.set(t, s);
|
|
622
|
-
const i = parseInt(r.size) || 6;
|
|
623
|
-
if (!r.strategy) {
|
|
624
|
-
this._setBlockProducts(t, [], i);
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
const o = r.filters.filter((d) => d.isValid), a = F(o), u = ((g = C().find((d) => d.key === r.strategy)) == null ? void 0 : g.path) || "", c = {
|
|
528
|
+
const s = r.filters.filter((m) => m.isValid), i = k(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
|
|
628
529
|
locale: r.language,
|
|
629
530
|
currency: r.currencySettings.value,
|
|
630
531
|
partnerName: n.partnerName,
|
|
@@ -632,21 +533,21 @@ const $ = () => ({
|
|
|
632
533
|
details: !0,
|
|
633
534
|
campaignId: n.variationId
|
|
634
535
|
};
|
|
635
|
-
r.strategy === "manualMerchandising" ?
|
|
636
|
-
|
|
637
|
-
|
|
536
|
+
r.strategy === "manualMerchandising" ? a.productId = A(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
537
|
+
a,
|
|
538
|
+
x(n.partnerName, r.strategy)
|
|
638
539
|
);
|
|
639
|
-
let
|
|
540
|
+
let l;
|
|
640
541
|
try {
|
|
641
|
-
|
|
542
|
+
l = await u.fetchRecommendationProducts(o, a);
|
|
642
543
|
} catch {
|
|
643
|
-
|
|
544
|
+
l = [];
|
|
644
545
|
}
|
|
645
|
-
|
|
546
|
+
this._setBlockProducts(t, l, c);
|
|
646
547
|
},
|
|
647
548
|
async _doFetchStrategyProducts(t) {
|
|
648
|
-
const e = (
|
|
649
|
-
|
|
549
|
+
const e = (p.get(t) ?? 0) + 1;
|
|
550
|
+
p.set(t, e);
|
|
650
551
|
const { recommendationConfigs: r } = this.blockStates[t];
|
|
651
552
|
let n = [], s = parseInt(r.size) || 6;
|
|
652
553
|
try {
|
|
@@ -656,25 +557,25 @@ const $ = () => ({
|
|
|
656
557
|
);
|
|
657
558
|
if (i) {
|
|
658
559
|
s = parseInt(String(i.size ?? "")) || s;
|
|
659
|
-
const o = r.currencySettings.value,
|
|
660
|
-
|
|
560
|
+
const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = m.length ? `${d}?${m.join("&")}` : d;
|
|
561
|
+
y && (n = await u.fetchRecommendationProductsByUrl(y));
|
|
661
562
|
}
|
|
662
563
|
} catch {
|
|
663
564
|
n = [];
|
|
664
565
|
}
|
|
665
|
-
|
|
566
|
+
p.get(t) === e && this._setBlockProducts(t, n, s);
|
|
666
567
|
},
|
|
667
568
|
_setBlockProducts(t, e, r) {
|
|
668
569
|
if (!this.blockStates[t])
|
|
669
570
|
return;
|
|
670
|
-
const n = e.length > 0 ? e :
|
|
571
|
+
const n = e.length > 0 ? e : R(r);
|
|
671
572
|
this.blockStates[t].recommendationProducts = [
|
|
672
573
|
...n.slice(0, r),
|
|
673
|
-
...
|
|
574
|
+
...R(Math.max(0, r - n.length))
|
|
674
575
|
];
|
|
675
576
|
}
|
|
676
577
|
}
|
|
677
578
|
});
|
|
678
579
|
export {
|
|
679
|
-
|
|
580
|
+
Y as useRecommendationExtensionStore
|
|
680
581
|
};
|
|
@@ -1,32 +1,22 @@
|
|
|
1
|
-
import { ModificationDescription as
|
|
2
|
-
import { RECOMMENDATION_ID_ATTR as
|
|
3
|
-
import { isPartnerManagedBlock as
|
|
4
|
-
import { RecommendationConfigService as
|
|
5
|
-
let
|
|
6
|
-
function
|
|
7
|
-
|
|
1
|
+
import { ModificationDescription as f } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
+
import { RECOMMENDATION_ID_ATTR as m } from "../constants/selectors.js";
|
|
3
|
+
import { isPartnerManagedBlock as a, updateProductContentInPlace as d, regenerateProductRowsWithStyles as l } from "../controls/main/utils.js";
|
|
4
|
+
import { RecommendationConfigService as s } from "../services/configService.js";
|
|
5
|
+
let e = null;
|
|
6
|
+
function N(r) {
|
|
7
|
+
e = r;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
9
|
+
function D(r, c, i, u) {
|
|
10
|
+
const n = e == null ? void 0 : e.getDocumentRootHtmlNode();
|
|
11
|
+
if (!e || !n || !("querySelector" in n))
|
|
12
12
|
return !1;
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
13
|
+
const t = n.querySelector(`[${m}="${r}"]`);
|
|
14
|
+
if (!t)
|
|
15
15
|
return !1;
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
return t.apply(new g(l)), !0;
|
|
19
|
-
let f = !1;
|
|
20
|
-
return C({
|
|
21
|
-
currentNode: e,
|
|
22
|
-
documentModifier: t,
|
|
23
|
-
products: c,
|
|
24
|
-
onApplied: () => {
|
|
25
|
-
f = !0;
|
|
26
|
-
}
|
|
27
|
-
}) || (f = N({ currentNode: e, documentModifier: t, products: c })), !f && d && t.apply(new g(l)), !0;
|
|
16
|
+
const o = e.getDocumentModifier();
|
|
17
|
+
return s.stageConfig(o, t, c), a(t) ? (o.apply(new f(u)), !0) : (d({ currentNode: t, documentModifier: o, products: i }) || l({ currentNode: t, documentModifier: o, products: i }), !0);
|
|
28
18
|
}
|
|
29
19
|
export {
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
D as commitBlockChangeOutsidePanel,
|
|
21
|
+
N as registerNodeConfigWriter
|
|
32
22
|
};
|
|
@@ -1,43 +1,34 @@
|
|
|
1
|
-
const
|
|
1
|
+
const l = [
|
|
2
2
|
{
|
|
3
3
|
key: "locale",
|
|
4
4
|
getValue: (e) => e.language,
|
|
5
5
|
getAvailableOptions: (e) => Object.keys(e.languages)
|
|
6
6
|
},
|
|
7
|
-
{
|
|
8
|
-
// A block feeds from either an assigned strategy (RRS) or an algorithm (legacy).
|
|
9
|
-
// Only a fresh RRS block has neither, and its feed URL would otherwise be built
|
|
10
|
-
// from an empty algorithm path.
|
|
11
|
-
key: o,
|
|
12
|
-
getValue: (e) => e.strategyId || e.strategy
|
|
13
|
-
},
|
|
14
7
|
{
|
|
15
8
|
key: "currency",
|
|
16
9
|
getValue: (e) => e.currencySettings.value,
|
|
17
10
|
getAvailableOptions: (e) => e.currencyList.map((n) => n.text),
|
|
18
11
|
canBeEmpty: !0
|
|
19
12
|
}
|
|
20
|
-
],
|
|
21
|
-
function c(e, n, i =
|
|
13
|
+
], o = "newsletter.recommendation-fill-required-fields";
|
|
14
|
+
function c(e, n, i = l) {
|
|
22
15
|
return i.filter((t) => {
|
|
23
|
-
var
|
|
16
|
+
var u;
|
|
24
17
|
if (t.condition && !t.condition(e))
|
|
25
18
|
return !1;
|
|
26
|
-
const
|
|
27
|
-
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)
|
|
28
21
|
return !1;
|
|
29
|
-
const
|
|
30
|
-
return
|
|
22
|
+
const a = t.getValue(e);
|
|
23
|
+
return a ? r !== void 0 && !r.includes(a) : !0;
|
|
31
24
|
}).map((t) => t.key);
|
|
32
25
|
}
|
|
33
|
-
function
|
|
26
|
+
function s(e, n) {
|
|
34
27
|
return c(e, n).length === 0;
|
|
35
28
|
}
|
|
36
29
|
export {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
l as RecommendationRequiredFieldsKey,
|
|
40
|
-
o as STRATEGY_FIELD_KEY,
|
|
30
|
+
l as REQUIRED_RECOMMENDATION_FIELDS,
|
|
31
|
+
o as RecommendationRequiredFieldsKey,
|
|
41
32
|
c as getInvalidFields,
|
|
42
|
-
|
|
33
|
+
s as isConfigValid
|
|
43
34
|
};
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
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-1ca6baf0]{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-
|
|
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-1ca6baf0]{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-050dfa52]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-050dfa52]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-050dfa52]{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-2580a7d9]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9] .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}
|
|
@@ -5,9 +5,7 @@ export declare const URLS: {
|
|
|
5
5
|
PRODUCT_ATTRIBUTES_PATH: string;
|
|
6
6
|
RECOMMENDATION_STRATEGIES_PATH: string;
|
|
7
7
|
RECOMMENDATION_STRATEGIES_PANEL_PATH: string;
|
|
8
|
-
RECOMMENDATION_STRATEGY_CREATE_PATH: string;
|
|
9
8
|
};
|
|
10
|
-
export declare const strategyEditPath: (strategyId: string | number) => string;
|
|
11
9
|
export declare const QUERY_PARAMS: {
|
|
12
10
|
CLIENT_ID: string;
|
|
13
11
|
};
|