@useinsider/guido 3.20.0-beta.5c9442d → 3.20.0-beta.6e5144c
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/extensions/Blocks/Recommendation/controls/main/index.js +297 -213
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +170 -155
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +6 -6
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +22 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +7 -1
- package/package.json +2 -2
|
@@ -1,68 +1,77 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useConfig as
|
|
5
|
-
import { ModificationDescription as
|
|
6
|
-
import { CommonControl as
|
|
7
|
-
import { RRS_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as
|
|
8
|
-
import { RECOMMENDATION_ID_ATTR as
|
|
9
|
-
import { RecommendationConfigService as
|
|
1
|
+
var m = Object.defineProperty;
|
|
2
|
+
var C = (h, u, e) => u in h ? m(h, u, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[u] = e;
|
|
3
|
+
var s = (h, u, e) => C(h, typeof u != "symbol" ? u + "" : u, e);
|
|
4
|
+
import { useConfig as f } from "../../../../../composables/useConfig.js";
|
|
5
|
+
import { ModificationDescription as p } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
6
|
+
import { CommonControl as y } from "../../../common-control.js";
|
|
7
|
+
import { RRS_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as d } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RECOMMENDATION_ID_ATTR as N } from "../../constants/selectors.js";
|
|
9
|
+
import { RecommendationConfigService as l } from "../../services/configService.js";
|
|
10
10
|
import { useRecommendationExtensionStore as R } from "../../store/recommendation.js";
|
|
11
|
-
import { registerNodeConfigWriter as
|
|
12
|
-
import { AlgorithmControl as
|
|
13
|
-
import { ALGORITHM_CONTROL_ID as
|
|
14
|
-
import { CurrencyControl as
|
|
15
|
-
import { CURRENCY_CONTROL_ID as
|
|
16
|
-
import { FiltersControl as
|
|
17
|
-
import { FILTERS_CONTROL_ID as
|
|
18
|
-
import { LayoutOrientationControl as
|
|
19
|
-
import { LAYOUT_ORIENTATION_CONTROL_ID as
|
|
20
|
-
import { LocaleControl as
|
|
21
|
-
import { LOCALE_CONTROL_ID as
|
|
22
|
-
import { PricePlacementControl as
|
|
23
|
-
import { PRICE_PLACEMENT_CONTROL_ID as
|
|
24
|
-
import { ProductCountControl as
|
|
25
|
-
import { PRODUCT_COUNT_CONTROL_ID as
|
|
26
|
-
import { ProductLayoutControl as
|
|
27
|
-
import { PRODUCT_LAYOUT_CONTROL_ID as
|
|
11
|
+
import { registerNodeConfigWriter as I, commitBlockChangeOutsidePanel as P } from "../../utils/nodeConfigWriter.js";
|
|
12
|
+
import { AlgorithmControl as S } from "./algorithm.js";
|
|
13
|
+
import { ALGORITHM_CONTROL_ID as le } from "./algorithm.js";
|
|
14
|
+
import { CurrencyControl as b } from "./currency.js";
|
|
15
|
+
import { CURRENCY_CONTROL_ID as he } from "./currency.js";
|
|
16
|
+
import { FiltersControl as k } from "./filters.js";
|
|
17
|
+
import { FILTERS_CONTROL_ID as ge } from "./filters.js";
|
|
18
|
+
import { LayoutOrientationControl as T } from "./layoutOrientation.js";
|
|
19
|
+
import { LAYOUT_ORIENTATION_CONTROL_ID as Ce } from "./layoutOrientation.js";
|
|
20
|
+
import { LocaleControl as O } from "./locale.js";
|
|
21
|
+
import { LOCALE_CONTROL_ID as ye } from "./locale.js";
|
|
22
|
+
import { PricePlacementControl as B } from "./pricePlacement.js";
|
|
23
|
+
import { PRICE_PLACEMENT_CONTROL_ID as Ne } from "./pricePlacement.js";
|
|
24
|
+
import { ProductCountControl as F } from "./productCount.js";
|
|
25
|
+
import { PRODUCT_COUNT_CONTROL_ID as Ie } from "./productCount.js";
|
|
26
|
+
import { ProductLayoutControl as L } from "./productLayout.js";
|
|
27
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as Se } from "./productLayout.js";
|
|
28
28
|
import { ShuffleControl as D } from "./shuffle.js";
|
|
29
|
-
import { SHUFFLE_CONTROL_ID as
|
|
30
|
-
import { StrategyControl as
|
|
31
|
-
import { STRATEGY_CONTROL_ID as
|
|
32
|
-
import { setCurrencyAttributes as
|
|
33
|
-
import { adjustProductsToSize as
|
|
34
|
-
import { useDebounceFn as
|
|
29
|
+
import { SHUFFLE_CONTROL_ID as ke } from "./shuffle.js";
|
|
30
|
+
import { StrategyControl as E } from "./strategy.js";
|
|
31
|
+
import { STRATEGY_CONTROL_ID as Oe } from "./strategy.js";
|
|
32
|
+
import { setCurrencyAttributes as w, getBlockElement as V, isPartnerManagedBlock as U, updateProductContentInPlace as v, regenerateProductRowsWithStyles as A } from "./utils.js";
|
|
33
|
+
import { adjustProductsToSize as Fe, formatProductPrice as Le, getCardComposition as De, getCurrentLayout as Ee, getMainContainerTbody as we, regenerateMobileProductRows as Ve, updatePricesInPlace as Ue, updateSingleProductContent as ve } from "./utils.js";
|
|
34
|
+
import { useDebounceFn as g } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
35
35
|
const W = "ui-elements-recommendation-block";
|
|
36
|
-
class
|
|
36
|
+
class ae extends y {
|
|
37
37
|
constructor() {
|
|
38
38
|
super(...arguments);
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
s(this, "store", R());
|
|
40
|
+
s(this, "storeUnsubscription", () => {
|
|
41
41
|
});
|
|
42
42
|
// A config change waiting to reach the node config. Deferred so it can ride the
|
|
43
43
|
// re-render's single apply() — one user action must cost one undo press.
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
s(this, "pendingNodeConfigWrite", null);
|
|
45
|
+
s(this, "pendingConfigFlushTimer", null);
|
|
46
|
+
// The block the subscription watches, and its own configVersion whose products were
|
|
47
|
+
// fetched / reached the canvas — read on teardown and block switch to finish its refresh.
|
|
48
|
+
s(this, "trackedBlockId", null);
|
|
49
|
+
s(this, "fetchedConfigVersion", 0);
|
|
50
|
+
s(this, "renderedConfigVersion", 0);
|
|
51
|
+
s(this, "isDestroyed", !1);
|
|
46
52
|
// Sub-control instances for lifecycle management
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
s(this, "algorithmControl", null);
|
|
54
|
+
s(this, "localeControl", null);
|
|
55
|
+
s(this, "currencyControl", null);
|
|
56
|
+
s(this, "productCountControl", null);
|
|
57
|
+
s(this, "productLayoutControl", null);
|
|
58
|
+
s(this, "filtersControl", null);
|
|
59
|
+
s(this, "shuffleControl", null);
|
|
60
|
+
s(this, "pricePlacementControl", null);
|
|
61
|
+
s(this, "layoutOrientationControl", null);
|
|
62
|
+
s(this, "strategyControl", null);
|
|
63
|
+
s(this, "rrsEnabled", !1);
|
|
58
64
|
/**
|
|
59
65
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
60
66
|
*/
|
|
61
|
-
|
|
67
|
+
s(this, "_debouncedFetchProducts", g(async (e) => {
|
|
68
|
+
if (this.isDestroyed || e !== this.store.currentRecommendationId)
|
|
69
|
+
return;
|
|
70
|
+
const t = this._getBlockConfigVersion(e);
|
|
62
71
|
try {
|
|
63
|
-
await this.store.fetchRecommendationProducts();
|
|
72
|
+
await this.store.fetchRecommendationProducts(), e === this.store.currentRecommendationId && (this.fetchedConfigVersion = Math.max(this.fetchedConfigVersion, t));
|
|
64
73
|
} finally {
|
|
65
|
-
this._scheduleConfigFlush();
|
|
74
|
+
!this.isDestroyed && e === this.store.currentRecommendationId && this._scheduleConfigFlush();
|
|
66
75
|
}
|
|
67
76
|
}, 500));
|
|
68
77
|
/**
|
|
@@ -76,23 +85,24 @@ class at extends N {
|
|
|
76
85
|
* count. The store pads products to the configured size, so in-place only
|
|
77
86
|
* fails when the size actually changed.
|
|
78
87
|
*/
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
if (!this.currentNode || !this.api)
|
|
88
|
+
s(this, "_debouncedRegenerateWithProducts", g(() => {
|
|
89
|
+
const e = this.store.recommendationProducts;
|
|
90
|
+
if (this.isDestroyed || !this.currentNode || !this.api)
|
|
82
91
|
return;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
this.renderedConfigVersion = this.fetchedConfigVersion;
|
|
93
|
+
const t = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(t);
|
|
94
|
+
if (U(this.currentNode)) {
|
|
95
|
+
o && (t.apply(new p("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
|
|
86
96
|
return;
|
|
87
97
|
}
|
|
88
|
-
|
|
98
|
+
v({
|
|
89
99
|
currentNode: this.currentNode,
|
|
90
|
-
documentModifier:
|
|
91
|
-
products:
|
|
92
|
-
}) ||
|
|
100
|
+
documentModifier: t,
|
|
101
|
+
products: e
|
|
102
|
+
}) || A({
|
|
93
103
|
currentNode: this.currentNode,
|
|
94
|
-
documentModifier:
|
|
95
|
-
products:
|
|
104
|
+
documentModifier: t,
|
|
105
|
+
products: e
|
|
96
106
|
});
|
|
97
107
|
}, 100));
|
|
98
108
|
}
|
|
@@ -114,15 +124,15 @@ class at extends N {
|
|
|
114
124
|
];
|
|
115
125
|
}
|
|
116
126
|
getTemplate() {
|
|
117
|
-
var
|
|
118
|
-
return this.rrsEnabled =
|
|
127
|
+
var e;
|
|
128
|
+
return this.rrsEnabled = f().isFeatureEnabled("reusableRecommendationStrategy"), this._subControls.forEach((t) => {
|
|
119
129
|
var o;
|
|
120
|
-
return (o =
|
|
121
|
-
}), this.algorithmControl = new
|
|
122
|
-
|
|
130
|
+
return (o = t == null ? void 0 : t.onDestroy) == null ? void 0 : o.call(t);
|
|
131
|
+
}), this.algorithmControl = new S(), this.localeControl = new O(), this.currencyControl = new b(), this.productCountControl = new F(), this.productLayoutControl = new L(), this.filtersControl = new k(), this.shuffleControl = new D(), this.pricePlacementControl = new B(), this.layoutOrientationControl = new T(), this.strategyControl = this.rrsEnabled ? new E() : null, this._subControls.forEach((t) => {
|
|
132
|
+
t && (t.api = this.api);
|
|
123
133
|
}), `
|
|
124
134
|
<div class="recommendation-controls-container">
|
|
125
|
-
${((
|
|
135
|
+
${((e = this.strategyControl) == null ? void 0 : e.getTemplate()) ?? ""}
|
|
126
136
|
${this.layoutOrientationControl.getTemplate()}
|
|
127
137
|
${this.productCountControl.getTemplate()}
|
|
128
138
|
${this.productLayoutControl.getTemplate()}
|
|
@@ -135,39 +145,39 @@ class at extends N {
|
|
|
135
145
|
</div>
|
|
136
146
|
`;
|
|
137
147
|
}
|
|
138
|
-
_showControlsForBlock(
|
|
148
|
+
_showControlsForBlock(e) {
|
|
139
149
|
var r;
|
|
140
|
-
const
|
|
141
|
-
if (!
|
|
150
|
+
const t = (r = this.getContainer()) == null ? void 0 : r.querySelector(".recommendation-controls-container");
|
|
151
|
+
if (!t)
|
|
142
152
|
return;
|
|
143
|
-
const o = this._getRecommendationIdFromNode(
|
|
144
|
-
|
|
153
|
+
const o = this._getRecommendationIdFromNode(e) === null ? null : l.getConfig(e), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _), i = this.rrsEnabled && !!o && !n;
|
|
154
|
+
t.classList.toggle("strategy-block", n), t.classList.toggle("legacy-strategy-block", i);
|
|
145
155
|
}
|
|
146
156
|
async onRender() {
|
|
147
157
|
var o;
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
158
|
+
I(this.api);
|
|
159
|
+
const e = this._getRecommendationIdFromNode(this.currentNode), t = e ?? this.store.currentRecommendationId;
|
|
160
|
+
if (t !== null && this.store.setCurrentBlock(t), e !== null && this._syncNodeConfigIfChanged(e), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && this.strategyControl && (this.strategyControl.api = this.api, this.strategyControl.currentNode = this.currentNode, this.strategyControl.onRender()), t !== null && ((o = this.store.blockStates[t]) != null && o.isInitialized)) {
|
|
151
161
|
this._initializeSubControls();
|
|
152
162
|
return;
|
|
153
163
|
}
|
|
154
|
-
await this._fetchBlockData(
|
|
164
|
+
await this._fetchBlockData(t), this._initializeSubControls();
|
|
155
165
|
}
|
|
156
|
-
onTemplateNodeUpdated(
|
|
166
|
+
onTemplateNodeUpdated(e) {
|
|
157
167
|
var o;
|
|
158
|
-
super.onTemplateNodeUpdated(
|
|
159
|
-
const
|
|
160
|
-
|
|
168
|
+
super.onTemplateNodeUpdated(e);
|
|
169
|
+
const t = this._getRecommendationIdFromNode(e);
|
|
170
|
+
t !== null && t !== this.store.currentRecommendationId && this.store.setCurrentBlock(t), t !== null && this._syncNodeConfigIfChanged(t, { keepRefreshedWrite: !0 }), this._showControlsForBlock(e), t !== null && !((o = this.store.blockStates[t]) != null && o.isInitialized) && this._fetchBlockData(t).then(() => {
|
|
161
171
|
this._initializeSubControls();
|
|
162
172
|
}), this._subControls.forEach((n) => {
|
|
163
|
-
var
|
|
164
|
-
n != null && n.api && (n.currentNode =
|
|
173
|
+
var i;
|
|
174
|
+
n != null && n.api && (n.currentNode = e, (i = n.onTemplateNodeUpdated) == null || i.call(n, e));
|
|
165
175
|
});
|
|
166
176
|
}
|
|
167
177
|
onDestroy() {
|
|
168
|
-
this.storeUnsubscription(), this._flushPendingNodeConfig(), this._subControls.forEach((
|
|
169
|
-
var
|
|
170
|
-
return (
|
|
178
|
+
this.isDestroyed = !0, this.storeUnsubscription(), this._finishUnrenderedChange() || this._flushPendingNodeConfig(), this._subControls.forEach((e) => {
|
|
179
|
+
var t;
|
|
180
|
+
return (t = e == null ? void 0 : e.onDestroy) == null ? void 0 : t.call(e);
|
|
171
181
|
});
|
|
172
182
|
}
|
|
173
183
|
/**
|
|
@@ -175,9 +185,9 @@ class at extends N {
|
|
|
175
185
|
* Each sub-control manages its own form values and event listeners
|
|
176
186
|
*/
|
|
177
187
|
_initializeSubControls() {
|
|
178
|
-
this._subControls.forEach((
|
|
179
|
-
var
|
|
180
|
-
|
|
188
|
+
this._subControls.forEach((e) => {
|
|
189
|
+
var t;
|
|
190
|
+
e && (e.api = this.api, e.currentNode = this.currentNode, (t = e.onRender) == null || t.call(e));
|
|
181
191
|
});
|
|
182
192
|
}
|
|
183
193
|
/**
|
|
@@ -204,35 +214,38 @@ class at extends N {
|
|
|
204
214
|
* that state and made a re-dropped saved module keep the defaults its wiped
|
|
205
215
|
* state was rebuilt with (SD-150347).
|
|
206
216
|
*/
|
|
207
|
-
_syncNodeConfigIfChanged(t) {
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
217
|
+
_syncNodeConfigIfChanged(e, { keepRefreshedWrite: t = !1 } = {}) {
|
|
218
|
+
var a;
|
|
219
|
+
const o = this.pendingNodeConfigWrite, n = t && o !== null && this._hasUnrenderedChange(o.blockId);
|
|
220
|
+
o && o.blockId !== e && !n && this._flushPendingNodeConfig();
|
|
221
|
+
const i = this.store.blockStates[e];
|
|
222
|
+
if (!i)
|
|
211
223
|
return;
|
|
212
|
-
const
|
|
213
|
-
|
|
224
|
+
const r = JSON.stringify(l.getConfig(this.currentNode)), c = i.syncedConfigFingerprint;
|
|
225
|
+
i.syncedConfigFingerprint = r, c !== r && ((a = this.pendingNodeConfigWrite) == null ? void 0 : a.blockId) !== e && this._syncNodeConfigToStore();
|
|
214
226
|
}
|
|
215
227
|
/** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
|
|
216
228
|
_isPendingStrategyIdChange() {
|
|
217
|
-
const
|
|
218
|
-
return
|
|
229
|
+
const e = this.pendingNodeConfigWrite;
|
|
230
|
+
return e ? l.getConfig(this.currentNode).strategyId !== e.updates.strategyId : !1;
|
|
219
231
|
}
|
|
220
|
-
_capturePendingNodeConfigWrite() {
|
|
221
|
-
const t = this.store.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const { filters: e, strategy: o, strategyId: n, size: s, nodeConfigVersion: r } = this.store.recommendationConfigs, { partnerName: l } = h();
|
|
225
|
-
this.pendingNodeConfigWrite = {
|
|
226
|
-
blockId: t,
|
|
232
|
+
_capturePendingNodeConfigWrite(e = this.store.currentRecommendationId) {
|
|
233
|
+
const t = e === null ? void 0 : this.store.blockStates[e];
|
|
234
|
+
!this.currentNode || !this.api || e === null || !t || (this.pendingNodeConfigWrite = {
|
|
235
|
+
blockId: e,
|
|
227
236
|
node: this.currentNode,
|
|
228
|
-
updates:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
updates: this._getNodeConfigUpdates(t.recommendationConfigs)
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
_getNodeConfigUpdates(e) {
|
|
241
|
+
const { filters: t, strategy: o, strategyId: n, size: i, nodeConfigVersion: r } = e, { partnerName: c } = f();
|
|
242
|
+
return {
|
|
243
|
+
filters: t,
|
|
244
|
+
strategy: o,
|
|
245
|
+
strategyId: n,
|
|
246
|
+
size: i,
|
|
247
|
+
configVersion: r,
|
|
248
|
+
...c.value ? { partnerName: c.value } : {}
|
|
236
249
|
};
|
|
237
250
|
}
|
|
238
251
|
/**
|
|
@@ -245,9 +258,9 @@ class at extends N {
|
|
|
245
258
|
* @param documentModifier - The batch to accumulate into
|
|
246
259
|
* @returns Whether anything was staged
|
|
247
260
|
*/
|
|
248
|
-
_stagePendingNodeConfig(
|
|
249
|
-
const
|
|
250
|
-
return !
|
|
261
|
+
_stagePendingNodeConfig(e) {
|
|
262
|
+
const t = this.pendingNodeConfigWrite;
|
|
263
|
+
return !t || !this.currentNode ? !1 : (l.stageConfig(e, this.currentNode, t.updates), !0);
|
|
251
264
|
}
|
|
252
265
|
/**
|
|
253
266
|
* Arms the guaranteed fallback write, once the product fetch has settled. The
|
|
@@ -268,41 +281,44 @@ class at extends N {
|
|
|
268
281
|
* snapshot the intervening re-render staled, and saveConfig swallows that failure.
|
|
269
282
|
*/
|
|
270
283
|
_flushPendingNodeConfig() {
|
|
271
|
-
const
|
|
272
|
-
|
|
284
|
+
const e = this.pendingNodeConfigWrite;
|
|
285
|
+
this.pendingNodeConfigWrite = null, this._clearConfigFlush(), this._writeNodeConfig(e);
|
|
286
|
+
}
|
|
287
|
+
_writeNodeConfig(e) {
|
|
288
|
+
if (!e || !this.api)
|
|
273
289
|
return;
|
|
274
|
-
const
|
|
275
|
-
JSON.stringify(o.filters) === JSON.stringify(
|
|
290
|
+
const t = e.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : e.node, o = l.getConfig(t);
|
|
291
|
+
JSON.stringify(o.filters) === JSON.stringify(e.updates.filters) && o.strategy === e.updates.strategy && o.strategyId === e.updates.strategyId && o.size === e.updates.size || l.updateConfig(this.api, t, e.updates, "Update recommendation filters");
|
|
276
292
|
}
|
|
277
293
|
_syncNodeConfigToStore() {
|
|
278
294
|
var n;
|
|
279
|
-
const
|
|
295
|
+
const e = l.getConfig(this.currentNode), t = this.store.currentRecommendationId, o = t !== null && ((n = this.store.blockStates[t]) == null ? void 0 : n.isInitialized);
|
|
280
296
|
this.store.patchCurrentBlockConfig({
|
|
281
|
-
strategy:
|
|
282
|
-
strategyId:
|
|
283
|
-
nodeConfigVersion:
|
|
284
|
-
language:
|
|
285
|
-
size:
|
|
286
|
-
productIds:
|
|
287
|
-
cardsInRow:
|
|
288
|
-
mobileCardsInRow:
|
|
289
|
-
mobileLayoutEnabled:
|
|
290
|
-
orientation:
|
|
297
|
+
strategy: e.strategy,
|
|
298
|
+
strategyId: e.strategyId,
|
|
299
|
+
nodeConfigVersion: e.configVersion,
|
|
300
|
+
language: e.language,
|
|
301
|
+
size: e.size,
|
|
302
|
+
productIds: e.productIds,
|
|
303
|
+
cardsInRow: e.cardsInRow,
|
|
304
|
+
mobileCardsInRow: e.mobileCardsInRow,
|
|
305
|
+
mobileLayoutEnabled: e.mobileLayoutEnabled,
|
|
306
|
+
orientation: e.layout,
|
|
291
307
|
// Only sync filters from node config during initial load.
|
|
292
308
|
// After initialization, the Pinia store is the source of truth
|
|
293
309
|
// for filters (edited via the filter drawer).
|
|
294
|
-
...o ? {} : { filters:
|
|
295
|
-
shuffleProducts:
|
|
296
|
-
priceMovedToNextLine:
|
|
297
|
-
priceHideIfSameAsDiscounted:
|
|
310
|
+
...o ? {} : { filters: e.filters },
|
|
311
|
+
shuffleProducts: e.shuffleProducts,
|
|
312
|
+
priceMovedToNextLine: e.priceMovedToNextLine,
|
|
313
|
+
priceHideIfSameAsDiscounted: e.priceHideIfSameAsDiscounted,
|
|
298
314
|
currencySettings: {
|
|
299
|
-
name:
|
|
300
|
-
value:
|
|
301
|
-
symbol:
|
|
302
|
-
alignment:
|
|
303
|
-
decimalCount:
|
|
304
|
-
decimalSeparator:
|
|
305
|
-
thousandSeparator:
|
|
315
|
+
name: e.currency.code,
|
|
316
|
+
value: e.currency.code,
|
|
317
|
+
symbol: e.currency.symbol,
|
|
318
|
+
alignment: e.currency.alignment === "before" ? "0" : "1",
|
|
319
|
+
decimalCount: e.currency.decimalCount.toString(),
|
|
320
|
+
decimalSeparator: e.currency.decimalSeparator,
|
|
321
|
+
thousandSeparator: e.currency.thousandSeparator
|
|
306
322
|
}
|
|
307
323
|
}, { triggerRefetch: !1 });
|
|
308
324
|
}
|
|
@@ -315,8 +331,8 @@ class at extends N {
|
|
|
315
331
|
* Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
|
|
316
332
|
* Marks the block as initialized to prevent redundant fetches on re-selection.
|
|
317
333
|
*/
|
|
318
|
-
async _fetchBlockData(
|
|
319
|
-
|
|
334
|
+
async _fetchBlockData(e) {
|
|
335
|
+
e !== null && this.store.markBlockInitialized(e), (await Promise.allSettled([
|
|
320
336
|
this.store.fetchRecommendationCreateData(),
|
|
321
337
|
this.store.fetchRecommendationFilters()
|
|
322
338
|
])).forEach((o, n) => {
|
|
@@ -341,72 +357,140 @@ class at extends N {
|
|
|
341
357
|
_applySmartDefaults() {
|
|
342
358
|
if (!this.currentNode || !this.api)
|
|
343
359
|
return;
|
|
344
|
-
const
|
|
345
|
-
let o = null, n = null,
|
|
346
|
-
if (
|
|
360
|
+
const e = l.getConfig(this.currentNode), t = {};
|
|
361
|
+
let o = null, n = null, i = null;
|
|
362
|
+
if (e.currency.code === d.currency.code) {
|
|
347
363
|
const { currencyList: r } = this.store;
|
|
348
364
|
r.length > 0 && (r.some(
|
|
349
|
-
(
|
|
350
|
-
) || (o = r[0].value.replace("price.", ""),
|
|
351
|
-
...
|
|
365
|
+
(a) => a.value === `price.${d.currency.code}`
|
|
366
|
+
) || (o = r[0].value.replace("price.", ""), t.currency = {
|
|
367
|
+
...d.currency,
|
|
352
368
|
code: o,
|
|
353
369
|
symbol: o
|
|
354
370
|
}));
|
|
355
371
|
}
|
|
356
|
-
if (
|
|
372
|
+
if (e.strategy === d.strategy) {
|
|
357
373
|
const r = this.store.getActivePredictiveAlgorithms;
|
|
358
374
|
r.length > 0 && (r.some(
|
|
359
|
-
(
|
|
360
|
-
) || (n = r[0].value,
|
|
375
|
+
(a) => a.value === d.strategy
|
|
376
|
+
) || (n = r[0].value, t.strategy = n));
|
|
361
377
|
}
|
|
362
|
-
if (
|
|
378
|
+
if (e.language === d.language) {
|
|
363
379
|
const r = this.store.getLanguages;
|
|
364
380
|
r.length > 0 && (r.some(
|
|
365
|
-
(
|
|
366
|
-
) || (
|
|
381
|
+
(a) => a.value === d.language
|
|
382
|
+
) || (i = r[0].value, t.language = i));
|
|
367
383
|
}
|
|
368
|
-
!o && !n && !
|
|
384
|
+
!o && !n && !i || (l.updateConfig(
|
|
369
385
|
this.api,
|
|
370
386
|
this.currentNode,
|
|
371
|
-
|
|
387
|
+
t,
|
|
372
388
|
"Applied smart defaults"
|
|
373
|
-
), o &&
|
|
389
|
+
), o && t.currency && w({
|
|
374
390
|
currentNode: this.currentNode,
|
|
375
391
|
documentModifier: this.api.getDocumentModifier(),
|
|
376
|
-
currency:
|
|
392
|
+
currency: t.currency
|
|
377
393
|
}), this.store.patchCurrentBlockConfig({
|
|
378
394
|
...o ? {
|
|
379
395
|
currencySettings: {
|
|
380
396
|
name: o,
|
|
381
397
|
value: o,
|
|
382
398
|
symbol: o,
|
|
383
|
-
alignment:
|
|
384
|
-
decimalCount:
|
|
385
|
-
decimalSeparator:
|
|
386
|
-
thousandSeparator:
|
|
399
|
+
alignment: d.currency.alignment === "before" ? "0" : "1",
|
|
400
|
+
decimalCount: d.currency.decimalCount.toString(),
|
|
401
|
+
decimalSeparator: d.currency.decimalSeparator,
|
|
402
|
+
thousandSeparator: d.currency.thousandSeparator
|
|
387
403
|
}
|
|
388
404
|
} : {},
|
|
389
405
|
...n ? { strategy: n } : {},
|
|
390
|
-
...
|
|
406
|
+
...i ? { language: i } : {}
|
|
391
407
|
}, { triggerRefetch: !1 }));
|
|
392
408
|
}
|
|
393
409
|
/**
|
|
394
410
|
* Reads the recommendation-id attribute from the block element within the node
|
|
395
411
|
*/
|
|
396
|
-
_getRecommendationIdFromNode(
|
|
397
|
-
const
|
|
398
|
-
if (!
|
|
412
|
+
_getRecommendationIdFromNode(e) {
|
|
413
|
+
const t = V(e);
|
|
414
|
+
if (!t || !("getAttribute" in t))
|
|
399
415
|
return null;
|
|
400
|
-
const o =
|
|
416
|
+
const o = t.getAttribute(N);
|
|
401
417
|
if (!o)
|
|
402
418
|
return null;
|
|
403
419
|
const n = parseInt(o);
|
|
404
420
|
return Number.isNaN(n) ? null : n;
|
|
405
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Hands a config change whose products never reached the canvas to a block-scoped
|
|
424
|
+
* refresh, so it survives the panel closing or moving to another block.
|
|
425
|
+
* @returns whether a refresh was started
|
|
426
|
+
*/
|
|
427
|
+
_finishUnrenderedChange() {
|
|
428
|
+
const e = this.trackedBlockId;
|
|
429
|
+
if (e === null || !this._hasUnrenderedChange(e))
|
|
430
|
+
return !1;
|
|
431
|
+
const t = this.fetchedConfigVersion !== this._getBlockConfigVersion(e);
|
|
432
|
+
return this._refreshBlockOutsidePanel(e, t), !0;
|
|
433
|
+
}
|
|
434
|
+
/** A removed block counts as unrendered so its pending write still gets flushed. */
|
|
435
|
+
_hasUnrenderedChange(e) {
|
|
436
|
+
if (e !== this.trackedBlockId)
|
|
437
|
+
return !1;
|
|
438
|
+
const t = this.store.blockStates[e];
|
|
439
|
+
return !t || this.renderedConfigVersion !== t.configVersion;
|
|
440
|
+
}
|
|
441
|
+
_hasPendingWriteFor(e) {
|
|
442
|
+
var t;
|
|
443
|
+
return ((t = this.pendingNodeConfigWrite) == null ? void 0 : t.blockId) === e;
|
|
444
|
+
}
|
|
445
|
+
_getBlockConfigVersion(e) {
|
|
446
|
+
var t;
|
|
447
|
+
return e === null ? 0 : ((t = this.store.blockStates[e]) == null ? void 0 : t.configVersion) ?? 0;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Fetches and renders one block's products without the panel, carrying its config
|
|
451
|
+
* write so both still land as one undo entry.
|
|
452
|
+
*/
|
|
453
|
+
async _refreshBlockOutsidePanel(e, t) {
|
|
454
|
+
var c;
|
|
455
|
+
if (((c = this.pendingNodeConfigWrite) == null ? void 0 : c.blockId) !== e && this._flushPendingNodeConfig(), !this.store.blockStates[e]) {
|
|
456
|
+
this._flushPendingNodeConfig();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
!this.pendingNodeConfigWrite && this._getRecommendationIdFromNode(this.currentNode) === e && this._capturePendingNodeConfigWrite(e);
|
|
460
|
+
const o = this.pendingNodeConfigWrite;
|
|
461
|
+
this.pendingNodeConfigWrite = null, this._clearConfigFlush();
|
|
462
|
+
const n = this.store.blockStates[e].configVersion;
|
|
463
|
+
if (t)
|
|
464
|
+
try {
|
|
465
|
+
await this.store.fetchRecommendationProductsForBlock(e);
|
|
466
|
+
} catch (a) {
|
|
467
|
+
console.warn("Recommendation block: fetchRecommendationProductsForBlock failed", a);
|
|
468
|
+
}
|
|
469
|
+
const i = this.store.blockStates[e];
|
|
470
|
+
if (i && i.configVersion !== n) {
|
|
471
|
+
if (o && !this._hasPendingWriteFor(e)) {
|
|
472
|
+
const a = this._getNodeConfigUpdates(i.recommendationConfigs);
|
|
473
|
+
this._writeNodeConfig({ ...o, updates: a });
|
|
474
|
+
}
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
let r = !1;
|
|
478
|
+
try {
|
|
479
|
+
r = !!i && P(
|
|
480
|
+
e,
|
|
481
|
+
this._getNodeConfigUpdates(i.recommendationConfigs),
|
|
482
|
+
i.recommendationProducts,
|
|
483
|
+
"Update recommendation configuration"
|
|
484
|
+
);
|
|
485
|
+
} catch (a) {
|
|
486
|
+
console.error("Recommendation block: refresh outside the panel failed", a);
|
|
487
|
+
}
|
|
488
|
+
r || this._writeNodeConfig(o);
|
|
489
|
+
}
|
|
406
490
|
/**
|
|
407
491
|
* Listen to store changes that require product refresh or regeneration.
|
|
408
492
|
*
|
|
409
|
-
* Uses configVersion counter (
|
|
493
|
+
* Uses the block's configVersion counter (bumped by patchCurrentBlockConfig and legacy conversion)
|
|
410
494
|
* to distinguish user-initiated config changes from internal mutations
|
|
411
495
|
* (e.g., fetchRecommendationCreateData setting preferred currency).
|
|
412
496
|
*
|
|
@@ -417,55 +501,55 @@ class at extends N {
|
|
|
417
501
|
* We skip that tick and update tracking references instead.
|
|
418
502
|
*/
|
|
419
503
|
_listenStateUpdates() {
|
|
420
|
-
const { store:
|
|
421
|
-
let
|
|
422
|
-
this.storeUnsubscription =
|
|
423
|
-
const
|
|
424
|
-
if (
|
|
425
|
-
|
|
504
|
+
const { store: e } = this;
|
|
505
|
+
let t = e.recommendationProducts, o = this._getBlockConfigVersion(e.currentRecommendationId);
|
|
506
|
+
this.isDestroyed = !1, this.trackedBlockId = e.currentRecommendationId, this.fetchedConfigVersion = o, this.renderedConfigVersion = o, this.storeUnsubscription = e.$subscribe(() => {
|
|
507
|
+
const n = e.currentRecommendationId;
|
|
508
|
+
if (n !== this.trackedBlockId) {
|
|
509
|
+
this._finishUnrenderedChange(), this.trackedBlockId = n, t = e.recommendationProducts, o = this._getBlockConfigVersion(n), this.fetchedConfigVersion = o, this.renderedConfigVersion = o;
|
|
426
510
|
return;
|
|
427
511
|
}
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
512
|
+
const i = this._getBlockConfigVersion(n);
|
|
513
|
+
i !== o && (o = i, this._capturePendingNodeConfigWrite(), this._isPendingStrategyIdChange() && this._flushPendingNodeConfig(), this._debouncedFetchProducts(n));
|
|
514
|
+
const r = e.recommendationProducts, c = r !== t, a = Array.isArray(r) && r.length > 0;
|
|
515
|
+
c && a && (t = r, this._debouncedRegenerateWithProducts());
|
|
432
516
|
});
|
|
433
517
|
}
|
|
434
518
|
}
|
|
435
519
|
export {
|
|
436
|
-
|
|
437
|
-
|
|
520
|
+
le as ALGORITHM_CONTROL_ID,
|
|
521
|
+
S as AlgorithmControl,
|
|
438
522
|
W as CONTROL_BLOCK_ID,
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
523
|
+
he as CURRENCY_CONTROL_ID,
|
|
524
|
+
b as CurrencyControl,
|
|
525
|
+
ge as FILTERS_CONTROL_ID,
|
|
526
|
+
k as FiltersControl,
|
|
527
|
+
Ce as LAYOUT_ORIENTATION_CONTROL_ID,
|
|
528
|
+
ye as LOCALE_CONTROL_ID,
|
|
529
|
+
T as LayoutOrientationControl,
|
|
530
|
+
O as LocaleControl,
|
|
531
|
+
Ne as PRICE_PLACEMENT_CONTROL_ID,
|
|
532
|
+
Ie as PRODUCT_COUNT_CONTROL_ID,
|
|
533
|
+
Se as PRODUCT_LAYOUT_CONTROL_ID,
|
|
534
|
+
B as PricePlacementControl,
|
|
535
|
+
F as ProductCountControl,
|
|
536
|
+
L as ProductLayoutControl,
|
|
537
|
+
ae as RecommendationBlockControl,
|
|
538
|
+
ke as SHUFFLE_CONTROL_ID,
|
|
539
|
+
Oe as STRATEGY_CONTROL_ID,
|
|
456
540
|
D as ShuffleControl,
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
541
|
+
E as StrategyControl,
|
|
542
|
+
Fe as adjustProductsToSize,
|
|
543
|
+
Le as formatProductPrice,
|
|
544
|
+
V as getBlockElement,
|
|
545
|
+
De as getCardComposition,
|
|
546
|
+
Ee as getCurrentLayout,
|
|
547
|
+
we as getMainContainerTbody,
|
|
548
|
+
U as isPartnerManagedBlock,
|
|
549
|
+
Ve as regenerateMobileProductRows,
|
|
550
|
+
A as regenerateProductRowsWithStyles,
|
|
551
|
+
w as setCurrencyAttributes,
|
|
552
|
+
Ue as updatePricesInPlace,
|
|
553
|
+
v as updateProductContentInPlace,
|
|
554
|
+
ve as updateSingleProductContent
|
|
471
555
|
};
|