@useinsider/guido 3.17.0-beta.3ff6ea0 → 3.17.0-beta.6255bfc
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 +12 -6
- package/dist/components/Guido.vue.js +2 -2
- package/dist/components/Guido.vue2.js +31 -30
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +18 -0
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +66 -0
- package/dist/composables/useCustomInterfaceAppearance.js +52 -38
- package/dist/composables/useRecommendation.js +52 -44
- package/dist/composables/useStripo.js +14 -14
- package/dist/config/migrator/index.js +8 -9
- package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
- package/dist/config/migrator/recommendation/extractors.js +24 -29
- package/dist/config/migrator/recommendation/htmlBuilder.js +130 -116
- package/dist/config/migrator/recommendation/settingsMapper.js +19 -17
- package/dist/config/migrator/recommendationMigrator.js +15 -16
- package/dist/enums/academy.js +2 -1
- package/dist/enums/date.js +4 -3
- package/dist/enums/extensions/recommendationBlock.js +4 -1
- package/dist/extensions/Blocks/Recommendation/block.js +26 -21
- 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 +26 -25
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +28 -34
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +256 -323
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +178 -165
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +142 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +0 -1
- package/dist/extensions/Blocks/Recommendation/extension.js +29 -31
- package/dist/extensions/Blocks/Recommendation/services/configService.js +35 -35
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +4 -23
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +251 -110
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +107 -85
- package/dist/extensions/Blocks/common-control.js +22 -19
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +75 -30
- package/dist/src/@types/config/schemas.d.ts +12 -0
- package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useRecommendation.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +0 -8
- package/dist/src/enums/academy.d.ts +1 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +1 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +0 -7
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +7 -7
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +0 -10
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +0 -10
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +15 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +30 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +206 -10
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
- package/dist/src/mock/api/recommendation-strategies.d.ts +63 -0
- package/dist/src/services/recommendationApi.d.ts +4 -1
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/utils/strategyInfoBox.d.ts +22 -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 +188 -0
- package/dist/static/styles/customEditorStyle.css.js +1 -3
- package/dist/utils/dateUtil.js +29 -10
- package/dist/utils/strategyInfoBox.js +37 -0
- package/dist/utils/templatePreparation.js +37 -34
- package/package.json +2 -1
- package/dist/config/migrator/recommendationTitleMigrator.js +0 -119
- package/dist/extensions/Blocks/Recommendation/controls/title/index.js +0 -44
- package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +0 -33
- package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +0 -5
- package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +0 -86
- package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +0 -13
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
var C = Object.defineProperty;
|
|
2
|
+
var g = (d, c, t) => c in d ? C(d, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[c] = t;
|
|
3
|
+
var n = (d, c, t) => g(d, typeof c != "symbol" ? c + "" : c, t);
|
|
4
|
+
import { useConfig as p } from "../../../../../composables/useConfig.js";
|
|
5
|
+
import { CommonControl as y } from "../../../common-control.js";
|
|
6
|
+
import { CURRENT_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
|
|
7
|
+
import { RecommendationConfigService as m } from "../../services/configService.js";
|
|
8
|
+
import { useRecommendationExtensionStore as N } from "../../store/recommendation.js";
|
|
9
|
+
import { AlgorithmControl as I } from "./algorithm.js";
|
|
10
|
+
import { ALGORITHM_CONTROL_ID as it } from "./algorithm.js";
|
|
10
11
|
import { CurrencyControl as R } from "./currency.js";
|
|
11
|
-
import { CURRENCY_CONTROL_ID as
|
|
12
|
-
import { FiltersControl as
|
|
13
|
-
import { FILTERS_CONTROL_ID as
|
|
12
|
+
import { CURRENCY_CONTROL_ID as at } from "./currency.js";
|
|
13
|
+
import { FiltersControl as T } from "./filters.js";
|
|
14
|
+
import { FILTERS_CONTROL_ID as lt } from "./filters.js";
|
|
14
15
|
import { LayoutOrientationControl as b } from "./layoutOrientation.js";
|
|
15
|
-
import { LAYOUT_ORIENTATION_CONTROL_ID as
|
|
16
|
-
import { LocaleControl as
|
|
17
|
-
import { LOCALE_CONTROL_ID as
|
|
18
|
-
import { PricePlacementControl as
|
|
19
|
-
import { PRICE_PLACEMENT_CONTROL_ID as
|
|
20
|
-
import { ProductCountControl as
|
|
21
|
-
import { PRODUCT_COUNT_CONTROL_ID as
|
|
22
|
-
import { ProductLayoutControl as
|
|
23
|
-
import { PRODUCT_LAYOUT_CONTROL_ID as
|
|
24
|
-
import { ShuffleControl as
|
|
25
|
-
import { SHUFFLE_CONTROL_ID as
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
import { LAYOUT_ORIENTATION_CONTROL_ID as dt } from "./layoutOrientation.js";
|
|
17
|
+
import { LocaleControl as S } from "./locale.js";
|
|
18
|
+
import { LOCALE_CONTROL_ID as ht } from "./locale.js";
|
|
19
|
+
import { PricePlacementControl as O } from "./pricePlacement.js";
|
|
20
|
+
import { PRICE_PLACEMENT_CONTROL_ID as Ct } from "./pricePlacement.js";
|
|
21
|
+
import { ProductCountControl as P } from "./productCount.js";
|
|
22
|
+
import { PRODUCT_COUNT_CONTROL_ID as pt } from "./productCount.js";
|
|
23
|
+
import { ProductLayoutControl as L } from "./productLayout.js";
|
|
24
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as _t } from "./productLayout.js";
|
|
25
|
+
import { ShuffleControl as k } from "./shuffle.js";
|
|
26
|
+
import { SHUFFLE_CONTROL_ID as It } from "./shuffle.js";
|
|
27
|
+
import { StrategyControl as E } from "./strategy.js";
|
|
28
|
+
import { STRATEGY_CONTROL_ID as Tt } from "./strategy.js";
|
|
29
|
+
import { setCurrencyAttributes as D, getBlockElement as w, isPartnerManagedBlock as B, updateProductContentInPlace as v, regenerateProductRowsWithStyles as $ } from "./utils.js";
|
|
30
|
+
import { adjustProductsToSize as St, formatProductPrice as Ot, getCardComposition as Pt, getCurrentLayout as Lt, regenerateMobileProductRows as kt, updatePricesInPlace as Et, updateSingleProductContent as Dt } from "./utils.js";
|
|
31
|
+
import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
32
|
+
const A = "recommendation-id", x = "ui-elements-recommendation-block";
|
|
33
|
+
class ot extends y {
|
|
31
34
|
constructor() {
|
|
32
35
|
super(...arguments);
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
n(this, "store", N());
|
|
37
|
+
n(this, "storeUnsubscription", () => {
|
|
35
38
|
});
|
|
36
|
-
|
|
39
|
+
n(this, "syncedBlockIds", /* @__PURE__ */ new Set());
|
|
37
40
|
// Sub-control instances for lifecycle management
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
n(this, "algorithmControl", null);
|
|
42
|
+
n(this, "localeControl", null);
|
|
43
|
+
n(this, "currencyControl", null);
|
|
44
|
+
n(this, "productCountControl", null);
|
|
45
|
+
n(this, "productLayoutControl", null);
|
|
46
|
+
n(this, "filtersControl", null);
|
|
47
|
+
n(this, "shuffleControl", null);
|
|
48
|
+
n(this, "pricePlacementControl", null);
|
|
49
|
+
n(this, "layoutOrientationControl", null);
|
|
50
|
+
n(this, "strategyControl", null);
|
|
47
51
|
/**
|
|
48
52
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
49
53
|
*/
|
|
50
|
-
|
|
54
|
+
n(this, "_debouncedFetchProducts", h(() => {
|
|
51
55
|
this.store.fetchRecommendationProducts();
|
|
52
56
|
}, 500));
|
|
53
57
|
/**
|
|
@@ -61,16 +65,16 @@ class Q extends g {
|
|
|
61
65
|
* count. The store pads products to the configured size, so in-place only
|
|
62
66
|
* fails when the size actually changed.
|
|
63
67
|
*/
|
|
64
|
-
|
|
68
|
+
n(this, "_debouncedRegenerateWithProducts", h(() => {
|
|
65
69
|
const t = this.store.recommendationProducts;
|
|
66
|
-
if (!this.currentNode || !this.api ||
|
|
70
|
+
if (!this.currentNode || !this.api || B(this.currentNode))
|
|
67
71
|
return;
|
|
68
72
|
const e = this.api.getDocumentModifier();
|
|
69
|
-
|
|
73
|
+
v({
|
|
70
74
|
currentNode: this.currentNode,
|
|
71
75
|
documentModifier: e,
|
|
72
76
|
products: t
|
|
73
|
-
}) ||
|
|
77
|
+
}) || $({
|
|
74
78
|
currentNode: this.currentNode,
|
|
75
79
|
documentModifier: e,
|
|
76
80
|
products: t
|
|
@@ -78,22 +82,44 @@ class Q extends g {
|
|
|
78
82
|
}, 100));
|
|
79
83
|
}
|
|
80
84
|
getId() {
|
|
81
|
-
return
|
|
85
|
+
return x;
|
|
82
86
|
}
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
/** Every sub-control the coordinator owns, in panel order. */
|
|
88
|
+
get _subControls() {
|
|
89
|
+
return [
|
|
90
|
+
this.layoutOrientationControl,
|
|
91
|
+
this.productCountControl,
|
|
85
92
|
this.algorithmControl,
|
|
86
93
|
this.localeControl,
|
|
87
94
|
this.currencyControl,
|
|
88
|
-
this.productCountControl,
|
|
89
95
|
this.productLayoutControl,
|
|
90
96
|
this.filtersControl,
|
|
91
97
|
this.shuffleControl,
|
|
92
98
|
this.pricePlacementControl,
|
|
93
|
-
this.
|
|
94
|
-
]
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
this.strategyControl
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
getTemplate() {
|
|
103
|
+
const t = p().isFeatureEnabled("reusableRecommendationStrategy");
|
|
104
|
+
return this._subControls.forEach((e) => {
|
|
105
|
+
var o;
|
|
106
|
+
return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
|
|
107
|
+
}), this.algorithmControl = new I(), this.localeControl = new S(), this.currencyControl = new R(), this.productCountControl = new P(), this.productLayoutControl = new L(), this.filtersControl = new T(), this.shuffleControl = new k(), this.pricePlacementControl = new O(), this.layoutOrientationControl = new b(), this.strategyControl = t ? new E() : null, this._subControls.forEach((e) => {
|
|
108
|
+
e && (e.api = this.api);
|
|
109
|
+
}), t ? `
|
|
110
|
+
<div class="recommendation-controls-container">
|
|
111
|
+
${this.strategyControl.getTemplate()}
|
|
112
|
+
${this.layoutOrientationControl.getTemplate()}
|
|
113
|
+
${this.productCountControl.getTemplate()}
|
|
114
|
+
${this.productLayoutControl.getTemplate()}
|
|
115
|
+
${this.algorithmControl.getTemplate()}
|
|
116
|
+
${this.localeControl.getTemplate()}
|
|
117
|
+
${this.pricePlacementControl.getTemplate()}
|
|
118
|
+
${this.currencyControl.getTemplate()}
|
|
119
|
+
${this.filtersControl.getTemplate()}
|
|
120
|
+
${this.shuffleControl.getTemplate()}
|
|
121
|
+
</div>
|
|
122
|
+
` : `
|
|
97
123
|
<div class="recommendation-controls-container">
|
|
98
124
|
${this.layoutOrientationControl.getTemplate()}
|
|
99
125
|
${this.productCountControl.getTemplate()}
|
|
@@ -107,50 +133,43 @@ class Q extends g {
|
|
|
107
133
|
</div>
|
|
108
134
|
`;
|
|
109
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Shows the selected block's own set of controls. A block is strategy-backed
|
|
138
|
+
* when a flag-on session stamped its config version, or when it already
|
|
139
|
+
* carries a strategy — an assignment must stay editable however it arrived.
|
|
140
|
+
*/
|
|
141
|
+
_showControlsForBlock(t) {
|
|
142
|
+
var i;
|
|
143
|
+
const e = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
|
|
144
|
+
if (!e || this._getRecommendationIdFromNode(t) === null)
|
|
145
|
+
return;
|
|
146
|
+
const o = m.getConfig(t), r = (o.configVersion ?? 0) >= _ || !!o.strategyId;
|
|
147
|
+
e.classList.toggle("strategy-block", r);
|
|
148
|
+
}
|
|
110
149
|
async onRender() {
|
|
111
150
|
var o;
|
|
112
151
|
const t = this._getRecommendationIdFromNode(this.currentNode), e = t ?? this.store.currentRecommendationId;
|
|
113
|
-
if (e !== null && this.store.setCurrentBlock(e), t !== null && !this.syncedBlockIds.has(t) && (this.syncedBlockIds.add(t), this._syncNodeConfigToStore()), this._listenStateUpdates(), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
|
|
152
|
+
if (e !== null && this.store.setCurrentBlock(e), t !== null && !this.syncedBlockIds.has(t) && (this.syncedBlockIds.add(t), this._syncNodeConfigToStore()), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
|
|
114
153
|
this._initializeSubControls();
|
|
115
154
|
return;
|
|
116
155
|
}
|
|
117
156
|
await this._fetchBlockData(e), this._initializeSubControls();
|
|
118
157
|
}
|
|
119
158
|
onTemplateNodeUpdated(t) {
|
|
120
|
-
var
|
|
159
|
+
var o;
|
|
121
160
|
super.onTemplateNodeUpdated(t);
|
|
122
161
|
const e = this._getRecommendationIdFromNode(t);
|
|
123
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.syncedBlockIds.has(e) && (this.syncedBlockIds.add(e), this._syncNodeConfigToStore()), e !== null && !((
|
|
162
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.syncedBlockIds.has(e) && (this.syncedBlockIds.add(e), this._syncNodeConfigToStore()), this._showControlsForBlock(t), e !== null && !((o = this.store.blockStates[e]) != null && o.isInitialized) && this._fetchBlockData(e).then(() => {
|
|
124
163
|
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) => {
|
|
164
|
+
}), this._subControls.forEach((r) => {
|
|
136
165
|
var i;
|
|
137
|
-
|
|
166
|
+
r != null && r.api && (r.currentNode = t, (i = r.onTemplateNodeUpdated) == null || i.call(r, t));
|
|
138
167
|
});
|
|
139
168
|
}
|
|
140
169
|
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);
|
|
170
|
+
this.storeUnsubscription(), this._subControls.forEach((t) => {
|
|
171
|
+
var e;
|
|
172
|
+
return (e = t == null ? void 0 : t.onDestroy) == null ? void 0 : e.call(t);
|
|
154
173
|
});
|
|
155
174
|
}
|
|
156
175
|
/**
|
|
@@ -158,19 +177,9 @@ class Q extends g {
|
|
|
158
177
|
* Each sub-control manages its own form values and event listeners
|
|
159
178
|
*/
|
|
160
179
|
_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));
|
|
180
|
+
this._subControls.forEach((t) => {
|
|
181
|
+
var e;
|
|
182
|
+
t && (t.api = this.api, t.currentNode = this.currentNode, (e = t.onRender) == null || e.call(t));
|
|
174
183
|
});
|
|
175
184
|
}
|
|
176
185
|
/**
|
|
@@ -186,9 +195,10 @@ class Q extends g {
|
|
|
186
195
|
*/
|
|
187
196
|
_syncNodeConfigToStore() {
|
|
188
197
|
var r;
|
|
189
|
-
const t =
|
|
198
|
+
const t = m.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
|
|
190
199
|
this.store.patchCurrentBlockConfig({
|
|
191
200
|
strategy: t.strategy,
|
|
201
|
+
strategyId: t.strategyId,
|
|
192
202
|
language: t.language,
|
|
193
203
|
size: t.size,
|
|
194
204
|
productIds: t.productIds,
|
|
@@ -249,36 +259,36 @@ class Q extends g {
|
|
|
249
259
|
_applySmartDefaults() {
|
|
250
260
|
if (!this.currentNode || !this.api)
|
|
251
261
|
return;
|
|
252
|
-
const t =
|
|
253
|
-
let o = null, r = null,
|
|
254
|
-
if (t.currency.code ===
|
|
255
|
-
const { currencyList:
|
|
256
|
-
|
|
257
|
-
(u) => u.value === `price.${
|
|
258
|
-
) || (o =
|
|
259
|
-
...
|
|
262
|
+
const t = m.getConfig(this.currentNode), e = {};
|
|
263
|
+
let o = null, r = null, i = null;
|
|
264
|
+
if (t.currency.code === a.currency.code) {
|
|
265
|
+
const { currencyList: s } = this.store;
|
|
266
|
+
s.length > 0 && (s.some(
|
|
267
|
+
(u) => u.value === `price.${a.currency.code}`
|
|
268
|
+
) || (o = s[0].value.replace("price.", ""), e.currency = {
|
|
269
|
+
...a.currency,
|
|
260
270
|
code: o,
|
|
261
271
|
symbol: o
|
|
262
272
|
}));
|
|
263
273
|
}
|
|
264
|
-
if (t.strategy ===
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
(u) => u.value ===
|
|
268
|
-
) || (r =
|
|
274
|
+
if (t.strategy === a.strategy) {
|
|
275
|
+
const s = this.store.getActivePredictiveAlgorithms;
|
|
276
|
+
s.length > 0 && (s.some(
|
|
277
|
+
(u) => u.value === a.strategy
|
|
278
|
+
) || (r = s[0].value, e.strategy = r));
|
|
269
279
|
}
|
|
270
|
-
if (t.language ===
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
(u) => u.value ===
|
|
274
|
-
) || (
|
|
280
|
+
if (t.language === a.language) {
|
|
281
|
+
const s = this.store.getLanguages;
|
|
282
|
+
s.length > 0 && (s.some(
|
|
283
|
+
(u) => u.value === a.language
|
|
284
|
+
) || (i = s[0].value, e.language = i));
|
|
275
285
|
}
|
|
276
|
-
!o && !r && !
|
|
286
|
+
!o && !r && !i || (m.updateConfig(
|
|
277
287
|
this.api,
|
|
278
288
|
this.currentNode,
|
|
279
289
|
e,
|
|
280
290
|
"Applied smart defaults"
|
|
281
|
-
), o && e.currency &&
|
|
291
|
+
), o && e.currency && D({
|
|
282
292
|
currentNode: this.currentNode,
|
|
283
293
|
documentModifier: this.api.getDocumentModifier(),
|
|
284
294
|
currency: e.currency
|
|
@@ -288,24 +298,24 @@ class Q extends g {
|
|
|
288
298
|
name: o,
|
|
289
299
|
value: o,
|
|
290
300
|
symbol: o,
|
|
291
|
-
alignment:
|
|
292
|
-
decimalCount:
|
|
293
|
-
decimalSeparator:
|
|
294
|
-
thousandSeparator:
|
|
301
|
+
alignment: a.currency.alignment === "before" ? "0" : "1",
|
|
302
|
+
decimalCount: a.currency.decimalCount.toString(),
|
|
303
|
+
decimalSeparator: a.currency.decimalSeparator,
|
|
304
|
+
thousandSeparator: a.currency.thousandSeparator
|
|
295
305
|
}
|
|
296
306
|
} : {},
|
|
297
307
|
...r ? { strategy: r } : {},
|
|
298
|
-
...
|
|
308
|
+
...i ? { language: i } : {}
|
|
299
309
|
}, { triggerRefetch: !1 }));
|
|
300
310
|
}
|
|
301
311
|
/**
|
|
302
312
|
* Reads the recommendation-id attribute from the block element within the node
|
|
303
313
|
*/
|
|
304
314
|
_getRecommendationIdFromNode(t) {
|
|
305
|
-
const e =
|
|
315
|
+
const e = w(t);
|
|
306
316
|
if (!e || !("getAttribute" in e))
|
|
307
317
|
return null;
|
|
308
|
-
const o = e.getAttribute(
|
|
318
|
+
const o = e.getAttribute(A);
|
|
309
319
|
if (!o)
|
|
310
320
|
return null;
|
|
311
321
|
const r = parseInt(o);
|
|
@@ -328,65 +338,68 @@ class Q extends g {
|
|
|
328
338
|
const { store: t } = this;
|
|
329
339
|
let e = t.recommendationProducts, o = t.$state.configVersion, r = t.currentRecommendationId;
|
|
330
340
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
r =
|
|
341
|
+
const i = t.currentRecommendationId;
|
|
342
|
+
if (i !== r) {
|
|
343
|
+
r = i, e = t.recommendationProducts, o = t.$state.configVersion;
|
|
334
344
|
return;
|
|
335
345
|
}
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
u &&
|
|
346
|
+
const s = t.$state.configVersion;
|
|
347
|
+
s !== o && (o = s, this._persistFiltersToNodeConfig(), this._debouncedFetchProducts());
|
|
348
|
+
const l = t.recommendationProducts, u = l !== e, f = Array.isArray(l) && l.length > 0;
|
|
349
|
+
u && f && (e = l, this._debouncedRegenerateWithProducts());
|
|
340
350
|
});
|
|
341
351
|
}
|
|
342
352
|
/**
|
|
343
|
-
* Persists
|
|
344
|
-
*
|
|
353
|
+
* Persists filter + strategy state to the Stripo node config so it survives
|
|
354
|
+
* save/reload (strategyId must reach esd-ext-config before any save).
|
|
355
|
+
* `size` rides along: assigning a strategy writes it to the store only, and a
|
|
356
|
+
* stale node config would rebuild the block against the old slot count.
|
|
345
357
|
*/
|
|
346
358
|
_persistFiltersToNodeConfig() {
|
|
347
359
|
if (!this.currentNode || !this.api)
|
|
348
360
|
return;
|
|
349
|
-
const { filters: t } = this.store.recommendationConfigs,
|
|
350
|
-
JSON.stringify(
|
|
361
|
+
const { filters: t, strategyId: e, size: o } = this.store.recommendationConfigs, r = m.getConfig(this.currentNode);
|
|
362
|
+
JSON.stringify(r.filters) === JSON.stringify(t) && r.strategyId === e && r.size === o || m.updateConfig(
|
|
351
363
|
this.api,
|
|
352
364
|
this.currentNode,
|
|
353
|
-
{ filters: t },
|
|
365
|
+
{ filters: t, strategyId: e, size: o },
|
|
354
366
|
"Update recommendation filters"
|
|
355
367
|
);
|
|
356
368
|
}
|
|
357
369
|
}
|
|
358
370
|
export {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
371
|
+
it as ALGORITHM_CONTROL_ID,
|
|
372
|
+
I as AlgorithmControl,
|
|
373
|
+
x as CONTROL_BLOCK_ID,
|
|
374
|
+
at as CURRENCY_CONTROL_ID,
|
|
363
375
|
R as CurrencyControl,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
376
|
+
lt as FILTERS_CONTROL_ID,
|
|
377
|
+
T as FiltersControl,
|
|
378
|
+
dt as LAYOUT_ORIENTATION_CONTROL_ID,
|
|
379
|
+
ht as LOCALE_CONTROL_ID,
|
|
368
380
|
b as LayoutOrientationControl,
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
381
|
+
S as LocaleControl,
|
|
382
|
+
Ct as PRICE_PLACEMENT_CONTROL_ID,
|
|
383
|
+
pt as PRODUCT_COUNT_CONTROL_ID,
|
|
384
|
+
_t as PRODUCT_LAYOUT_CONTROL_ID,
|
|
385
|
+
O as PricePlacementControl,
|
|
386
|
+
P as ProductCountControl,
|
|
387
|
+
L as ProductLayoutControl,
|
|
388
|
+
ot as RecommendationBlockControl,
|
|
389
|
+
It as SHUFFLE_CONTROL_ID,
|
|
390
|
+
Tt as STRATEGY_CONTROL_ID,
|
|
391
|
+
k as ShuffleControl,
|
|
392
|
+
E as StrategyControl,
|
|
393
|
+
St as adjustProductsToSize,
|
|
394
|
+
Ot as formatProductPrice,
|
|
395
|
+
w as getBlockElement,
|
|
396
|
+
Pt as getCardComposition,
|
|
397
|
+
Lt as getCurrentLayout,
|
|
398
|
+
B as isPartnerManagedBlock,
|
|
399
|
+
kt as regenerateMobileProductRows,
|
|
400
|
+
$ as regenerateProductRowsWithStyles,
|
|
401
|
+
D as setCurrencyAttributes,
|
|
402
|
+
Et as updatePricesInPlace,
|
|
403
|
+
v as updateProductContentInPlace,
|
|
404
|
+
Dt as updateSingleProductContent
|
|
392
405
|
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var y = (r, s, t) => s in r ? d(r, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[s] = t;
|
|
3
|
+
var o = (r, s, t) => y(r, typeof s != "symbol" ? s + "" : s, t);
|
|
4
|
+
import { ACADEMY_LINKS as m } from "../../../../../enums/academy.js";
|
|
5
|
+
import { CommonControl as h } from "../../../common-control.js";
|
|
6
|
+
import { useRecommendationExtensionStore as u } from "../../store/recommendation.js";
|
|
7
|
+
const p = "recommendation-strategy-control";
|
|
8
|
+
class f extends h {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
o(this, "store", u());
|
|
12
|
+
o(this, "storeUnsubscription", () => {
|
|
13
|
+
});
|
|
14
|
+
o(this, "listeners", []);
|
|
15
|
+
// The store subscription fires on EVERY mutation of a store six controls
|
|
16
|
+
// share, so the last painted state is kept to skip the DOM work.
|
|
17
|
+
o(this, "lastPaintedState", null);
|
|
18
|
+
}
|
|
19
|
+
getId() {
|
|
20
|
+
return p;
|
|
21
|
+
}
|
|
22
|
+
getTemplate() {
|
|
23
|
+
const t = this.api.translate(
|
|
24
|
+
"You can assign a recommendation strategy by selecting an existing one or creating a new one to show specific content."
|
|
25
|
+
), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
|
|
26
|
+
return `
|
|
27
|
+
<div class="strategy-control-container">
|
|
28
|
+
<div class="strategy-control-header">
|
|
29
|
+
<h3 class="strategy-control-title">${this.api.translate("Recommendation Strategy")}</h3>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="strategy-control-description-row">
|
|
32
|
+
<p class="strategy-control-description">
|
|
33
|
+
${t}
|
|
34
|
+
${e}
|
|
35
|
+
<a
|
|
36
|
+
href="${m.EMAIL_RECOMMENDATION_BLOCK}"
|
|
37
|
+
target="_blank"
|
|
38
|
+
rel="noopener noreferrer">${a}</a>.
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
<div data-strategy-empty-state>
|
|
42
|
+
${this._GuTwoColumns([
|
|
43
|
+
this._GuButton({
|
|
44
|
+
name: "assignStrategy",
|
|
45
|
+
label: this.api.translate("Assign Strategy"),
|
|
46
|
+
id: "guido__btn-assign-strategy",
|
|
47
|
+
className: "strategy-control-cta on"
|
|
48
|
+
}),
|
|
49
|
+
// Create round-trip ships with SD-149916; until then the CTA
|
|
50
|
+
// stays inert at full contrast, as the design draws it.
|
|
51
|
+
this._GuButton({
|
|
52
|
+
name: "createStrategy",
|
|
53
|
+
label: this.api.translate("Create New Strategy"),
|
|
54
|
+
id: "guido__btn-create-strategy",
|
|
55
|
+
className: "strategy-control-cta primary",
|
|
56
|
+
disabled: !0
|
|
57
|
+
})
|
|
58
|
+
], "strategy-control-cta-row")}
|
|
59
|
+
</div>
|
|
60
|
+
<div data-strategy-assigned-state style="display: none;">
|
|
61
|
+
<div class="strategy-control-name-band">
|
|
62
|
+
<span class="strategy-control-name" data-strategy-name></span>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="strategy-control-actions">
|
|
65
|
+
${this._strategyAction({
|
|
66
|
+
id: "guido__btn-change-strategy",
|
|
67
|
+
label: this.api.translate("Change"),
|
|
68
|
+
modifier: "change"
|
|
69
|
+
})}
|
|
70
|
+
${this._strategyAction({
|
|
71
|
+
id: "guido__btn-remove-strategy",
|
|
72
|
+
label: this.api.translate("Remove"),
|
|
73
|
+
modifier: "remove"
|
|
74
|
+
})}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Change / Remove are icon+text actions in the design, not buttons — and
|
|
82
|
+
* `ue-button` cannot pair a caption with an arbitrary icon, so these are
|
|
83
|
+
* plain elements. Click wiring is by id, which works on any element.
|
|
84
|
+
*
|
|
85
|
+
* The icon is a CSS mask, not inline SVG: Stripo re-creates the control's
|
|
86
|
+
* markup through Angular, which rebuilds `<svg>` outside the SVG namespace
|
|
87
|
+
* (the view-box attribute comes back lowercased) and it never paints.
|
|
88
|
+
*/
|
|
89
|
+
_strategyAction({ id: t, label: e, modifier: a }) {
|
|
90
|
+
return `
|
|
91
|
+
<button
|
|
92
|
+
id="${t}"
|
|
93
|
+
type="button"
|
|
94
|
+
class="strategy-control-action strategy-control-action--${a}">
|
|
95
|
+
<span>${e}</span>
|
|
96
|
+
</button>
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
onRender() {
|
|
100
|
+
this._teardown(), this._setupButtonListeners(), this._renderState(), this.storeUnsubscription = this.store.$subscribe(() => {
|
|
101
|
+
this._renderState();
|
|
102
|
+
}), this.store.recommendationConfigs.strategyId && !this.store.strategies.length && this.store.fetchStrategies().catch(() => {
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
onDestroy() {
|
|
106
|
+
this._teardown();
|
|
107
|
+
}
|
|
108
|
+
_teardown() {
|
|
109
|
+
this.storeUnsubscription(), this.storeUnsubscription = () => {
|
|
110
|
+
}, this.lastPaintedState = null, this.listeners.forEach(({ element: t, handler: e }) => t.removeEventListener("click", e)), this.listeners = [];
|
|
111
|
+
}
|
|
112
|
+
_setupButtonListeners() {
|
|
113
|
+
const t = this.getContainer();
|
|
114
|
+
if (!t)
|
|
115
|
+
return;
|
|
116
|
+
const e = (a, n) => {
|
|
117
|
+
const i = t.querySelector(a);
|
|
118
|
+
i && (i.addEventListener("click", n), this.listeners.push({ element: i, handler: n }));
|
|
119
|
+
};
|
|
120
|
+
e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.removeStrategy());
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Toggles empty vs assigned state from the store's current block config.
|
|
124
|
+
* Display name comes from the listing; falls back to the raw id while the
|
|
125
|
+
* listing loads (or when the strategy is no longer listed).
|
|
126
|
+
*/
|
|
127
|
+
_renderState() {
|
|
128
|
+
var l;
|
|
129
|
+
const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((l = this.store.assignedStrategy) == null ? void 0 : l.name) ?? "" : "", a = `${t}\0${e}`;
|
|
130
|
+
if (a === this.lastPaintedState)
|
|
131
|
+
return;
|
|
132
|
+
const n = this.getContainer();
|
|
133
|
+
if (!n)
|
|
134
|
+
return;
|
|
135
|
+
const i = n.querySelector("[data-strategy-empty-state]"), c = n.querySelector("[data-strategy-assigned-state]"), g = n.querySelector("[data-strategy-name]");
|
|
136
|
+
!i || !c || (i.style.display = t ? "none" : "", c.style.display = t ? "" : "none", g && t && (g.textContent = e || `#${t}`), this.lastPaintedState = a);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
p as STRATEGY_CONTROL_ID,
|
|
141
|
+
f as StrategyControl
|
|
142
|
+
};
|