@useinsider/guido 3.17.0-beta.978ff7e → 3.17.0-beta.a0d17c2
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/README.md +1 -0
- package/dist/@types/config/schemas.js +7 -6
- package/dist/components/Guido.vue.js +10 -10
- package/dist/components/Guido.vue2.js +82 -76
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +21 -0
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +106 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
- package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
- package/dist/composables/useCustomInterfaceAppearance.js +52 -38
- package/dist/composables/useRecommendation.js +41 -34
- package/dist/config/i18n/en/labels.json.js +1 -1
- package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
- package/dist/config/migrator/recommendationMigrator.js +5 -4
- package/dist/enums/academy.js +2 -1
- package/dist/enums/date.js +5 -3
- package/dist/enums/extensions/recommendationBlock.js +3 -1
- package/dist/extensions/Blocks/Recommendation/block.js +26 -21
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +30 -30
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +60 -59
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +246 -187
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +124 -0
- package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +175 -79
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
- package/dist/extensions/Blocks/common-control.js +22 -19
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +69 -30
- package/dist/src/@types/config/schemas.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
- package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useRecommendation.d.ts +1 -0
- package/dist/src/enums/academy.d.ts +1 -0
- package/dist/src/enums/date.d.ts +1 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +2 -6
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +16 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +176 -10
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
- package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
- package/dist/src/services/recommendationApi.d.ts +4 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/stores/save-as-template.d.ts +4 -3
- package/dist/src/utils/genericUtil.d.ts +5 -0
- package/dist/static/assets/icons/line-change.svg.js +5 -0
- package/dist/static/assets/icons/line-delete.svg.js +5 -0
- package/dist/static/assets/icons/line-plus.svg.js +5 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +155 -0
- package/dist/utils/dateUtil.js +23 -10
- package/dist/utils/genericUtil.js +28 -27
- package/dist/utils/templatePreparation.js +35 -34
- package/package.json +2 -1
|
@@ -1,54 +1,70 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
1
|
+
var m = Object.defineProperty;
|
|
2
|
+
var C = (h, l, t) => l in h ? m(h, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[l] = t;
|
|
3
|
+
var r = (h, l, t) => C(h, typeof l != "symbol" ? l + "" : l, t);
|
|
4
|
+
import { useConfig as p } from "../../../../../composables/useConfig.js";
|
|
5
|
+
import { ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
6
|
+
import { CommonControl as N } from "../../../common-control.js";
|
|
7
|
+
import { CURRENT_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as c } from "../../services/configService.js";
|
|
9
|
+
import { useRecommendationExtensionStore as I } from "../../store/recommendation.js";
|
|
10
|
+
import { registerNodeConfigWriter as R } from "../../utils/nodeConfigWriter.js";
|
|
11
|
+
import { AlgorithmControl as b } from "./algorithm.js";
|
|
12
|
+
import { ALGORITHM_CONTROL_ID as ct } from "./algorithm.js";
|
|
13
|
+
import { CurrencyControl as T } from "./currency.js";
|
|
14
|
+
import { CURRENCY_CONTROL_ID as dt } from "./currency.js";
|
|
15
|
+
import { FiltersControl as P } from "./filters.js";
|
|
16
|
+
import { FILTERS_CONTROL_ID as ft } from "./filters.js";
|
|
17
|
+
import { LayoutOrientationControl as S } from "./layoutOrientation.js";
|
|
18
|
+
import { LAYOUT_ORIENTATION_CONTROL_ID as mt } from "./layoutOrientation.js";
|
|
19
|
+
import { LocaleControl as O } from "./locale.js";
|
|
20
|
+
import { LOCALE_CONTROL_ID as pt } from "./locale.js";
|
|
21
|
+
import { PricePlacementControl as L } from "./pricePlacement.js";
|
|
22
|
+
import { PRICE_PLACEMENT_CONTROL_ID as Nt } from "./pricePlacement.js";
|
|
23
|
+
import { ProductCountControl as E } from "./productCount.js";
|
|
24
|
+
import { PRODUCT_COUNT_CONTROL_ID as It } from "./productCount.js";
|
|
25
|
+
import { ProductLayoutControl as k } from "./productLayout.js";
|
|
26
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as bt } from "./productLayout.js";
|
|
27
|
+
import { ShuffleControl as D } from "./shuffle.js";
|
|
28
|
+
import { SHUFFLE_CONTROL_ID as Pt } from "./shuffle.js";
|
|
29
|
+
import { StrategyControl as F } from "./strategy.js";
|
|
30
|
+
import { STRATEGY_CONTROL_ID as Ot } from "./strategy.js";
|
|
31
|
+
import { setCurrencyAttributes as w, getBlockElement as A, isPartnerManagedBlock as v, updateProductContentInPlace as x, regenerateProductRowsWithStyles as B } from "./utils.js";
|
|
32
|
+
import { adjustProductsToSize as Et, formatProductPrice as kt, getCardComposition as Dt, getCurrentLayout as Ft, getMainContainerTbody as wt, regenerateMobileProductRows as At, updatePricesInPlace as vt, updateSingleProductContent as xt } from "./utils.js";
|
|
33
|
+
import { useDebounceFn as f } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
34
|
+
const U = "recommendation-id", $ = "ui-elements-recommendation-block";
|
|
35
|
+
class st extends N {
|
|
31
36
|
constructor() {
|
|
32
37
|
super(...arguments);
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
r(this, "store", I());
|
|
39
|
+
r(this, "storeUnsubscription", () => {
|
|
35
40
|
});
|
|
36
|
-
|
|
41
|
+
// blockId -> fingerprint of the node config as it looked at the last sync.
|
|
42
|
+
r(this, "syncedConfigs", /* @__PURE__ */ new Map());
|
|
43
|
+
// A config change waiting to reach the node config. Deferred so it can ride the
|
|
44
|
+
// re-render's single apply() — one user action must cost one undo press.
|
|
45
|
+
r(this, "pendingNodeConfigWrite", null);
|
|
46
|
+
r(this, "pendingConfigFlushTimer", null);
|
|
37
47
|
// Sub-control instances for lifecycle management
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
r(this, "algorithmControl", null);
|
|
49
|
+
r(this, "localeControl", null);
|
|
50
|
+
r(this, "currencyControl", null);
|
|
51
|
+
r(this, "productCountControl", null);
|
|
52
|
+
r(this, "productLayoutControl", null);
|
|
53
|
+
r(this, "filtersControl", null);
|
|
54
|
+
r(this, "shuffleControl", null);
|
|
55
|
+
r(this, "pricePlacementControl", null);
|
|
56
|
+
r(this, "layoutOrientationControl", null);
|
|
57
|
+
r(this, "strategyControl", null);
|
|
58
|
+
r(this, "rrsEnabled", !1);
|
|
47
59
|
/**
|
|
48
60
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
49
61
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
r(this, "_debouncedFetchProducts", f(async () => {
|
|
63
|
+
try {
|
|
64
|
+
await this.store.fetchRecommendationProducts();
|
|
65
|
+
} finally {
|
|
66
|
+
this._scheduleConfigFlush();
|
|
67
|
+
}
|
|
52
68
|
}, 500));
|
|
53
69
|
/**
|
|
54
70
|
* Debounced content update when products arrive from API.
|
|
@@ -61,16 +77,20 @@ class Q extends g {
|
|
|
61
77
|
* count. The store pads products to the configured size, so in-place only
|
|
62
78
|
* fails when the size actually changed.
|
|
63
79
|
*/
|
|
64
|
-
|
|
80
|
+
r(this, "_debouncedRegenerateWithProducts", f(() => {
|
|
65
81
|
const t = this.store.recommendationProducts;
|
|
66
|
-
if (!this.currentNode || !this.api
|
|
82
|
+
if (!this.currentNode || !this.api)
|
|
83
|
+
return;
|
|
84
|
+
const e = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(e);
|
|
85
|
+
if (v(this.currentNode)) {
|
|
86
|
+
o && (e.apply(new y("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
|
|
67
87
|
return;
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
}
|
|
89
|
+
x({
|
|
70
90
|
currentNode: this.currentNode,
|
|
71
91
|
documentModifier: e,
|
|
72
92
|
products: t
|
|
73
|
-
}) ||
|
|
93
|
+
}) || B({
|
|
74
94
|
currentNode: this.currentNode,
|
|
75
95
|
documentModifier: e,
|
|
76
96
|
products: t
|
|
@@ -78,23 +98,32 @@ class Q extends g {
|
|
|
78
98
|
}, 100));
|
|
79
99
|
}
|
|
80
100
|
getId() {
|
|
81
|
-
return
|
|
101
|
+
return $;
|
|
82
102
|
}
|
|
83
|
-
|
|
84
|
-
return
|
|
103
|
+
get _subControls() {
|
|
104
|
+
return [
|
|
105
|
+
this.layoutOrientationControl,
|
|
106
|
+
this.productCountControl,
|
|
85
107
|
this.algorithmControl,
|
|
86
108
|
this.localeControl,
|
|
87
109
|
this.currencyControl,
|
|
88
|
-
this.productCountControl,
|
|
89
110
|
this.productLayoutControl,
|
|
90
111
|
this.filtersControl,
|
|
91
112
|
this.shuffleControl,
|
|
92
113
|
this.pricePlacementControl,
|
|
93
|
-
this.
|
|
94
|
-
]
|
|
95
|
-
|
|
114
|
+
this.strategyControl
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
getTemplate() {
|
|
118
|
+
var t;
|
|
119
|
+
return this.rrsEnabled = p().isFeatureEnabled("reusableRecommendationStrategy"), this._subControls.forEach((e) => {
|
|
120
|
+
var o;
|
|
121
|
+
return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
|
|
122
|
+
}), this.algorithmControl = new b(), this.localeControl = new O(), this.currencyControl = new T(), this.productCountControl = new E(), this.productLayoutControl = new k(), this.filtersControl = new P(), this.shuffleControl = new D(), this.pricePlacementControl = new L(), this.layoutOrientationControl = new S(), this.strategyControl = this.rrsEnabled ? new F() : null, this._subControls.forEach((e) => {
|
|
123
|
+
e && (e.api = this.api);
|
|
96
124
|
}), `
|
|
97
125
|
<div class="recommendation-controls-container">
|
|
126
|
+
${((t = this.strategyControl) == null ? void 0 : t.getTemplate()) ?? ""}
|
|
98
127
|
${this.layoutOrientationControl.getTemplate()}
|
|
99
128
|
${this.productCountControl.getTemplate()}
|
|
100
129
|
${this.productLayoutControl.getTemplate()}
|
|
@@ -107,50 +136,39 @@ class Q extends g {
|
|
|
107
136
|
</div>
|
|
108
137
|
`;
|
|
109
138
|
}
|
|
139
|
+
_showControlsForBlock(t) {
|
|
140
|
+
var i;
|
|
141
|
+
const e = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
|
|
142
|
+
if (!e)
|
|
143
|
+
return;
|
|
144
|
+
const o = this._getRecommendationIdFromNode(t) === null ? null : c.getConfig(t), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _);
|
|
145
|
+
e.classList.toggle("strategy-block", n);
|
|
146
|
+
}
|
|
110
147
|
async onRender() {
|
|
111
148
|
var o;
|
|
149
|
+
R(this.api);
|
|
112
150
|
const t = this._getRecommendationIdFromNode(this.currentNode), e = t ?? this.store.currentRecommendationId;
|
|
113
|
-
if (e !== null && this.store.setCurrentBlock(e), t !== null &&
|
|
151
|
+
if (e !== null && this.store.setCurrentBlock(e), t !== null && this._syncNodeConfigIfChanged(t), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
|
|
114
152
|
this._initializeSubControls();
|
|
115
153
|
return;
|
|
116
154
|
}
|
|
117
155
|
await this._fetchBlockData(e), this._initializeSubControls();
|
|
118
156
|
}
|
|
119
157
|
onTemplateNodeUpdated(t) {
|
|
120
|
-
var
|
|
158
|
+
var o;
|
|
121
159
|
super.onTemplateNodeUpdated(t);
|
|
122
160
|
const e = this._getRecommendationIdFromNode(t);
|
|
123
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null &&
|
|
161
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigIfChanged(e), this._showControlsForBlock(t), e !== null && !((o = this.store.blockStates[e]) != null && o.isInitialized) && this._fetchBlockData(e).then(() => {
|
|
124
162
|
this._initializeSubControls();
|
|
125
|
-
}),
|
|
126
|
-
this.layoutOrientationControl,
|
|
127
|
-
this.productCountControl,
|
|
128
|
-
this.algorithmControl,
|
|
129
|
-
this.localeControl,
|
|
130
|
-
this.currencyControl,
|
|
131
|
-
this.productLayoutControl,
|
|
132
|
-
this.filtersControl,
|
|
133
|
-
this.shuffleControl,
|
|
134
|
-
this.pricePlacementControl
|
|
135
|
-
].forEach((n) => {
|
|
163
|
+
}), this._subControls.forEach((n) => {
|
|
136
164
|
var i;
|
|
137
165
|
n != null && n.api && (n.currentNode = t, (i = n.onTemplateNodeUpdated) == null || i.call(n, t));
|
|
138
166
|
});
|
|
139
167
|
}
|
|
140
168
|
onDestroy() {
|
|
141
|
-
this.storeUnsubscription(),
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.algorithmControl,
|
|
145
|
-
this.localeControl,
|
|
146
|
-
this.currencyControl,
|
|
147
|
-
this.productLayoutControl,
|
|
148
|
-
this.filtersControl,
|
|
149
|
-
this.shuffleControl,
|
|
150
|
-
this.pricePlacementControl
|
|
151
|
-
].forEach((e) => {
|
|
152
|
-
var o;
|
|
153
|
-
return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
|
|
169
|
+
this.storeUnsubscription(), this._flushPendingNodeConfig(), this._subControls.forEach((t) => {
|
|
170
|
+
var e;
|
|
171
|
+
return (e = t == null ? void 0 : t.onDestroy) == null ? void 0 : e.call(t);
|
|
154
172
|
});
|
|
155
173
|
}
|
|
156
174
|
/**
|
|
@@ -158,25 +176,14 @@ class Q extends g {
|
|
|
158
176
|
* Each sub-control manages its own form values and event listeners
|
|
159
177
|
*/
|
|
160
178
|
_initializeSubControls() {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.
|
|
164
|
-
this.algorithmControl,
|
|
165
|
-
this.localeControl,
|
|
166
|
-
this.currencyControl,
|
|
167
|
-
this.productLayoutControl,
|
|
168
|
-
this.filtersControl,
|
|
169
|
-
this.shuffleControl,
|
|
170
|
-
this.pricePlacementControl
|
|
171
|
-
].forEach((e) => {
|
|
172
|
-
var o;
|
|
173
|
-
e && (e.api = this.api, e.currentNode = this.currentNode, (o = e.onRender) == null || o.call(e));
|
|
179
|
+
this._subControls.forEach((t) => {
|
|
180
|
+
var e;
|
|
181
|
+
t && (t.api = this.api, t.currentNode = this.currentNode, (e = t.onRender) == null || e.call(t));
|
|
174
182
|
});
|
|
175
183
|
}
|
|
176
184
|
/**
|
|
177
185
|
* Syncs persisted node config into the Pinia store's block state.
|
|
178
186
|
*
|
|
179
|
-
* setCurrentBlock() creates a default entry (USD, en_US, mostPopular).
|
|
180
187
|
* For saved templates, the real config lives in the node (e.g., TRY, tr_TR).
|
|
181
188
|
* This method reads it and patches the store so fetchRecommendationProducts()
|
|
182
189
|
* uses the correct values.
|
|
@@ -184,11 +191,76 @@ class Q extends g {
|
|
|
184
191
|
* Uses triggerRefetch: false because the fetch hasn't happened yet —
|
|
185
192
|
* values are being prepared for the upcoming initial fetch.
|
|
186
193
|
*/
|
|
194
|
+
/**
|
|
195
|
+
* Re-syncs the store when the node config moved since we last read it.
|
|
196
|
+
*
|
|
197
|
+
* Undo/redo, the code editor and version-history restore rewrite the node
|
|
198
|
+
* config behind the store's back — Stripo exposes no undo signal, so a
|
|
199
|
+
* fingerprint diff on this hook is the only way to notice (SD-149105).
|
|
200
|
+
* An unchanged fingerprint means the move came from us, so runtime store
|
|
201
|
+
* edits are never clobbered (SD-141049).
|
|
202
|
+
*/
|
|
203
|
+
_syncNodeConfigIfChanged(t) {
|
|
204
|
+
this.pendingNodeConfigWrite && this.pendingNodeConfigWrite.blockId !== t && this._flushPendingNodeConfig();
|
|
205
|
+
const e = JSON.stringify(c.getConfig(this.currentNode)), o = this.syncedConfigs.get(t);
|
|
206
|
+
this.syncedConfigs.set(t, e), o !== e && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
|
|
207
|
+
}
|
|
208
|
+
_capturePendingNodeConfigWrite() {
|
|
209
|
+
const t = this.store.currentRecommendationId;
|
|
210
|
+
if (!this.currentNode || !this.api || t === null)
|
|
211
|
+
return;
|
|
212
|
+
const { filters: e, strategyId: o, size: n } = this.store.recommendationConfigs;
|
|
213
|
+
this.pendingNodeConfigWrite = {
|
|
214
|
+
blockId: t,
|
|
215
|
+
node: this.currentNode,
|
|
216
|
+
updates: { filters: e, strategyId: o, size: n }
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Accumulates the pending write into `documentModifier` without applying, so the
|
|
221
|
+
* caller's apply() commits config and re-render as ONE undo entry.
|
|
222
|
+
*
|
|
223
|
+
* Deliberately does not consume the pending record: the product helpers call
|
|
224
|
+
* apply() only when they actually changed something, so this batch may never be
|
|
225
|
+
* committed and the flush has to stay able to write it standalone.
|
|
226
|
+
* @param documentModifier - The batch to accumulate into
|
|
227
|
+
* @returns Whether anything was staged
|
|
228
|
+
*/
|
|
229
|
+
_stagePendingNodeConfig(t) {
|
|
230
|
+
const e = this.pendingNodeConfigWrite;
|
|
231
|
+
return !e || !this.currentNode ? !1 : (c.stageConfig(t, this.currentNode, e.updates), !0);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Arms the guaranteed fallback write, once the product fetch has settled. The
|
|
235
|
+
* delay only has to outlast the re-render debounce that fetch triggers — firing
|
|
236
|
+
* earlier writes the config on its own and the undo entry splits in two again.
|
|
237
|
+
*/
|
|
238
|
+
_scheduleConfigFlush() {
|
|
239
|
+
this._clearConfigFlush(), this.pendingConfigFlushTimer = setTimeout(() => {
|
|
240
|
+
this.pendingConfigFlushTimer = null, this._flushPendingNodeConfig();
|
|
241
|
+
}, 800);
|
|
242
|
+
}
|
|
243
|
+
_clearConfigFlush() {
|
|
244
|
+
this.pendingConfigFlushTimer !== null && (clearTimeout(this.pendingConfigFlushTimer), this.pendingConfigFlushTimer = null);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Writes the deferred change standalone when the batch it was staged into never
|
|
248
|
+
* committed. Always targets the LIVE node — the captured one is an immutable
|
|
249
|
+
* snapshot the intervening re-render staled, and saveConfig swallows that failure.
|
|
250
|
+
*/
|
|
251
|
+
_flushPendingNodeConfig() {
|
|
252
|
+
const t = this.pendingNodeConfigWrite;
|
|
253
|
+
if (this.pendingNodeConfigWrite = null, this._clearConfigFlush(), !t || !this.api)
|
|
254
|
+
return;
|
|
255
|
+
const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o = c.getConfig(e);
|
|
256
|
+
JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategyId === t.updates.strategyId && o.size === t.updates.size || c.updateConfig(this.api, e, t.updates, "Update recommendation filters");
|
|
257
|
+
}
|
|
187
258
|
_syncNodeConfigToStore() {
|
|
188
|
-
var
|
|
189
|
-
const t =
|
|
259
|
+
var n;
|
|
260
|
+
const t = c.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
|
|
190
261
|
this.store.patchCurrentBlockConfig({
|
|
191
262
|
strategy: t.strategy,
|
|
263
|
+
strategyId: t.strategyId,
|
|
192
264
|
language: t.language,
|
|
193
265
|
size: t.size,
|
|
194
266
|
productIds: t.productIds,
|
|
@@ -227,8 +299,8 @@ class Q extends g {
|
|
|
227
299
|
t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
|
|
228
300
|
this.store.fetchRecommendationCreateData(),
|
|
229
301
|
this.store.fetchRecommendationFilters()
|
|
230
|
-
])).forEach((o,
|
|
231
|
-
o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][
|
|
302
|
+
])).forEach((o, n) => {
|
|
303
|
+
o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][n]} failed`, o.reason);
|
|
232
304
|
}), this._applySmartDefaults();
|
|
233
305
|
try {
|
|
234
306
|
await this.store.fetchRecommendationProducts();
|
|
@@ -249,36 +321,36 @@ class Q extends g {
|
|
|
249
321
|
_applySmartDefaults() {
|
|
250
322
|
if (!this.currentNode || !this.api)
|
|
251
323
|
return;
|
|
252
|
-
const t =
|
|
253
|
-
let o = null,
|
|
254
|
-
if (t.currency.code ===
|
|
255
|
-
const { currencyList:
|
|
256
|
-
|
|
257
|
-
(
|
|
258
|
-
) || (o =
|
|
259
|
-
...
|
|
324
|
+
const t = c.getConfig(this.currentNode), e = {};
|
|
325
|
+
let o = null, n = null, i = null;
|
|
326
|
+
if (t.currency.code === a.currency.code) {
|
|
327
|
+
const { currencyList: s } = this.store;
|
|
328
|
+
s.length > 0 && (s.some(
|
|
329
|
+
(d) => d.value === `price.${a.currency.code}`
|
|
330
|
+
) || (o = s[0].value.replace("price.", ""), e.currency = {
|
|
331
|
+
...a.currency,
|
|
260
332
|
code: o,
|
|
261
333
|
symbol: o
|
|
262
334
|
}));
|
|
263
335
|
}
|
|
264
|
-
if (t.strategy ===
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
(
|
|
268
|
-
) || (
|
|
336
|
+
if (t.strategy === a.strategy) {
|
|
337
|
+
const s = this.store.getActivePredictiveAlgorithms;
|
|
338
|
+
s.length > 0 && (s.some(
|
|
339
|
+
(d) => d.value === a.strategy
|
|
340
|
+
) || (n = s[0].value, e.strategy = n));
|
|
269
341
|
}
|
|
270
|
-
if (t.language ===
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
(
|
|
274
|
-
) || (
|
|
342
|
+
if (t.language === a.language) {
|
|
343
|
+
const s = this.store.getLanguages;
|
|
344
|
+
s.length > 0 && (s.some(
|
|
345
|
+
(d) => d.value === a.language
|
|
346
|
+
) || (i = s[0].value, e.language = i));
|
|
275
347
|
}
|
|
276
|
-
!o && !
|
|
348
|
+
!o && !n && !i || (c.updateConfig(
|
|
277
349
|
this.api,
|
|
278
350
|
this.currentNode,
|
|
279
351
|
e,
|
|
280
352
|
"Applied smart defaults"
|
|
281
|
-
), o && e.currency &&
|
|
353
|
+
), o && e.currency && w({
|
|
282
354
|
currentNode: this.currentNode,
|
|
283
355
|
documentModifier: this.api.getDocumentModifier(),
|
|
284
356
|
currency: e.currency
|
|
@@ -288,28 +360,28 @@ class Q extends g {
|
|
|
288
360
|
name: o,
|
|
289
361
|
value: o,
|
|
290
362
|
symbol: o,
|
|
291
|
-
alignment:
|
|
292
|
-
decimalCount:
|
|
293
|
-
decimalSeparator:
|
|
294
|
-
thousandSeparator:
|
|
363
|
+
alignment: a.currency.alignment === "before" ? "0" : "1",
|
|
364
|
+
decimalCount: a.currency.decimalCount.toString(),
|
|
365
|
+
decimalSeparator: a.currency.decimalSeparator,
|
|
366
|
+
thousandSeparator: a.currency.thousandSeparator
|
|
295
367
|
}
|
|
296
368
|
} : {},
|
|
297
|
-
...
|
|
298
|
-
...
|
|
369
|
+
...n ? { strategy: n } : {},
|
|
370
|
+
...i ? { language: i } : {}
|
|
299
371
|
}, { triggerRefetch: !1 }));
|
|
300
372
|
}
|
|
301
373
|
/**
|
|
302
374
|
* Reads the recommendation-id attribute from the block element within the node
|
|
303
375
|
*/
|
|
304
376
|
_getRecommendationIdFromNode(t) {
|
|
305
|
-
const e =
|
|
377
|
+
const e = A(t);
|
|
306
378
|
if (!e || !("getAttribute" in e))
|
|
307
379
|
return null;
|
|
308
|
-
const o = e.getAttribute(
|
|
380
|
+
const o = e.getAttribute(U);
|
|
309
381
|
if (!o)
|
|
310
382
|
return null;
|
|
311
|
-
const
|
|
312
|
-
return Number.isNaN(
|
|
383
|
+
const n = parseInt(o);
|
|
384
|
+
return Number.isNaN(n) ? null : n;
|
|
313
385
|
}
|
|
314
386
|
/**
|
|
315
387
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -326,67 +398,54 @@ class Q extends g {
|
|
|
326
398
|
*/
|
|
327
399
|
_listenStateUpdates() {
|
|
328
400
|
const { store: t } = this;
|
|
329
|
-
let e = t.recommendationProducts, o = t.$state.configVersion,
|
|
401
|
+
let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
|
|
330
402
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
|
|
403
|
+
const i = t.currentRecommendationId;
|
|
404
|
+
if (i !== n) {
|
|
405
|
+
n = i, e = t.recommendationProducts, o = t.$state.configVersion;
|
|
334
406
|
return;
|
|
335
407
|
}
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
408
|
+
const s = t.$state.configVersion;
|
|
409
|
+
s !== o && (o = s, this._capturePendingNodeConfigWrite(), this._debouncedFetchProducts());
|
|
410
|
+
const u = t.recommendationProducts, d = u !== e, g = Array.isArray(u) && u.length > 0;
|
|
411
|
+
d && g && (e = u, this._debouncedRegenerateWithProducts());
|
|
340
412
|
});
|
|
341
413
|
}
|
|
342
|
-
/**
|
|
343
|
-
* Persists the current filter state from Pinia store to the Stripo node config.
|
|
344
|
-
* This ensures filters survive template save/reload cycles.
|
|
345
|
-
*/
|
|
346
|
-
_persistFiltersToNodeConfig() {
|
|
347
|
-
if (!this.currentNode || !this.api)
|
|
348
|
-
return;
|
|
349
|
-
const { filters: t } = this.store.recommendationConfigs, e = h.getConfig(this.currentNode).filters;
|
|
350
|
-
JSON.stringify(e) !== JSON.stringify(t) && h.updateConfig(
|
|
351
|
-
this.api,
|
|
352
|
-
this.currentNode,
|
|
353
|
-
{ filters: t },
|
|
354
|
-
"Update recommendation filters"
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
414
|
}
|
|
358
415
|
export {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
416
|
+
ct as ALGORITHM_CONTROL_ID,
|
|
417
|
+
b as AlgorithmControl,
|
|
418
|
+
$ as CONTROL_BLOCK_ID,
|
|
419
|
+
dt as CURRENCY_CONTROL_ID,
|
|
420
|
+
T as CurrencyControl,
|
|
421
|
+
ft as FILTERS_CONTROL_ID,
|
|
422
|
+
P as FiltersControl,
|
|
423
|
+
mt as LAYOUT_ORIENTATION_CONTROL_ID,
|
|
424
|
+
pt as LOCALE_CONTROL_ID,
|
|
425
|
+
S as LayoutOrientationControl,
|
|
426
|
+
O as LocaleControl,
|
|
427
|
+
Nt as PRICE_PLACEMENT_CONTROL_ID,
|
|
428
|
+
It as PRODUCT_COUNT_CONTROL_ID,
|
|
429
|
+
bt as PRODUCT_LAYOUT_CONTROL_ID,
|
|
430
|
+
L as PricePlacementControl,
|
|
431
|
+
E as ProductCountControl,
|
|
432
|
+
k as ProductLayoutControl,
|
|
433
|
+
st as RecommendationBlockControl,
|
|
434
|
+
Pt as SHUFFLE_CONTROL_ID,
|
|
435
|
+
Ot as STRATEGY_CONTROL_ID,
|
|
436
|
+
D as ShuffleControl,
|
|
437
|
+
F as StrategyControl,
|
|
438
|
+
Et as adjustProductsToSize,
|
|
439
|
+
kt as formatProductPrice,
|
|
440
|
+
A as getBlockElement,
|
|
441
|
+
Dt as getCardComposition,
|
|
442
|
+
Ft as getCurrentLayout,
|
|
443
|
+
wt as getMainContainerTbody,
|
|
444
|
+
v as isPartnerManagedBlock,
|
|
445
|
+
At as regenerateMobileProductRows,
|
|
446
|
+
B as regenerateProductRowsWithStyles,
|
|
447
|
+
w as setCurrencyAttributes,
|
|
448
|
+
vt as updatePricesInPlace,
|
|
449
|
+
x as updateProductContentInPlace,
|
|
450
|
+
xt as updateSingleProductContent
|
|
392
451
|
};
|