@useinsider/guido 2.1.0-beta.9ba2e9d → 2.1.0-beta.a67f307
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 +36 -0
- package/dist/@types/config/schemas.js +70 -65
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +69 -58
- package/dist/components/organisms/header/HeaderWrapper.vue.js +9 -9
- package/dist/composables/useBlocksConfig.js +26 -16
- package/dist/composables/useHtmlValidator.js +107 -119
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +70 -96
- package/dist/config/migrator/itemsBlockMigrator.js +101 -97
- package/dist/enums/defaults.js +8 -4
- package/dist/enums/extensions/recommendationBlock.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +26 -23
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +27 -26
- package/dist/extensions/Blocks/Recommendation/constants/layout.js +6 -4
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +12 -10
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +103 -70
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +87 -37
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +138 -117
- package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +21 -0
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +117 -107
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +25 -30
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +27 -30
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +20 -25
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +43 -31
- package/dist/extensions/ModulesTabIcons/extension.js +17 -0
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +257 -187
- package/dist/services/recommendationApi.js +11 -9
- package/dist/src/@types/config/schemas.d.ts +8 -0
- package/dist/src/composables/useConfig.d.ts +4 -0
- package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +1 -1
- package/dist/src/enums/defaults.d.ts +4 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
- package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +4 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +12 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +22 -4
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -2
- package/dist/src/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.d.ts +29 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +12 -3
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
- package/dist/src/extensions/ModulesTabIcons/extension.d.ts +2 -0
- package/dist/src/stores/config.d.ts +36 -0
- package/dist/static/styles/components/notification.css.js +1 -0
- package/dist/static/styles/components/version-history.css.js +10 -2
- package/dist/static/styles/components/wide-panel.css.js +18 -2
- package/dist/static/styles/customEditorStyle.css.js +10 -9
- package/package.json +2 -2
|
@@ -1,55 +1,54 @@
|
|
|
1
1
|
var d = Object.defineProperty;
|
|
2
|
-
var m = (
|
|
3
|
-
var
|
|
2
|
+
var m = (c, s, t) => s in c ? d(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
|
|
3
|
+
var n = (c, s, t) => m(c, typeof s != "symbol" ? s + "" : s, t);
|
|
4
4
|
import { CommonControl as h } from "../../../common-control.js";
|
|
5
|
+
import { RecommendationConfigService as f } from "../../services/configService.js";
|
|
5
6
|
import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
|
|
6
|
-
import { AlgorithmControl as
|
|
7
|
-
import { ALGORITHM_CONTROL_ID as
|
|
8
|
-
import { CurrencyControl as
|
|
9
|
-
import { CURRENCY_CONTROL_ID as
|
|
10
|
-
import { FiltersControl as
|
|
11
|
-
import { FILTERS_CONTROL_ID as
|
|
12
|
-
import { LocaleControl as
|
|
13
|
-
import { LOCALE_CONTROL_ID as
|
|
7
|
+
import { AlgorithmControl as p } from "./algorithm.js";
|
|
8
|
+
import { ALGORITHM_CONTROL_ID as W } from "./algorithm.js";
|
|
9
|
+
import { CurrencyControl as g } from "./currency.js";
|
|
10
|
+
import { CURRENCY_CONTROL_ID as H } from "./currency.js";
|
|
11
|
+
import { FiltersControl as R } from "./filters.js";
|
|
12
|
+
import { FILTERS_CONTROL_ID as j } from "./filters.js";
|
|
13
|
+
import { LocaleControl as y } from "./locale.js";
|
|
14
|
+
import { LOCALE_CONTROL_ID as K } from "./locale.js";
|
|
14
15
|
import { ProductLayoutControl as _ } from "./productLayout.js";
|
|
15
|
-
import { PRODUCT_LAYOUT_CONTROL_ID as
|
|
16
|
+
import { PRODUCT_LAYOUT_CONTROL_ID as J } from "./productLayout.js";
|
|
16
17
|
import { ShuffleControl as N } from "./shuffle.js";
|
|
17
|
-
import { SHUFFLE_CONTROL_ID as
|
|
18
|
-
import { regenerateProductRowsWithStyles as
|
|
19
|
-
import { formatProductPrice as
|
|
20
|
-
import { useDebounceFn as
|
|
21
|
-
const T = "recommendation-id",
|
|
22
|
-
class
|
|
18
|
+
import { SHUFFLE_CONTROL_ID as X } from "./shuffle.js";
|
|
19
|
+
import { regenerateProductRowsWithStyles as b, getBlockElement as P, updateProductContentInPlace as I } from "./utils.js";
|
|
20
|
+
import { formatProductPrice as tt, getCardComposition as et, getCurrentLayout as ot, reapplySpacing as rt, regenerateMobileProductRows as nt, regenerateProductRows as it, setCurrencyAttributes as st, updatePricesInPlace as ct, updateSingleProductContent as at } from "./utils.js";
|
|
21
|
+
import { useDebounceFn as l } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
22
|
+
const T = "recommendation-id", S = "ui-elements-recommendation-block";
|
|
23
|
+
class $ extends h {
|
|
23
24
|
constructor() {
|
|
24
25
|
super(...arguments);
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
n(this, "store", C());
|
|
27
|
+
n(this, "storeUnsubscription", () => {
|
|
27
28
|
});
|
|
28
|
-
// Track if initial data has been fetched per block ID to avoid redundant API calls
|
|
29
|
-
i(this, "initializedBlocks", /* @__PURE__ */ new Map());
|
|
30
29
|
// Sub-control instances for lifecycle management
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
n(this, "algorithmControl", null);
|
|
31
|
+
n(this, "localeControl", null);
|
|
32
|
+
n(this, "currencyControl", null);
|
|
33
|
+
n(this, "productLayoutControl", null);
|
|
34
|
+
n(this, "filtersControl", null);
|
|
35
|
+
n(this, "shuffleControl", null);
|
|
37
36
|
/**
|
|
38
37
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
39
38
|
*/
|
|
40
|
-
|
|
39
|
+
n(this, "_debouncedFetchProducts", l(() => {
|
|
41
40
|
this.store.fetchRecommendationProducts();
|
|
42
41
|
}, 500));
|
|
43
42
|
/**
|
|
44
43
|
* Debounced regeneration when products arrive from API
|
|
45
44
|
* Tries in-place update first to preserve styles, falls back to full regeneration
|
|
46
45
|
*/
|
|
47
|
-
|
|
46
|
+
n(this, "_debouncedRegenerateWithProducts", l(() => {
|
|
48
47
|
const t = this.store.recommendationProducts;
|
|
49
48
|
if (!this.currentNode || !this.api)
|
|
50
49
|
return;
|
|
51
50
|
const e = this.api.getDocumentModifier();
|
|
52
|
-
|
|
51
|
+
I({
|
|
53
52
|
currentNode: this.currentNode,
|
|
54
53
|
documentModifier: e,
|
|
55
54
|
products: t
|
|
@@ -57,10 +56,10 @@ class x extends h {
|
|
|
57
56
|
}, 100));
|
|
58
57
|
}
|
|
59
58
|
getId() {
|
|
60
|
-
return
|
|
59
|
+
return S;
|
|
61
60
|
}
|
|
62
61
|
getTemplate() {
|
|
63
|
-
return this.algorithmControl = new
|
|
62
|
+
return this.algorithmControl = new p(), this.localeControl = new y(), this.currencyControl = new g(), this.productLayoutControl = new _(), this.filtersControl = new R(), this.shuffleControl = new N(), `
|
|
64
63
|
<div class="recommendation-controls-container">
|
|
65
64
|
${this.algorithmControl.getTemplate()}
|
|
66
65
|
${this.localeControl.getTemplate()}
|
|
@@ -72,8 +71,9 @@ class x extends h {
|
|
|
72
71
|
`;
|
|
73
72
|
}
|
|
74
73
|
async onRender() {
|
|
74
|
+
var e;
|
|
75
75
|
const t = this._getRecommendationIdFromNode(this.currentNode) ?? this.store.currentRecommendationId;
|
|
76
|
-
if (t !== null && this.store.setCurrentBlock(t), this._listenStateUpdates(), t !== null && this.
|
|
76
|
+
if (t !== null && this.store.setCurrentBlock(t), this._listenStateUpdates(), t !== null && ((e = this.store.blockStates[t]) != null && e.isInitialized)) {
|
|
77
77
|
this._initializeSubControls();
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
@@ -88,16 +88,17 @@ class x extends h {
|
|
|
88
88
|
console.warn("[Recommendation] Cannot regenerate - missing currentNode or api");
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
b({
|
|
92
92
|
currentNode: this.currentNode,
|
|
93
93
|
documentModifier: this.api.getDocumentModifier(),
|
|
94
94
|
products: t
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
onTemplateNodeUpdated(t) {
|
|
98
|
+
var i;
|
|
98
99
|
super.onTemplateNodeUpdated(t);
|
|
99
100
|
const e = this._getRecommendationIdFromNode(t);
|
|
100
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.
|
|
101
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((i = this.store.blockStates[e]) != null && i.isInitialized) && this._fetchBlockData(e), [
|
|
101
102
|
this.algorithmControl,
|
|
102
103
|
this.localeControl,
|
|
103
104
|
this.currencyControl,
|
|
@@ -105,8 +106,8 @@ class x extends h {
|
|
|
105
106
|
this.filtersControl,
|
|
106
107
|
this.shuffleControl
|
|
107
108
|
].forEach((r) => {
|
|
108
|
-
var
|
|
109
|
-
r != null && r.api && (r.currentNode = t, (
|
|
109
|
+
var a;
|
|
110
|
+
r != null && r.api && (r.currentNode = t, (a = r.onTemplateNodeUpdated) == null || a.call(r, t));
|
|
110
111
|
});
|
|
111
112
|
}
|
|
112
113
|
onDestroy() {
|
|
@@ -139,36 +140,67 @@ class x extends h {
|
|
|
139
140
|
e && (e.api = this.api, e.currentNode = this.currentNode, (o = e.onRender) == null || o.call(e));
|
|
140
141
|
});
|
|
141
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Syncs persisted node config into the Pinia store's block state.
|
|
145
|
+
*
|
|
146
|
+
* setCurrentBlock() creates a default entry (USD, en_US, mostPopular).
|
|
147
|
+
* For saved templates, the real config lives in the node (e.g., TRY, tr_TR).
|
|
148
|
+
* This method reads it and patches the store so fetchRecommendationProducts()
|
|
149
|
+
* uses the correct values.
|
|
150
|
+
*
|
|
151
|
+
* Uses triggerRefetch: false because the fetch hasn't happened yet —
|
|
152
|
+
* values are being prepared for the upcoming initial fetch.
|
|
153
|
+
*/
|
|
154
|
+
_syncNodeConfigToStore() {
|
|
155
|
+
const t = f.getConfig(this.currentNode);
|
|
156
|
+
this.store.patchCurrentBlockConfig({
|
|
157
|
+
strategy: t.strategy,
|
|
158
|
+
language: t.language,
|
|
159
|
+
size: t.size,
|
|
160
|
+
productIds: t.productIds,
|
|
161
|
+
filters: t.filters,
|
|
162
|
+
shuffleProducts: t.shuffleProducts,
|
|
163
|
+
currencySettings: {
|
|
164
|
+
name: t.currency.code,
|
|
165
|
+
value: t.currency.code,
|
|
166
|
+
symbol: t.currency.symbol,
|
|
167
|
+
alignment: t.currency.alignment === "before" ? "0" : "1",
|
|
168
|
+
decimalCount: t.currency.decimalCount.toString(),
|
|
169
|
+
decimalSeparator: t.currency.decimalSeparator,
|
|
170
|
+
thousandSeparator: t.currency.thousandSeparator
|
|
171
|
+
}
|
|
172
|
+
}, { triggerRefetch: !1 });
|
|
173
|
+
}
|
|
142
174
|
/**
|
|
143
175
|
* Fetches initial data for a block (filters, algorithms, products).
|
|
144
176
|
* Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
|
|
145
177
|
* Marks the block as initialized to prevent redundant fetches on re-selection.
|
|
146
178
|
*/
|
|
147
179
|
async _fetchBlockData(t) {
|
|
148
|
-
t !== null && this.
|
|
180
|
+
t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
|
|
149
181
|
this.store.fetchRecommendationFilters(),
|
|
150
182
|
this.store.fetchRecommendationCreateData(),
|
|
151
183
|
this.store.fetchRecommendationProducts()
|
|
152
|
-
])).forEach((o,
|
|
184
|
+
])).forEach((o, i) => {
|
|
153
185
|
o.status === "rejected" && console.warn(`Recommendation block: ${[
|
|
154
186
|
"fetchRecommendationFilters",
|
|
155
187
|
"fetchRecommendationCreateData",
|
|
156
188
|
"fetchRecommendationProducts"
|
|
157
|
-
][
|
|
189
|
+
][i]} failed`, o.reason);
|
|
158
190
|
});
|
|
159
191
|
}
|
|
160
192
|
/**
|
|
161
193
|
* Reads the recommendation-id attribute from the block element within the node
|
|
162
194
|
*/
|
|
163
195
|
_getRecommendationIdFromNode(t) {
|
|
164
|
-
const e =
|
|
196
|
+
const e = P(t);
|
|
165
197
|
if (!e || !("getAttribute" in e))
|
|
166
198
|
return null;
|
|
167
199
|
const o = e.getAttribute(T);
|
|
168
200
|
if (!o)
|
|
169
201
|
return null;
|
|
170
|
-
const
|
|
171
|
-
return Number.isNaN(
|
|
202
|
+
const i = parseInt(o);
|
|
203
|
+
return Number.isNaN(i) ? null : i;
|
|
172
204
|
}
|
|
173
205
|
/**
|
|
174
206
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -181,37 +213,38 @@ class x extends h {
|
|
|
181
213
|
const { store: t } = this;
|
|
182
214
|
let e = t.recommendationProducts, o = t.$state.configVersion;
|
|
183
215
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
a && u && (e =
|
|
216
|
+
const i = t.$state.configVersion;
|
|
217
|
+
i !== o && (o = i, this._debouncedFetchProducts());
|
|
218
|
+
const r = t.recommendationProducts, a = r !== e, u = Array.isArray(r) && r.length > 0;
|
|
219
|
+
a && u && (e = r, this._debouncedRegenerateWithProducts());
|
|
188
220
|
});
|
|
189
221
|
}
|
|
190
222
|
}
|
|
191
223
|
export {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
224
|
+
W as ALGORITHM_CONTROL_ID,
|
|
225
|
+
p as AlgorithmControl,
|
|
226
|
+
S as CONTROL_BLOCK_ID,
|
|
227
|
+
H as CURRENCY_CONTROL_ID,
|
|
228
|
+
g as CurrencyControl,
|
|
229
|
+
j as FILTERS_CONTROL_ID,
|
|
230
|
+
R as FiltersControl,
|
|
231
|
+
K as LOCALE_CONTROL_ID,
|
|
232
|
+
y as LocaleControl,
|
|
233
|
+
J as PRODUCT_LAYOUT_CONTROL_ID,
|
|
202
234
|
_ as ProductLayoutControl,
|
|
203
|
-
|
|
204
|
-
|
|
235
|
+
$ as RecommendationBlockControl,
|
|
236
|
+
X as SHUFFLE_CONTROL_ID,
|
|
205
237
|
N as ShuffleControl,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
238
|
+
tt as formatProductPrice,
|
|
239
|
+
P as getBlockElement,
|
|
240
|
+
et as getCardComposition,
|
|
241
|
+
ot as getCurrentLayout,
|
|
242
|
+
rt as reapplySpacing,
|
|
243
|
+
nt as regenerateMobileProductRows,
|
|
244
|
+
it as regenerateProductRows,
|
|
245
|
+
b as regenerateProductRowsWithStyles,
|
|
246
|
+
st as setCurrencyAttributes,
|
|
247
|
+
ct as updatePricesInPlace,
|
|
248
|
+
I as updateProductContentInPlace,
|
|
249
|
+
at as updateSingleProductContent
|
|
217
250
|
};
|
|
@@ -1,45 +1,60 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
1
|
+
var _ = Object.defineProperty;
|
|
2
|
+
var c = (i, o, t) => o in i ? _(i, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[o] = t;
|
|
3
|
+
var d = (i, o, t) => c(i, typeof o != "symbol" ? o + "" : o, t);
|
|
4
|
+
import { EditorStatePropertyType as u, PreviewDeviceMode as R } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as h } from "../../../common-control.js";
|
|
6
|
+
import { MAX_PRODUCT_COUNT as C, MAX_PRODUCTS_PER_ROW as p, MAX_MOBILE_PRODUCTS_PER_ROW as m } from "../../constants/layout.js";
|
|
7
|
+
import { RecommendationConfigService as s } from "../../services/configService.js";
|
|
8
|
+
import { useRecommendationExtensionStore as l } from "../../store/recommendation.js";
|
|
9
|
+
import { ensureMobileCssRulesExist as O } from "../mobileLayout/cssRules.js";
|
|
10
|
+
import { getCurrentLayout as I, regenerateMobileProductRows as g, regenerateProductRowsWithStyles as b } from "./utils.js";
|
|
11
|
+
import { useDebounceFn as N } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
12
|
+
const P = "recommendation-product-layout-control", e = {
|
|
11
13
|
PRODUCT_COUNT: "size",
|
|
12
14
|
PRODUCT_IN_ROW: "cardsInRow",
|
|
13
|
-
PRODUCT_IN_ROW_LABEL: "cardsInRowLabel"
|
|
15
|
+
PRODUCT_IN_ROW_LABEL: "cardsInRowLabel",
|
|
16
|
+
MOBILE_CARDS_IN_ROW: "mobileCardsInRow",
|
|
17
|
+
MOBILE_CARDS_IN_ROW_LABEL: "mobileCardsInRowLabel"
|
|
14
18
|
};
|
|
15
|
-
class
|
|
19
|
+
class S extends h {
|
|
16
20
|
constructor() {
|
|
17
21
|
super(...arguments);
|
|
18
22
|
// Store is used for backward compatibility with product fetching and regeneration
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
d(this, "store", l());
|
|
24
|
+
d(this, "storeUnsubscription", () => {
|
|
21
25
|
});
|
|
22
|
-
|
|
26
|
+
d(this, "_debouncedRegenerateProductRows", N(() => {
|
|
23
27
|
this._regenerateProductRows();
|
|
24
28
|
}, 500));
|
|
25
29
|
}
|
|
26
30
|
getId() {
|
|
27
|
-
return
|
|
31
|
+
return P;
|
|
28
32
|
}
|
|
29
33
|
getTemplate() {
|
|
30
34
|
return `
|
|
31
35
|
<div class="product-layout-control-container">
|
|
32
36
|
${this._GuTwoColumns([
|
|
33
37
|
this._GuLabel({ text: "Number of Products" }),
|
|
34
|
-
this._GuCounter({ name:
|
|
35
|
-
this._GuLabel({
|
|
36
|
-
|
|
38
|
+
this._GuCounter({ name: e.PRODUCT_COUNT, maxValue: C }),
|
|
39
|
+
this._GuLabel({
|
|
40
|
+
text: "Products in One Row on Desktop",
|
|
41
|
+
name: e.PRODUCT_IN_ROW_LABEL
|
|
42
|
+
}),
|
|
43
|
+
this._GuCounter({ name: e.PRODUCT_IN_ROW, maxValue: p }),
|
|
44
|
+
this._GuLabel({
|
|
45
|
+
text: "Products in One Row on Mobile",
|
|
46
|
+
name: e.MOBILE_CARDS_IN_ROW_LABEL
|
|
47
|
+
}),
|
|
48
|
+
this._GuCounter({
|
|
49
|
+
name: e.MOBILE_CARDS_IN_ROW,
|
|
50
|
+
maxValue: m
|
|
51
|
+
})
|
|
37
52
|
])}
|
|
38
53
|
</div>
|
|
39
54
|
`;
|
|
40
55
|
}
|
|
41
56
|
onRender() {
|
|
42
|
-
this._setFormValues(), this._updateProductsInRowVisibility(), this._listenToFormUpdates(), this._listenStateUpdates();
|
|
57
|
+
this._setFormValues(), this._updateProductsInRowVisibility(), this._listenToFormUpdates(), this._listenStateUpdates(), this._subscribeToEditorModeChanges();
|
|
43
58
|
}
|
|
44
59
|
onTemplateNodeUpdated(t) {
|
|
45
60
|
super.onTemplateNodeUpdated(t), this._setFormValues(), this._updateProductsInRowVisibility();
|
|
@@ -48,23 +63,45 @@ class I extends c {
|
|
|
48
63
|
this.storeUnsubscription();
|
|
49
64
|
}
|
|
50
65
|
_setFormValues() {
|
|
51
|
-
const t =
|
|
66
|
+
const t = s.getConfig(this.currentNode);
|
|
52
67
|
this.api.updateValues({
|
|
53
|
-
[
|
|
54
|
-
[
|
|
68
|
+
[e.PRODUCT_COUNT]: t.size,
|
|
69
|
+
[e.PRODUCT_IN_ROW]: t.cardsInRow,
|
|
70
|
+
[e.MOBILE_CARDS_IN_ROW]: t.mobileCardsInRow
|
|
55
71
|
});
|
|
56
72
|
}
|
|
57
73
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
|
|
74
|
+
* Checks if the editor is currently in mobile preview mode
|
|
75
|
+
* using Stripo's EditorStatePropertyType API.
|
|
76
|
+
*/
|
|
77
|
+
_isMobileMode() {
|
|
78
|
+
return this.api.getEditorState()[u.previewDeviceMode] === R.MOBILE;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Updates counter visibility based on layout orientation and editor mode.
|
|
82
|
+
* - List layout: hide both counters (products always full-width)
|
|
83
|
+
* - Grid + desktop mode: show desktop counter, hide mobile counter
|
|
84
|
+
* - Grid + mobile mode: show mobile counter, hide desktop counter
|
|
61
85
|
*/
|
|
62
86
|
_updateProductsInRowVisibility() {
|
|
63
|
-
const
|
|
64
|
-
this.api.setVisibility(
|
|
87
|
+
const r = (s.getConfig(this.currentNode).layout || I(this.currentNode)) === "grid", n = this._isMobileMode();
|
|
88
|
+
this.api.setVisibility(e.PRODUCT_IN_ROW, r && !n), this.api.setVisibility(e.PRODUCT_IN_ROW_LABEL, r && !n), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW, r && n), this.api.setVisibility(e.MOBILE_CARDS_IN_ROW_LABEL, r && n);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Subscribes to editor preview mode changes via Stripo API.
|
|
92
|
+
* When the user switches between desktop/mobile preview, toggles
|
|
93
|
+
* which "Products in One Row" counter is visible.
|
|
94
|
+
*/
|
|
95
|
+
_subscribeToEditorModeChanges() {
|
|
96
|
+
this.api.onEditorStatePropUpdated(
|
|
97
|
+
u.previewDeviceMode,
|
|
98
|
+
() => {
|
|
99
|
+
this._updateProductsInRowVisibility();
|
|
100
|
+
}
|
|
101
|
+
);
|
|
65
102
|
}
|
|
66
103
|
_onProductCountChange(t) {
|
|
67
|
-
this.currentNode && (
|
|
104
|
+
this.currentNode && (s.updateConfig(
|
|
68
105
|
this.api,
|
|
69
106
|
this.currentNode,
|
|
70
107
|
{ size: t },
|
|
@@ -72,24 +109,37 @@ class I extends c {
|
|
|
72
109
|
), this.store.patchCurrentBlockConfig({ size: t }), this._debouncedRegenerateProductRows());
|
|
73
110
|
}
|
|
74
111
|
_onProductsInRowChange(t) {
|
|
75
|
-
this.currentNode && (
|
|
112
|
+
this.currentNode && (s.updateConfig(
|
|
76
113
|
this.api,
|
|
77
114
|
this.currentNode,
|
|
78
115
|
{ cardsInRow: t },
|
|
79
116
|
`Changed products per row to ${t}`
|
|
80
117
|
), this.store.patchCurrentBlockConfig({ cardsInRow: t }), this._debouncedRegenerateProductRows());
|
|
81
118
|
}
|
|
119
|
+
_onMobileCardsInRowChange(t) {
|
|
120
|
+
this.currentNode && (s.updateConfig(
|
|
121
|
+
this.api,
|
|
122
|
+
this.currentNode,
|
|
123
|
+
{ mobileCardsInRow: t },
|
|
124
|
+
`Changed mobile products per row to ${t}`
|
|
125
|
+
), O(this.api), g({
|
|
126
|
+
currentNode: this.currentNode,
|
|
127
|
+
documentModifier: this.api.getDocumentModifier()
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
82
130
|
_regenerateProductRows() {
|
|
83
|
-
|
|
131
|
+
b({
|
|
84
132
|
currentNode: this.currentNode,
|
|
85
133
|
documentModifier: this.api.getDocumentModifier()
|
|
86
134
|
});
|
|
87
135
|
}
|
|
88
136
|
_listenToFormUpdates() {
|
|
89
|
-
this.api.onValueChanged(
|
|
137
|
+
this.api.onValueChanged(e.PRODUCT_COUNT, (t) => {
|
|
90
138
|
this._onProductCountChange(t.toString());
|
|
91
|
-
}), this.api.onValueChanged(
|
|
139
|
+
}), this.api.onValueChanged(e.PRODUCT_IN_ROW, (t) => {
|
|
92
140
|
this._onProductsInRowChange(Number(t));
|
|
141
|
+
}), this.api.onValueChanged(e.MOBILE_CARDS_IN_ROW, (t) => {
|
|
142
|
+
this._onMobileCardsInRowChange(Number(t));
|
|
93
143
|
});
|
|
94
144
|
}
|
|
95
145
|
/**
|
|
@@ -99,12 +149,12 @@ class I extends c {
|
|
|
99
149
|
_listenStateUpdates() {
|
|
100
150
|
let t = this.store.recommendationConfigs.orientation;
|
|
101
151
|
this.storeUnsubscription = this.store.$subscribe(() => {
|
|
102
|
-
const
|
|
103
|
-
|
|
152
|
+
const a = this.store.recommendationConfigs.orientation;
|
|
153
|
+
a !== t && (t = a, this._updateProductsInRowVisibility());
|
|
104
154
|
});
|
|
105
155
|
}
|
|
106
156
|
}
|
|
107
157
|
export {
|
|
108
|
-
|
|
109
|
-
|
|
158
|
+
P as PRODUCT_LAYOUT_CONTROL_ID,
|
|
159
|
+
S as ProductLayoutControl
|
|
110
160
|
};
|