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