@useinsider/guido 3.18.1-beta.e489d08 → 3.18.1-beta.e609a33
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 +53 -65
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
- package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +34 -34
- package/dist/composables/useCustomInterfaceAppearance.js +41 -46
- package/dist/composables/useHtmlValidator.js +79 -84
- package/dist/composables/useHttp.js +24 -22
- package/dist/composables/useRecommendation.js +18 -21
- package/dist/composables/useStripo.js +7 -7
- package/dist/enums/extensions/recommendationBlock.js +31 -38
- package/dist/extensions/Blocks/Recommendation/block.js +39 -43
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +57 -62
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -80
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +73 -150
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
- package/dist/guido.css +1 -1
- package/dist/services/templateLibraryApi.js +39 -37
- package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
- 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/store/recommendation.d.ts +0 -61
- 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 -51
- package/dist/stores/onboarding.js +36 -41
- package/dist/utils/templatePreparation.js +50 -50
- 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/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +0 -2
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { ACADEMY_LINKS as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const k = "recommendation-strategy-control";
|
|
10
|
-
class L extends f {
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var y = (r, s, t) => s in r ? d(r, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[s] = t;
|
|
3
|
+
var o = (r, s, t) => y(r, typeof s != "symbol" ? s + "" : s, t);
|
|
4
|
+
import { ACADEMY_LINKS as m } from "../../../../../enums/academy.js";
|
|
5
|
+
import { CommonControl as h } from "../../../common-control.js";
|
|
6
|
+
import { useRecommendationExtensionStore as u } from "../../store/recommendation.js";
|
|
7
|
+
const p = "recommendation-strategy-control";
|
|
8
|
+
class f extends h {
|
|
11
9
|
constructor() {
|
|
12
10
|
super(...arguments);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
r(this, "storeUnsubscription", () => {
|
|
11
|
+
o(this, "store", u());
|
|
12
|
+
o(this, "storeUnsubscription", () => {
|
|
16
13
|
});
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
o(this, "listeners", []);
|
|
15
|
+
o(this, "lastPaintedState", null);
|
|
19
16
|
}
|
|
20
17
|
getId() {
|
|
21
|
-
return
|
|
18
|
+
return p;
|
|
22
19
|
}
|
|
23
20
|
getTemplate() {
|
|
24
21
|
const t = this.api.translate(
|
|
@@ -26,34 +23,21 @@ class L extends f {
|
|
|
26
23
|
), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
|
|
27
24
|
return `
|
|
28
25
|
<div class="strategy-control-container">
|
|
29
|
-
<div
|
|
30
|
-
<
|
|
31
|
-
<span class="guido-skeleton guido-skeleton--strategy-title"></span>
|
|
32
|
-
</div>
|
|
33
|
-
<div class="strategy-control-description-row">
|
|
34
|
-
<span class="guido-skeleton guido-skeleton--strategy-description"></span>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="strategy-control-skeleton-row">
|
|
37
|
-
<span class="guido-skeleton guido-skeleton--strategy-cta"></span>
|
|
38
|
-
<span class="guido-skeleton guido-skeleton--strategy-cta"></span>
|
|
39
|
-
</div>
|
|
26
|
+
<div class="strategy-control-header">
|
|
27
|
+
<h3 class="strategy-control-title">${this.api.translate("Recommendation Strategy")}</h3>
|
|
40
28
|
</div>
|
|
41
|
-
<div
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</p>
|
|
54
|
-
</div>
|
|
55
|
-
<div data-strategy-empty-state style="display: none;">
|
|
56
|
-
${this._GuTwoColumns([
|
|
29
|
+
<div class="strategy-control-description-row">
|
|
30
|
+
<p class="strategy-control-description">
|
|
31
|
+
${t}
|
|
32
|
+
${e}
|
|
33
|
+
<a
|
|
34
|
+
href="${m.EMAIL_RECOMMENDATION_BLOCK}"
|
|
35
|
+
target="_blank"
|
|
36
|
+
rel="noopener noreferrer">${a}</a>.
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
<div data-strategy-empty-state>
|
|
40
|
+
${this._GuTwoColumns([
|
|
57
41
|
this._GuButton({
|
|
58
42
|
name: "assignStrategy",
|
|
59
43
|
label: this.api.translate("Assign Strategy"),
|
|
@@ -64,28 +48,26 @@ class L extends f {
|
|
|
64
48
|
name: "createStrategy",
|
|
65
49
|
label: this.api.translate("Create New Strategy"),
|
|
66
50
|
id: "guido__btn-create-strategy",
|
|
67
|
-
className: "strategy-control-cta primary"
|
|
51
|
+
className: "strategy-control-cta primary",
|
|
52
|
+
disabled: !0
|
|
68
53
|
})
|
|
69
54
|
], "strategy-control-cta-row")}
|
|
55
|
+
</div>
|
|
56
|
+
<div data-strategy-assigned-state style="display: none;">
|
|
57
|
+
<div class="strategy-control-name-band">
|
|
58
|
+
<span class="strategy-control-name" data-strategy-name></span>
|
|
70
59
|
</div>
|
|
71
|
-
<div
|
|
72
|
-
|
|
73
|
-
<span class="strategy-control-name" data-strategy-name></span>
|
|
74
|
-
<span
|
|
75
|
-
class="guido-skeleton guido-skeleton--strategy-name" data-strategy-name-skeleton></span>
|
|
76
|
-
</div>
|
|
77
|
-
<div class="strategy-control-actions">
|
|
78
|
-
${this._strategyAction({
|
|
60
|
+
<div class="strategy-control-actions">
|
|
61
|
+
${this._strategyAction({
|
|
79
62
|
id: "guido__btn-change-strategy",
|
|
80
63
|
label: this.api.translate("Change"),
|
|
81
64
|
modifier: "change"
|
|
82
65
|
})}
|
|
83
|
-
|
|
66
|
+
${this._strategyAction({
|
|
84
67
|
id: "guido__btn-remove-strategy",
|
|
85
68
|
label: this.api.translate("Remove"),
|
|
86
69
|
modifier: "remove"
|
|
87
70
|
})}
|
|
88
|
-
</div>
|
|
89
71
|
</div>
|
|
90
72
|
</div>
|
|
91
73
|
</div>
|
|
@@ -102,51 +84,41 @@ class L extends f {
|
|
|
102
84
|
`;
|
|
103
85
|
}
|
|
104
86
|
onRender() {
|
|
105
|
-
this._teardown(), this.
|
|
87
|
+
this._teardown(), this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
106
88
|
this._renderState();
|
|
107
|
-
}), this.store.recommendationConfigs.strategyId && !this.store.
|
|
89
|
+
}), this.store.recommendationConfigs.strategyId && !this.store.strategies.length && this.store.fetchStrategies().catch(() => {
|
|
108
90
|
});
|
|
109
91
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Whether the document itself says this block has no strategy.
|
|
112
|
-
*
|
|
113
|
-
* Read the node, not the store: when the main control cannot resolve the block id off the
|
|
114
|
-
* node it never syncs the persisted config, so the store still holds defaults (empty
|
|
115
|
-
* strategyId) for an assigned block.
|
|
116
|
-
*/
|
|
117
|
-
_isNodeUnassigned() {
|
|
118
|
-
return h.hasConfig(this.currentNode) && !h.getConfig(this.currentNode).strategyId;
|
|
119
|
-
}
|
|
120
92
|
onDestroy() {
|
|
121
93
|
this._teardown();
|
|
122
94
|
}
|
|
123
95
|
_teardown() {
|
|
124
|
-
this.
|
|
96
|
+
this.storeUnsubscription(), this.storeUnsubscription = () => {
|
|
125
97
|
}, this.lastPaintedState = null, this.listeners.forEach(({ element: t, handler: e }) => t.removeEventListener("click", e)), this.listeners = [];
|
|
126
98
|
}
|
|
127
99
|
_setupButtonListeners() {
|
|
128
100
|
const t = this.getContainer();
|
|
129
101
|
if (!t)
|
|
130
102
|
return;
|
|
131
|
-
const e = (a,
|
|
132
|
-
const
|
|
133
|
-
|
|
103
|
+
const e = (a, n) => {
|
|
104
|
+
const i = t.querySelector(a);
|
|
105
|
+
i && (i.addEventListener("click", n), this.listeners.push({ element: i, handler: n }));
|
|
134
106
|
};
|
|
135
|
-
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-
|
|
107
|
+
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal());
|
|
136
108
|
}
|
|
137
109
|
_renderState() {
|
|
138
|
-
var
|
|
139
|
-
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((
|
|
140
|
-
if (
|
|
110
|
+
var l;
|
|
111
|
+
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((l = this.store.assignedStrategy) == null ? void 0 : l.name) ?? "" : "", a = `${t}\0${e}`;
|
|
112
|
+
if (a === this.lastPaintedState)
|
|
141
113
|
return;
|
|
142
|
-
const
|
|
143
|
-
if (!
|
|
114
|
+
const n = this.getContainer();
|
|
115
|
+
if (!n)
|
|
144
116
|
return;
|
|
145
|
-
const
|
|
146
|
-
!
|
|
117
|
+
const i = n.querySelector("[data-strategy-empty-state]"), c = n.querySelector("[data-strategy-assigned-state]"), g = n.querySelector("[data-strategy-name]");
|
|
118
|
+
!i || !c || (i.style.display = t ? "none" : "", c.style.display = t ? "" : "none", g && t && (g.textContent = e || `#${t}`), this.lastPaintedState = a);
|
|
147
119
|
}
|
|
148
120
|
}
|
|
149
121
|
export {
|
|
150
|
-
|
|
151
|
-
|
|
122
|
+
p as STRATEGY_CONTROL_ID,
|
|
123
|
+
f as StrategyControl
|
|
152
124
|
};
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { getRecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi 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
3
|
import { useConfigStore as P } from "../../../../stores/config.js";
|
|
4
|
-
import { defineStore as
|
|
4
|
+
import { defineStore as F } 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 F() {
|
|
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, h = null, g = 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 F() {
|
|
|
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 F() {
|
|
|
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,
|
|
@@ -64,7 +59,7 @@ function w() {
|
|
|
64
59
|
filterSnapshot: null
|
|
65
60
|
};
|
|
66
61
|
}
|
|
67
|
-
const
|
|
62
|
+
const z = () => ({
|
|
68
63
|
recommendationCampaignUrls: {},
|
|
69
64
|
activePredictiveAlgorithms: [],
|
|
70
65
|
languages: {},
|
|
@@ -73,13 +68,11 @@ const j = () => ({
|
|
|
73
68
|
strategies: [],
|
|
74
69
|
strategiesLoading: !1,
|
|
75
70
|
strategyUrlTemplates: {},
|
|
76
|
-
strategiesFetched: !1,
|
|
77
71
|
blockStates: {},
|
|
78
72
|
currentRecommendationId: null,
|
|
79
|
-
strategyPanelOpen: !1,
|
|
80
73
|
configVersion: 0
|
|
81
|
-
}),
|
|
82
|
-
state: () =>
|
|
74
|
+
}), Y = F("guidoRecommendationExtension", {
|
|
75
|
+
state: () => z(),
|
|
83
76
|
getters: {
|
|
84
77
|
// ====================================================================
|
|
85
78
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -89,7 +82,7 @@ const j = () => ({
|
|
|
89
82
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
90
83
|
*/
|
|
91
84
|
recommendationConfigs(t) {
|
|
92
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
85
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
|
|
93
86
|
},
|
|
94
87
|
/**
|
|
95
88
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -144,8 +137,8 @@ const j = () => ({
|
|
|
144
137
|
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
145
138
|
},
|
|
146
139
|
getActivePredictiveAlgorithms: (t) => {
|
|
147
|
-
const e =
|
|
148
|
-
return t.activePredictiveAlgorithms.filter((n) => !
|
|
140
|
+
const e = b(), r = [];
|
|
141
|
+
return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
|
|
149
142
|
r.push(...e.filter((s) => s.id === n));
|
|
150
143
|
}), r.map((n) => ({
|
|
151
144
|
text: n.name,
|
|
@@ -163,7 +156,7 @@ const j = () => ({
|
|
|
163
156
|
getFilterList() {
|
|
164
157
|
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
165
158
|
let e;
|
|
166
|
-
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` :
|
|
159
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
167
160
|
text: t.displayName,
|
|
168
161
|
value: e,
|
|
169
162
|
type: t.attributeType
|
|
@@ -185,7 +178,7 @@ const j = () => ({
|
|
|
185
178
|
setCurrentBlock(t) {
|
|
186
179
|
this.blockStates[t] || (this.blockStates = {
|
|
187
180
|
...this.blockStates,
|
|
188
|
-
[t]:
|
|
181
|
+
[t]: C()
|
|
189
182
|
}), this.currentRecommendationId = t;
|
|
190
183
|
},
|
|
191
184
|
/**
|
|
@@ -253,7 +246,7 @@ const j = () => ({
|
|
|
253
246
|
decimalCount: String(e.currencyDecimalCount),
|
|
254
247
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
255
248
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
256
|
-
}, s = !this.blockStates[t], i = s ?
|
|
249
|
+
}, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
|
|
257
250
|
i.recommendationConfigs = {
|
|
258
251
|
...i.recommendationConfigs,
|
|
259
252
|
strategy: e.strategy,
|
|
@@ -292,7 +285,7 @@ const j = () => ({
|
|
|
292
285
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
293
286
|
*/
|
|
294
287
|
createDefaultFilter(t, e) {
|
|
295
|
-
const [r] = this.getFilterList, [n] =
|
|
288
|
+
const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
|
|
296
289
|
return {
|
|
297
290
|
type: "standardFilter",
|
|
298
291
|
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
@@ -352,87 +345,29 @@ const j = () => ({
|
|
|
352
345
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
|
|
353
346
|
},
|
|
354
347
|
async fetchStrategies() {
|
|
355
|
-
if (
|
|
348
|
+
if (S) {
|
|
349
|
+
await S;
|
|
356
350
|
return;
|
|
357
|
-
|
|
358
|
-
|
|
351
|
+
}
|
|
352
|
+
S = (async () => {
|
|
359
353
|
this.strategiesLoading = !0;
|
|
360
354
|
try {
|
|
361
|
-
|
|
362
|
-
if (t !== y)
|
|
363
|
-
return;
|
|
364
|
-
this.strategies = e, this.strategiesFetched = !0;
|
|
355
|
+
this.strategies = await u.fetchRecommendationStrategies();
|
|
365
356
|
} finally {
|
|
366
357
|
this.strategiesLoading = !1;
|
|
367
358
|
}
|
|
368
359
|
})();
|
|
369
360
|
try {
|
|
370
|
-
await
|
|
361
|
+
await S;
|
|
371
362
|
} finally {
|
|
372
|
-
|
|
363
|
+
S = null;
|
|
373
364
|
}
|
|
374
365
|
},
|
|
375
|
-
invalidateStrategies() {
|
|
376
|
-
this.strategiesFetched = !1, y += 1;
|
|
377
|
-
},
|
|
378
|
-
/**
|
|
379
|
-
* Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
|
|
380
|
-
* the user comes back. `visibilitychange` covers the tab case; `focus` covers the page
|
|
381
|
-
* landing in a separate window, where this document never goes hidden.
|
|
382
|
-
*
|
|
383
|
-
* Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
|
|
384
|
-
* strategy in it and come back again — a listener that disarmed on the first return would
|
|
385
|
-
* leave that one missing from the list. Armed only once the user actually opens a strategy
|
|
386
|
-
* page, so anyone who never does pays nothing.
|
|
387
|
-
*/
|
|
388
|
-
_armStrategyPageReturn(t) {
|
|
389
|
-
window.open(t, "_blank", "noopener"), u == null || u();
|
|
390
|
-
let e = !1;
|
|
391
|
-
const r = () => {
|
|
392
|
-
document.hidden || e || (e = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
|
|
393
|
-
}).finally(() => {
|
|
394
|
-
e = !1;
|
|
395
|
-
}));
|
|
396
|
-
};
|
|
397
|
-
document.addEventListener("visibilitychange", r), window.addEventListener("focus", r), u = () => {
|
|
398
|
-
document.removeEventListener("visibilitychange", r), window.removeEventListener("focus", r), u = null;
|
|
399
|
-
};
|
|
400
|
-
},
|
|
401
|
-
/**
|
|
402
|
-
* Reloads the products of the block the user is on, so an edit made in the strategy tab
|
|
403
|
-
* lands on the canvas instead of waiting for the assign drawer to be reopened.
|
|
404
|
-
*
|
|
405
|
-
* Only the selected block: the canvas regeneration is driven off the active block's
|
|
406
|
-
* product array, so refreshing an unselected block would fetch without redrawing it.
|
|
407
|
-
*/
|
|
408
|
-
async _refreshAssignedStrategyProducts() {
|
|
409
|
-
var e;
|
|
410
|
-
const t = this.currentRecommendationId;
|
|
411
|
-
t === null || !((e = this.blockStates[t]) != null && e.recommendationConfigs.strategyId) || await this.fetchRecommendationProducts();
|
|
412
|
-
},
|
|
413
|
-
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
414
|
-
disposeStrategyPageReturn() {
|
|
415
|
-
u == null || u();
|
|
416
|
-
},
|
|
417
|
-
/**
|
|
418
|
-
* Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
|
|
419
|
-
* new strategy is offered; the user picks it themselves.
|
|
420
|
-
*/
|
|
421
|
-
openStrategyCreation() {
|
|
422
|
-
this._armStrategyPageReturn(D.RECOMMENDATION_STRATEGY_CREATE_PATH);
|
|
423
|
-
},
|
|
424
|
-
/**
|
|
425
|
-
* Opens the strategy's edit page. Every return refreshes the list so the block reflects the
|
|
426
|
-
* edited configuration.
|
|
427
|
-
*/
|
|
428
|
-
openStrategyEdit(t) {
|
|
429
|
-
this._armStrategyPageReturn(G(t));
|
|
430
|
-
},
|
|
431
366
|
async resolveStrategyUrlTemplate(t, e) {
|
|
432
367
|
const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
|
|
433
368
|
if (s)
|
|
434
369
|
return s;
|
|
435
|
-
const { full_path: i = "" } = await
|
|
370
|
+
const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
|
|
436
371
|
return n && i && (this.strategyUrlTemplates = {
|
|
437
372
|
...this.strategyUrlTemplates,
|
|
438
373
|
[n]: i
|
|
@@ -445,23 +380,23 @@ const j = () => ({
|
|
|
445
380
|
});
|
|
446
381
|
},
|
|
447
382
|
removeStrategy() {
|
|
448
|
-
this.patchCurrentBlockConfig({ strategyId: "", size:
|
|
383
|
+
this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
|
|
449
384
|
},
|
|
450
385
|
// ====================================================================
|
|
451
386
|
// Shared Data Fetching (fetched once, used by all blocks)
|
|
452
387
|
// ====================================================================
|
|
453
388
|
async fetchRecommendationCreateData() {
|
|
454
389
|
if (!this.activePredictiveAlgorithms.length) {
|
|
455
|
-
if (
|
|
456
|
-
await
|
|
390
|
+
if (f) {
|
|
391
|
+
await f;
|
|
457
392
|
return;
|
|
458
393
|
}
|
|
459
|
-
|
|
394
|
+
f = (async () => {
|
|
460
395
|
const {
|
|
461
396
|
activePredictiveAlgorithms: t,
|
|
462
397
|
languages: e,
|
|
463
398
|
currencies: r
|
|
464
|
-
} = await
|
|
399
|
+
} = await u.fetchRecommendationCreateData();
|
|
465
400
|
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
466
401
|
const n = this.blockStates[this.currentRecommendationId];
|
|
467
402
|
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
@@ -469,26 +404,26 @@ const j = () => ({
|
|
|
469
404
|
this.currencyList = r;
|
|
470
405
|
})();
|
|
471
406
|
try {
|
|
472
|
-
await
|
|
407
|
+
await f;
|
|
473
408
|
} finally {
|
|
474
|
-
|
|
409
|
+
f = null;
|
|
475
410
|
}
|
|
476
411
|
}
|
|
477
412
|
},
|
|
478
413
|
async fetchRecommendationFilters() {
|
|
479
414
|
if (!Object.keys(this.filterList).length) {
|
|
480
|
-
if (
|
|
481
|
-
await
|
|
415
|
+
if (h) {
|
|
416
|
+
await h;
|
|
482
417
|
return;
|
|
483
418
|
}
|
|
484
|
-
|
|
485
|
-
const t = await
|
|
419
|
+
h = (async () => {
|
|
420
|
+
const t = await u.fetchRecommendationFilters();
|
|
486
421
|
this.filterList = t;
|
|
487
422
|
})();
|
|
488
423
|
try {
|
|
489
|
-
await
|
|
424
|
+
await h;
|
|
490
425
|
} finally {
|
|
491
|
-
|
|
426
|
+
h = null;
|
|
492
427
|
}
|
|
493
428
|
}
|
|
494
429
|
},
|
|
@@ -517,7 +452,7 @@ const j = () => ({
|
|
|
517
452
|
const n = [...e.recommendationConfigs.filters];
|
|
518
453
|
n[r] = {
|
|
519
454
|
...t,
|
|
520
|
-
isValid:
|
|
455
|
+
isValid: B(t)
|
|
521
456
|
}, e.recommendationConfigs.filters = n;
|
|
522
457
|
}
|
|
523
458
|
},
|
|
@@ -555,7 +490,7 @@ const j = () => ({
|
|
|
555
490
|
}), e.recommendationConfigs.filters = r;
|
|
556
491
|
},
|
|
557
492
|
generateFilterQuery() {
|
|
558
|
-
return
|
|
493
|
+
return k(this.recommendationConfigs.filters);
|
|
559
494
|
},
|
|
560
495
|
/**
|
|
561
496
|
* Validation-only check invoked at save-CTA time. Defined as an action
|
|
@@ -563,45 +498,33 @@ const j = () => ({
|
|
|
563
498
|
* every block's recommendationConfigs across user edits.
|
|
564
499
|
*/
|
|
565
500
|
hasInvalidBlock() {
|
|
566
|
-
return Object.values(this.blockStates).some((t) => !
|
|
567
|
-
},
|
|
568
|
-
/**
|
|
569
|
-
* Which required fields are missing across the design's blocks, so the save
|
|
570
|
-
* toaster can name the cause instead of always showing the generic message.
|
|
571
|
-
*/
|
|
572
|
-
invalidBlockFields() {
|
|
573
|
-
return Object.values(this.blockStates).flatMap((t) => z(t.recommendationConfigs, this));
|
|
501
|
+
return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
|
|
574
502
|
},
|
|
575
503
|
// ====================================================================
|
|
576
504
|
// Per-Block Product Fetching
|
|
577
505
|
// ====================================================================
|
|
578
506
|
async fetchRecommendationProducts() {
|
|
579
507
|
if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
|
|
580
|
-
if (
|
|
581
|
-
await
|
|
508
|
+
if (g) {
|
|
509
|
+
await g;
|
|
582
510
|
return;
|
|
583
511
|
}
|
|
584
|
-
|
|
512
|
+
g = this._doFetchProducts();
|
|
585
513
|
try {
|
|
586
|
-
await
|
|
514
|
+
await g;
|
|
587
515
|
} finally {
|
|
588
|
-
|
|
516
|
+
g = null;
|
|
589
517
|
}
|
|
590
518
|
}
|
|
591
519
|
},
|
|
592
520
|
async _doFetchProducts() {
|
|
593
|
-
var
|
|
521
|
+
var d;
|
|
594
522
|
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = P();
|
|
595
523
|
if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
596
524
|
await this._doFetchStrategyProducts(t);
|
|
597
525
|
return;
|
|
598
526
|
}
|
|
599
|
-
const s = parseInt(r.size) || 6
|
|
600
|
-
if (!r.strategy) {
|
|
601
|
-
this._setBlockProducts(t, [], s);
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
const i = r.filters.filter((m) => m.isValid), o = v(i), c = ((f = k().find((m) => m.key === r.strategy)) == null ? void 0 : f.path) || "", a = {
|
|
527
|
+
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 = {
|
|
605
528
|
locale: r.language,
|
|
606
529
|
currency: r.currencySettings.value,
|
|
607
530
|
partnerName: n.partnerName,
|
|
@@ -609,21 +532,21 @@ const j = () => ({
|
|
|
609
532
|
details: !0,
|
|
610
533
|
campaignId: n.variationId
|
|
611
534
|
};
|
|
612
|
-
r.strategy === "manualMerchandising" ? a.productId =
|
|
535
|
+
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(
|
|
613
536
|
a,
|
|
614
|
-
|
|
537
|
+
x(n.partnerName, r.strategy)
|
|
615
538
|
);
|
|
616
539
|
let l;
|
|
617
540
|
try {
|
|
618
|
-
l = await
|
|
541
|
+
l = await u.fetchRecommendationProducts(o, a);
|
|
619
542
|
} catch {
|
|
620
543
|
l = [];
|
|
621
544
|
}
|
|
622
|
-
this._setBlockProducts(t, l,
|
|
545
|
+
this._setBlockProducts(t, l, c);
|
|
623
546
|
},
|
|
624
547
|
async _doFetchStrategyProducts(t) {
|
|
625
|
-
const e = (
|
|
626
|
-
|
|
548
|
+
const e = (p.get(t) ?? 0) + 1;
|
|
549
|
+
p.set(t, e);
|
|
627
550
|
const { recommendationConfigs: r } = this.blockStates[t];
|
|
628
551
|
let n = [], s = parseInt(r.size) || 6;
|
|
629
552
|
try {
|
|
@@ -633,25 +556,25 @@ const j = () => ({
|
|
|
633
556
|
);
|
|
634
557
|
if (i) {
|
|
635
558
|
s = parseInt(String(i.size ?? "")) || s;
|
|
636
|
-
const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"),
|
|
637
|
-
|
|
559
|
+
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;
|
|
560
|
+
y && (n = await u.fetchRecommendationProductsByUrl(y));
|
|
638
561
|
}
|
|
639
562
|
} catch {
|
|
640
563
|
n = [];
|
|
641
564
|
}
|
|
642
|
-
|
|
565
|
+
p.get(t) === e && this._setBlockProducts(t, n, s);
|
|
643
566
|
},
|
|
644
567
|
_setBlockProducts(t, e, r) {
|
|
645
568
|
if (!this.blockStates[t])
|
|
646
569
|
return;
|
|
647
|
-
const n = e.length > 0 ? e :
|
|
570
|
+
const n = e.length > 0 ? e : R(r);
|
|
648
571
|
this.blockStates[t].recommendationProducts = [
|
|
649
572
|
...n.slice(0, r),
|
|
650
|
-
...
|
|
573
|
+
...R(Math.max(0, r - n.length))
|
|
651
574
|
];
|
|
652
575
|
}
|
|
653
576
|
}
|
|
654
577
|
});
|
|
655
578
|
export {
|
|
656
|
-
|
|
579
|
+
Y as useRecommendationExtensionStore
|
|
657
580
|
};
|