@useinsider/guido 2.1.0-beta.f869a80 → 2.1.0-beta.f9ab899
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/@types/config/schemas.js +1 -1
- package/dist/components/organisms/base/Toaster.vue.js +4 -4
- package/dist/components/organisms/base/Toaster.vue2.js +12 -9
- package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +5 -5
- package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +2 -2
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +13 -11
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +23 -54
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +5 -7
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +21 -34
- package/dist/components/organisms/extensions/recommendation/Filters.vue.js +11 -11
- package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +36 -48
- package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +9 -11
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
- package/dist/composables/useRecommendation.js +9 -9
- package/dist/composables/useStripo.js +25 -23
- package/dist/composables/useVersionHistoryApi.js +1 -1
- package/dist/config/i18n/en/index.js +11 -0
- package/dist/config/i18n/en/labels.json.js +7 -0
- package/dist/config/i18n/en/toasters.json.js +56 -0
- package/dist/config/i18n/en/tooltips.json.js +82 -0
- package/dist/config/i18n/index.js +7 -0
- package/dist/config/migrator/itemsBlockMigrator.js +65 -64
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +36 -33
- package/dist/extensions/Blocks/Recommendation/constants/layout.js +16 -14
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +13 -12
- package/dist/extensions/Blocks/Recommendation/controls/button/index.js +9 -9
- package/dist/extensions/Blocks/Recommendation/controls/image/index.js +1 -1
- package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +37 -27
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +16 -16
- package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +30 -32
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +177 -125
- package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +9 -9
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +46 -38
- package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +16 -16
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +269 -215
- package/dist/extensions/Blocks/Recommendation/controls/name/index.js +10 -10
- package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +5 -5
- package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +14 -14
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +9 -9
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +3 -3
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +1 -1
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +9 -9
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +3 -3
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +3 -3
- package/dist/extensions/Blocks/Recommendation/controls/price/index.js +3 -3
- package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +225 -102
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +123 -128
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
- package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
- package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
- package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
- package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
- package/dist/guido.css +1 -1
- package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +0 -1
- package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +1 -17
- package/dist/src/config/i18n/en/index.d.ts +1 -0
- package/dist/src/config/i18n/index.d.ts +16 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +3 -3
- package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +6 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +33 -15
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +24 -14
- package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +49 -17
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +3 -18
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +8 -0
- package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
- package/dist/static/styles/components/notification.css.js +18 -0
- package/dist/static/styles/components/tools.css.js +6 -2
- package/dist/static/styles/variables.css.js +2 -0
- package/dist/stores/unsubscribe.js +37 -34
- package/package.json +1 -1
- package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +0 -29
- package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +0 -15
|
@@ -1,65 +1,77 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { CommonControl as
|
|
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
|
-
|
|
23
|
-
|
|
1
|
+
var g = Object.defineProperty;
|
|
2
|
+
var C = (d, c, t) => c in d ? g(d, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[c] = t;
|
|
3
|
+
var i = (d, c, t) => C(d, typeof c != "symbol" ? c + "" : c, t);
|
|
4
|
+
import { CommonControl as p } from "../../../common-control.js";
|
|
5
|
+
import { DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
|
|
6
|
+
import { RecommendationConfigService as m } from "../../services/configService.js";
|
|
7
|
+
import { useRecommendationExtensionStore as y } from "../../store/recommendation.js";
|
|
8
|
+
import { AlgorithmControl as R } from "./algorithm.js";
|
|
9
|
+
import { ALGORITHM_CONTROL_ID as H } from "./algorithm.js";
|
|
10
|
+
import { CurrencyControl as b } from "./currency.js";
|
|
11
|
+
import { CURRENCY_CONTROL_ID as K } from "./currency.js";
|
|
12
|
+
import { FiltersControl as N } from "./filters.js";
|
|
13
|
+
import { FILTERS_CONTROL_ID as J } from "./filters.js";
|
|
14
|
+
import { LocaleControl as _ } from "./locale.js";
|
|
15
|
+
import { LOCALE_CONTROL_ID as X } from "./locale.js";
|
|
16
|
+
import { ProductLayoutControl as S } from "./productLayout.js";
|
|
17
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as tt } from "./productLayout.js";
|
|
18
|
+
import { ShuffleControl as I } from "./shuffle.js";
|
|
19
|
+
import { SHUFFLE_CONTROL_ID as ot } from "./shuffle.js";
|
|
20
|
+
import { getBlockElement as P, updateProductContentInPlace as L, regenerateProductRowsWithStyles as T } from "./utils.js";
|
|
21
|
+
import { adjustProductsToSize as nt, formatProductPrice as st, getCardComposition as it, getCurrentLayout as at, reapplySpacing as ct, regenerateMobileProductRows as lt, regenerateProductRows as ut, setCurrencyAttributes as dt, updatePricesInPlace as mt, updateSingleProductContent as ht } from "./utils.js";
|
|
22
|
+
import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
23
|
+
const k = "recommendation-id", D = "ui-elements-recommendation-block";
|
|
24
|
+
class W extends p {
|
|
24
25
|
constructor() {
|
|
25
26
|
super(...arguments);
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
i(this, "store", y());
|
|
28
|
+
i(this, "storeUnsubscription", () => {
|
|
28
29
|
});
|
|
29
30
|
// Sub-control instances for lifecycle management
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
i(this, "algorithmControl", null);
|
|
32
|
+
i(this, "localeControl", null);
|
|
33
|
+
i(this, "currencyControl", null);
|
|
34
|
+
i(this, "productLayoutControl", null);
|
|
35
|
+
i(this, "filtersControl", null);
|
|
36
|
+
i(this, "shuffleControl", null);
|
|
36
37
|
/**
|
|
37
38
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
38
39
|
*/
|
|
39
|
-
|
|
40
|
+
i(this, "_debouncedFetchProducts", h(() => {
|
|
40
41
|
this.store.fetchRecommendationProducts();
|
|
41
42
|
}, 500));
|
|
42
43
|
/**
|
|
43
|
-
* Debounced
|
|
44
|
-
*
|
|
44
|
+
* Debounced content update when products arrive from API.
|
|
45
|
+
*
|
|
46
|
+
* Tries in-place update first (preserves user-applied styles) — this succeeds
|
|
47
|
+
* when the product count matches the DOM (algorithm/locale/currency changes).
|
|
48
|
+
*
|
|
49
|
+
* Falls back to full regeneration when product count differs from DOM — this
|
|
50
|
+
* happens after "Number of Products" changes where the DOM still has the old
|
|
51
|
+
* count. The store pads products to the configured size, so in-place only
|
|
52
|
+
* fails when the size actually changed.
|
|
45
53
|
*/
|
|
46
|
-
|
|
54
|
+
i(this, "_debouncedRegenerateWithProducts", h(() => {
|
|
47
55
|
const t = this.store.recommendationProducts;
|
|
48
56
|
if (!this.currentNode || !this.api)
|
|
49
57
|
return;
|
|
50
58
|
const e = this.api.getDocumentModifier();
|
|
51
|
-
|
|
59
|
+
L({
|
|
52
60
|
currentNode: this.currentNode,
|
|
53
61
|
documentModifier: e,
|
|
54
62
|
products: t
|
|
55
|
-
}) ||
|
|
63
|
+
}) || T({
|
|
64
|
+
currentNode: this.currentNode,
|
|
65
|
+
documentModifier: e,
|
|
66
|
+
products: t
|
|
67
|
+
});
|
|
56
68
|
}, 100));
|
|
57
69
|
}
|
|
58
70
|
getId() {
|
|
59
|
-
return
|
|
71
|
+
return D;
|
|
60
72
|
}
|
|
61
73
|
getTemplate() {
|
|
62
|
-
return this.algorithmControl = new
|
|
74
|
+
return this.algorithmControl = new R(), this.localeControl = new _(), this.currencyControl = new b(), this.productLayoutControl = new S(), this.filtersControl = new N(), this.shuffleControl = new I(), `
|
|
63
75
|
<div class="recommendation-controls-container">
|
|
64
76
|
${this.algorithmControl.getTemplate()}
|
|
65
77
|
${this.localeControl.getTemplate()}
|
|
@@ -79,35 +91,20 @@ class z extends f {
|
|
|
79
91
|
}
|
|
80
92
|
await this._fetchBlockData(t), this._initializeSubControls();
|
|
81
93
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Immediately regenerate products with styles (no debounce)
|
|
84
|
-
* Used for initial load after fetch completes
|
|
85
|
-
*/
|
|
86
|
-
_regenerateWithProducts(t) {
|
|
87
|
-
if (!this.currentNode || !this.api) {
|
|
88
|
-
console.warn("[Recommendation] Cannot regenerate - missing currentNode or api");
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
b({
|
|
92
|
-
currentNode: this.currentNode,
|
|
93
|
-
documentModifier: this.api.getDocumentModifier(),
|
|
94
|
-
products: t
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
94
|
onTemplateNodeUpdated(t) {
|
|
98
|
-
var
|
|
95
|
+
var s;
|
|
99
96
|
super.onTemplateNodeUpdated(t);
|
|
100
97
|
const e = this._getRecommendationIdFromNode(t);
|
|
101
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((
|
|
98
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((s = this.store.blockStates[e]) != null && s.isInitialized) && this._fetchBlockData(e), [
|
|
102
99
|
this.algorithmControl,
|
|
103
100
|
this.localeControl,
|
|
104
101
|
this.currencyControl,
|
|
105
102
|
this.productLayoutControl,
|
|
106
103
|
this.filtersControl,
|
|
107
104
|
this.shuffleControl
|
|
108
|
-
].forEach((
|
|
109
|
-
var
|
|
110
|
-
|
|
105
|
+
].forEach((r) => {
|
|
106
|
+
var n;
|
|
107
|
+
r != null && r.api && (r.currentNode = t, (n = r.onTemplateNodeUpdated) == null || n.call(r, t));
|
|
111
108
|
});
|
|
112
109
|
}
|
|
113
110
|
onDestroy() {
|
|
@@ -152,17 +149,13 @@ class z extends f {
|
|
|
152
149
|
* values are being prepared for the upcoming initial fetch.
|
|
153
150
|
*/
|
|
154
151
|
_syncNodeConfigToStore() {
|
|
155
|
-
|
|
156
|
-
const t = l.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
|
|
152
|
+
const t = m.getConfig(this.currentNode);
|
|
157
153
|
this.store.patchCurrentBlockConfig({
|
|
158
154
|
strategy: t.strategy,
|
|
159
155
|
language: t.language,
|
|
160
156
|
size: t.size,
|
|
161
157
|
productIds: t.productIds,
|
|
162
|
-
|
|
163
|
-
// After initialization, the Pinia store is the source of truth
|
|
164
|
-
// for filters (edited via the filter drawer).
|
|
165
|
-
...o ? {} : { filters: t.filters },
|
|
158
|
+
filters: t.filters,
|
|
166
159
|
shuffleProducts: t.shuffleProducts,
|
|
167
160
|
currencySettings: {
|
|
168
161
|
name: t.currency.code,
|
|
@@ -176,35 +169,97 @@ class z extends f {
|
|
|
176
169
|
}, { triggerRefetch: !1 });
|
|
177
170
|
}
|
|
178
171
|
/**
|
|
179
|
-
* Fetches initial data for a block
|
|
172
|
+
* Fetches initial data for a block in three phases:
|
|
173
|
+
* 1. Shared reference data (algorithms, currencies, filters) — parallel
|
|
174
|
+
* 2. Smart defaults for new blocks (currency, algorithm) — sequential
|
|
175
|
+
* 3. Product data with correct defaults — sequential
|
|
176
|
+
*
|
|
180
177
|
* Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
|
|
181
178
|
* Marks the block as initialized to prevent redundant fetches on re-selection.
|
|
182
179
|
*/
|
|
183
180
|
async _fetchBlockData(t) {
|
|
184
181
|
t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
|
|
185
|
-
this.store.fetchRecommendationFilters(),
|
|
186
182
|
this.store.fetchRecommendationCreateData(),
|
|
187
|
-
this.store.
|
|
188
|
-
])).forEach((o,
|
|
189
|
-
o.status === "rejected" && console.warn(`Recommendation block: ${[
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
183
|
+
this.store.fetchRecommendationFilters()
|
|
184
|
+
])).forEach((o, s) => {
|
|
185
|
+
o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][s]} failed`, o.reason);
|
|
186
|
+
}), this._applySmartDefaults();
|
|
187
|
+
try {
|
|
188
|
+
await this.store.fetchRecommendationProducts();
|
|
189
|
+
} catch (o) {
|
|
190
|
+
console.warn("Recommendation block: fetchRecommendationProducts failed", o);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Applies smart defaults for newly dropped blocks.
|
|
195
|
+
*
|
|
196
|
+
* For new blocks (config still matches hardcoded defaults), validates that
|
|
197
|
+
* the default currency and algorithm are available from the API response.
|
|
198
|
+
* If not, falls back to the first available option.
|
|
199
|
+
*
|
|
200
|
+
* Saved templates with user-customized config are left unchanged because
|
|
201
|
+
* their values won't match the hardcoded defaults.
|
|
202
|
+
*/
|
|
203
|
+
_applySmartDefaults() {
|
|
204
|
+
if (!this.currentNode || !this.api)
|
|
205
|
+
return;
|
|
206
|
+
const t = m.getConfig(this.currentNode), e = {};
|
|
207
|
+
let o = null, s = null, r = null;
|
|
208
|
+
if (t.currency.code === a.currency.code) {
|
|
209
|
+
const { currencyList: n } = this.store;
|
|
210
|
+
n.length > 0 && (n.some(
|
|
211
|
+
(u) => u.value === `price.${a.currency.code}`
|
|
212
|
+
) || (o = n[0].value.replace("price.", ""), e.currency = {
|
|
213
|
+
...a.currency,
|
|
214
|
+
code: o,
|
|
215
|
+
symbol: o
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
if (t.strategy === a.strategy) {
|
|
219
|
+
const n = this.store.getActivePredictiveAlgorithms;
|
|
220
|
+
n.length > 0 && (n.some(
|
|
221
|
+
(u) => u.value === a.strategy
|
|
222
|
+
) || (s = n[0].value, e.strategy = s));
|
|
223
|
+
}
|
|
224
|
+
if (t.language === a.language) {
|
|
225
|
+
const n = this.store.getLanguages;
|
|
226
|
+
n.length > 0 && (n.some(
|
|
227
|
+
(u) => u.value === a.language
|
|
228
|
+
) || (r = n[0].value, e.language = r));
|
|
229
|
+
}
|
|
230
|
+
!o && !s && !r || (m.updateConfig(
|
|
231
|
+
this.api,
|
|
232
|
+
this.currentNode,
|
|
233
|
+
e,
|
|
234
|
+
"Applied smart defaults"
|
|
235
|
+
), this.store.patchCurrentBlockConfig({
|
|
236
|
+
...o ? {
|
|
237
|
+
currencySettings: {
|
|
238
|
+
name: o,
|
|
239
|
+
value: o,
|
|
240
|
+
symbol: o,
|
|
241
|
+
alignment: a.currency.alignment === "before" ? "0" : "1",
|
|
242
|
+
decimalCount: a.currency.decimalCount.toString(),
|
|
243
|
+
decimalSeparator: a.currency.decimalSeparator,
|
|
244
|
+
thousandSeparator: a.currency.thousandSeparator
|
|
245
|
+
}
|
|
246
|
+
} : {},
|
|
247
|
+
...s ? { strategy: s } : {},
|
|
248
|
+
...r ? { language: r } : {}
|
|
249
|
+
}, { triggerRefetch: !1 }));
|
|
195
250
|
}
|
|
196
251
|
/**
|
|
197
252
|
* Reads the recommendation-id attribute from the block element within the node
|
|
198
253
|
*/
|
|
199
254
|
_getRecommendationIdFromNode(t) {
|
|
200
|
-
const e =
|
|
255
|
+
const e = P(t);
|
|
201
256
|
if (!e || !("getAttribute" in e))
|
|
202
257
|
return null;
|
|
203
|
-
const o = e.getAttribute(
|
|
258
|
+
const o = e.getAttribute(k);
|
|
204
259
|
if (!o)
|
|
205
260
|
return null;
|
|
206
|
-
const
|
|
207
|
-
return Number.isNaN(
|
|
261
|
+
const s = parseInt(o);
|
|
262
|
+
return Number.isNaN(s) ? null : s;
|
|
208
263
|
}
|
|
209
264
|
/**
|
|
210
265
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -212,58 +267,55 @@ class z extends f {
|
|
|
212
267
|
* Uses configVersion counter (incremented only by patchCurrentBlockConfig)
|
|
213
268
|
* to distinguish user-initiated config changes from internal mutations
|
|
214
269
|
* (e.g., fetchRecommendationCreateData setting preferred currency).
|
|
270
|
+
*
|
|
271
|
+
* Tracks currentRecommendationId to detect block switches. When the user
|
|
272
|
+
* selects a different recommendation block, the proxy getters (e.g.,
|
|
273
|
+
* recommendationProducts) return the new block's data — a different array
|
|
274
|
+
* reference that would be falsely detected as "new products arrived".
|
|
275
|
+
* We skip that tick and update tracking references instead.
|
|
215
276
|
*/
|
|
216
277
|
_listenStateUpdates() {
|
|
217
278
|
const { store: t } = this;
|
|
218
|
-
let e = t.recommendationProducts, o = t.$state.configVersion;
|
|
279
|
+
let e = t.recommendationProducts, o = t.$state.configVersion, s = t.currentRecommendationId;
|
|
219
280
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
220
|
-
const r = t
|
|
221
|
-
r !==
|
|
222
|
-
|
|
223
|
-
|
|
281
|
+
const r = t.currentRecommendationId;
|
|
282
|
+
if (r !== s) {
|
|
283
|
+
s = r, e = t.recommendationProducts, o = t.$state.configVersion;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const n = t.$state.configVersion;
|
|
287
|
+
n !== o && (o = n, this._debouncedFetchProducts());
|
|
288
|
+
const l = t.recommendationProducts, u = l !== e, f = Array.isArray(l) && l.length > 0;
|
|
289
|
+
u && f && (e = l, this._debouncedRegenerateWithProducts());
|
|
224
290
|
});
|
|
225
291
|
}
|
|
226
|
-
/**
|
|
227
|
-
* Persists the current filter state from Pinia store to the Stripo node config.
|
|
228
|
-
* This ensures filters survive template save/reload cycles.
|
|
229
|
-
*/
|
|
230
|
-
_persistFiltersToNodeConfig() {
|
|
231
|
-
if (!this.currentNode || !this.api)
|
|
232
|
-
return;
|
|
233
|
-
const { filters: t } = this.store.recommendationConfigs;
|
|
234
|
-
l.updateConfig(
|
|
235
|
-
this.api,
|
|
236
|
-
this.currentNode,
|
|
237
|
-
{ filters: t },
|
|
238
|
-
"Update recommendation filters"
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
292
|
}
|
|
242
293
|
export {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
294
|
+
H as ALGORITHM_CONTROL_ID,
|
|
295
|
+
R as AlgorithmControl,
|
|
296
|
+
D as CONTROL_BLOCK_ID,
|
|
297
|
+
K as CURRENCY_CONTROL_ID,
|
|
298
|
+
b as CurrencyControl,
|
|
299
|
+
J as FILTERS_CONTROL_ID,
|
|
300
|
+
N as FiltersControl,
|
|
301
|
+
X as LOCALE_CONTROL_ID,
|
|
302
|
+
_ as LocaleControl,
|
|
303
|
+
tt as PRODUCT_LAYOUT_CONTROL_ID,
|
|
304
|
+
S as ProductLayoutControl,
|
|
305
|
+
W as RecommendationBlockControl,
|
|
306
|
+
ot as SHUFFLE_CONTROL_ID,
|
|
307
|
+
I as ShuffleControl,
|
|
308
|
+
nt as adjustProductsToSize,
|
|
309
|
+
st as formatProductPrice,
|
|
310
|
+
P as getBlockElement,
|
|
311
|
+
it as getCardComposition,
|
|
312
|
+
at as getCurrentLayout,
|
|
313
|
+
ct as reapplySpacing,
|
|
314
|
+
lt as regenerateMobileProductRows,
|
|
315
|
+
ut as regenerateProductRows,
|
|
316
|
+
T as regenerateProductRowsWithStyles,
|
|
317
|
+
dt as setCurrencyAttributes,
|
|
318
|
+
mt as updatePricesInPlace,
|
|
319
|
+
L as updateProductContentInPlace,
|
|
320
|
+
ht as updateSingleProductContent
|
|
269
321
|
};
|
|
@@ -2,20 +2,20 @@ var s = Object.defineProperty;
|
|
|
2
2
|
var r = (o, t, e) => t in o ? s(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
3
|
var a = (o, t, e) => r(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
4
|
import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
-
import { CommonControl as
|
|
5
|
+
import { CommonControl as c } from "../../../common-control.js";
|
|
6
6
|
import { RecommendationConfigService as i } from "../../services/configService.js";
|
|
7
|
-
import { useRecommendationExtensionStore as
|
|
8
|
-
const
|
|
7
|
+
import { useRecommendationExtensionStore as g } from "../../store/recommendation.js";
|
|
8
|
+
const m = "recommendation-locale-control", n = {
|
|
9
9
|
LOCALE: "language"
|
|
10
10
|
};
|
|
11
|
-
class
|
|
11
|
+
class E extends c {
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
14
|
// Store is used ONLY for API-fetched data (language options), not for config
|
|
15
|
-
a(this, "store",
|
|
15
|
+
a(this, "store", g());
|
|
16
16
|
}
|
|
17
17
|
getId() {
|
|
18
|
-
return
|
|
18
|
+
return m;
|
|
19
19
|
}
|
|
20
20
|
getTemplate() {
|
|
21
21
|
return `
|
|
@@ -51,7 +51,7 @@ class C extends m {
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
_onLocaleChange(e) {
|
|
54
|
-
this.currentNode
|
|
54
|
+
!this.currentNode || i.getConfig(this.currentNode).language === e || (i.updateConfig(
|
|
55
55
|
this.api,
|
|
56
56
|
this.currentNode,
|
|
57
57
|
{ language: e },
|
|
@@ -65,6 +65,6 @@ class C extends m {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
export {
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
m as LOCALE_CONTROL_ID,
|
|
69
|
+
E as LocaleControl
|
|
70
70
|
};
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { EditorStatePropertyType as
|
|
5
|
-
import { CommonControl as
|
|
6
|
-
import { MAX_PRODUCT_COUNT as
|
|
7
|
-
import { RecommendationConfigService as
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var _ = (n, r, t) => r in n ? u(n, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[r] = t;
|
|
3
|
+
var a = (n, r, t) => _(n, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { EditorStatePropertyType as c, PreviewDeviceMode as C } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as R } from "../../../common-control.js";
|
|
6
|
+
import { MAX_PRODUCT_COUNT as h, MAX_PRODUCTS_PER_ROW as p, MAX_MOBILE_PRODUCTS_PER_ROW as g, DEFAULT_COLUMN_SPACING as m, DEFAULT_MOBILE_COLUMN_SPACING as O } from "../../constants/layout.js";
|
|
7
|
+
import { RecommendationConfigService as i } from "../../services/configService.js";
|
|
8
8
|
import { useRecommendationExtensionStore as l } from "../../store/recommendation.js";
|
|
9
|
-
import { ensureMobileCssRulesExist as
|
|
10
|
-
import { getCurrentLayout as
|
|
11
|
-
import { useDebounceFn as
|
|
12
|
-
const
|
|
9
|
+
import { ensureMobileCssRulesExist as I } from "../mobileLayout/cssRules.js";
|
|
10
|
+
import { getCurrentLayout as N, regenerateMobileProductRows as f, adjustProductsToSize as b, regenerateProductRowsWithStyles as P } from "./utils.js";
|
|
11
|
+
import { useDebounceFn as L } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
12
|
+
const M = "recommendation-product-layout-control", e = {
|
|
13
13
|
PRODUCT_COUNT: "size",
|
|
14
14
|
PRODUCT_IN_ROW: "cardsInRow",
|
|
15
15
|
PRODUCT_IN_ROW_LABEL: "cardsInRowLabel",
|
|
16
16
|
MOBILE_CARDS_IN_ROW: "mobileCardsInRow",
|
|
17
17
|
MOBILE_CARDS_IN_ROW_LABEL: "mobileCardsInRowLabel"
|
|
18
18
|
};
|
|
19
|
-
class
|
|
19
|
+
class V extends R {
|
|
20
20
|
constructor() {
|
|
21
21
|
super(...arguments);
|
|
22
22
|
// Store is used for backward compatibility with product fetching and regeneration
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
a(this, "store", l());
|
|
24
|
+
a(this, "storeUnsubscription", () => {
|
|
25
25
|
});
|
|
26
|
-
|
|
26
|
+
a(this, "_debouncedRegenerateProductRows", L(() => {
|
|
27
27
|
this._regenerateProductRows();
|
|
28
28
|
}, 500));
|
|
29
29
|
}
|
|
30
30
|
getId() {
|
|
31
|
-
return
|
|
31
|
+
return M;
|
|
32
32
|
}
|
|
33
33
|
getTemplate() {
|
|
34
34
|
return `
|
|
35
35
|
<div class="product-layout-control-container">
|
|
36
36
|
${this._GuTwoColumns([
|
|
37
37
|
this._GuLabel({ text: "Number of Products" }),
|
|
38
|
-
this._GuCounter({ name: e.PRODUCT_COUNT, maxValue:
|
|
38
|
+
this._GuCounter({ name: e.PRODUCT_COUNT, maxValue: h }),
|
|
39
39
|
this._GuLabel({
|
|
40
40
|
text: "Products in One Row on Desktop",
|
|
41
41
|
name: e.PRODUCT_IN_ROW_LABEL
|
|
@@ -47,7 +47,7 @@ class S extends h {
|
|
|
47
47
|
}),
|
|
48
48
|
this._GuCounter({
|
|
49
49
|
name: e.MOBILE_CARDS_IN_ROW,
|
|
50
|
-
maxValue:
|
|
50
|
+
maxValue: g
|
|
51
51
|
})
|
|
52
52
|
])}
|
|
53
53
|
</div>
|
|
@@ -63,7 +63,7 @@ class S extends h {
|
|
|
63
63
|
this.storeUnsubscription();
|
|
64
64
|
}
|
|
65
65
|
_setFormValues() {
|
|
66
|
-
const t =
|
|
66
|
+
const t = i.getConfig(this.currentNode);
|
|
67
67
|
this.api.updateValues({
|
|
68
68
|
[e.PRODUCT_COUNT]: t.size,
|
|
69
69
|
[e.PRODUCT_IN_ROW]: t.cardsInRow,
|
|
@@ -75,7 +75,7 @@ class S extends h {
|
|
|
75
75
|
* using Stripo's EditorStatePropertyType API.
|
|
76
76
|
*/
|
|
77
77
|
_isMobileMode() {
|
|
78
|
-
return this.api.getEditorState()[
|
|
78
|
+
return this.api.getEditorState()[c.previewDeviceMode] === C.MOBILE;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
81
|
* Updates counter visibility based on layout orientation and editor mode.
|
|
@@ -84,8 +84,8 @@ class S extends h {
|
|
|
84
84
|
* - Grid + mobile mode: show mobile counter, hide desktop counter
|
|
85
85
|
*/
|
|
86
86
|
_updateProductsInRowVisibility() {
|
|
87
|
-
const
|
|
88
|
-
this.api.setVisibility(e.PRODUCT_IN_ROW,
|
|
87
|
+
const o = (i.getConfig(this.currentNode).layout || N(this.currentNode)) === "grid", d = this._isMobileMode();
|
|
88
|
+
this.api.setVisibility(e.PRODUCT_IN_ROW, o && !d), this.api.setVisibility(e.PRODUCT_IN_ROW_LABEL, o && !d), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW, o && d), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW_LABEL, o && d);
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* Subscribes to editor preview mode changes via Stripo API.
|
|
@@ -94,43 +94,51 @@ class S extends h {
|
|
|
94
94
|
*/
|
|
95
95
|
_subscribeToEditorModeChanges() {
|
|
96
96
|
this.api.onEditorStatePropUpdated(
|
|
97
|
-
|
|
97
|
+
c.previewDeviceMode,
|
|
98
98
|
() => {
|
|
99
99
|
this._updateProductsInRowVisibility();
|
|
100
100
|
}
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
_onProductCountChange(t) {
|
|
104
|
-
this.currentNode
|
|
104
|
+
!this.currentNode || i.getConfig(this.currentNode).size === t || (i.updateConfig(
|
|
105
105
|
this.api,
|
|
106
106
|
this.currentNode,
|
|
107
107
|
{ size: t },
|
|
108
108
|
`Changed product count to ${t}`
|
|
109
|
-
), this.store.patchCurrentBlockConfig({ size: t })
|
|
109
|
+
), this.store.patchCurrentBlockConfig({ size: t }));
|
|
110
110
|
}
|
|
111
111
|
_onProductsInRowChange(t) {
|
|
112
|
-
this.currentNode
|
|
112
|
+
if (!this.currentNode || i.getConfig(this.currentNode).cardsInRow === t)
|
|
113
|
+
return;
|
|
114
|
+
const o = t === 1 ? 0 : m;
|
|
115
|
+
i.updateConfig(
|
|
113
116
|
this.api,
|
|
114
117
|
this.currentNode,
|
|
115
|
-
{ cardsInRow: t },
|
|
118
|
+
{ cardsInRow: t, columnSpacing: o },
|
|
116
119
|
`Changed products per row to ${t}`
|
|
117
|
-
), this.store.patchCurrentBlockConfig({ cardsInRow: t }), this._debouncedRegenerateProductRows()
|
|
120
|
+
), this.store.patchCurrentBlockConfig({ cardsInRow: t }, { triggerRefetch: !1 }), this._debouncedRegenerateProductRows();
|
|
118
121
|
}
|
|
119
122
|
_onMobileCardsInRowChange(t) {
|
|
120
|
-
this.currentNode
|
|
123
|
+
if (!this.currentNode || i.getConfig(this.currentNode).mobileCardsInRow === t)
|
|
124
|
+
return;
|
|
125
|
+
const o = t === 1 ? 0 : O;
|
|
126
|
+
i.updateConfig(
|
|
121
127
|
this.api,
|
|
122
128
|
this.currentNode,
|
|
123
|
-
{ mobileCardsInRow: t },
|
|
129
|
+
{ mobileCardsInRow: t, mobileColumnSpacing: o },
|
|
124
130
|
`Changed mobile products per row to ${t}`
|
|
125
|
-
),
|
|
131
|
+
), I(this.api), f({
|
|
126
132
|
currentNode: this.currentNode,
|
|
127
133
|
documentModifier: this.api.getDocumentModifier()
|
|
128
|
-
})
|
|
134
|
+
});
|
|
129
135
|
}
|
|
130
136
|
_regenerateProductRows() {
|
|
131
|
-
b(
|
|
137
|
+
const t = i.getConfig(this.currentNode), s = parseInt(t.size) || 6, o = b(this.store.recommendationProducts, s);
|
|
138
|
+
P({
|
|
132
139
|
currentNode: this.currentNode,
|
|
133
|
-
documentModifier: this.api.getDocumentModifier()
|
|
140
|
+
documentModifier: this.api.getDocumentModifier(),
|
|
141
|
+
products: o
|
|
134
142
|
});
|
|
135
143
|
}
|
|
136
144
|
_listenToFormUpdates() {
|
|
@@ -149,12 +157,12 @@ class S extends h {
|
|
|
149
157
|
_listenStateUpdates() {
|
|
150
158
|
let t = this.store.recommendationConfigs.orientation;
|
|
151
159
|
this.storeUnsubscription = this.store.$subscribe(() => {
|
|
152
|
-
const
|
|
153
|
-
|
|
160
|
+
const s = this.store.recommendationConfigs.orientation;
|
|
161
|
+
s !== t && (t = s, this._updateProductsInRowVisibility());
|
|
154
162
|
});
|
|
155
163
|
}
|
|
156
164
|
}
|
|
157
165
|
export {
|
|
158
|
-
|
|
159
|
-
|
|
166
|
+
M as PRODUCT_LAYOUT_CONTROL_ID,
|
|
167
|
+
V as ProductLayoutControl
|
|
160
168
|
};
|