@useinsider/guido 3.8.1-beta.fc167ba → 3.8.2-beta.189e91c
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 +70 -66
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +8 -8
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +15 -12
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +16 -15
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +5 -5
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +42 -37
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +3 -3
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +40 -37
- package/dist/composables/usePreviewInteractionGuard.js +17 -0
- package/dist/composables/usePreviewMode.js +15 -14
- package/dist/composables/useRecommendationPreview.js +111 -0
- package/dist/composables/useSave.js +14 -14
- package/dist/composables/validators/useUnsubscribeBlockValidator.js +26 -17
- package/dist/config/compiler/recommendationCompilerRules.js +1 -1
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +88 -80
- package/dist/config/migrator/recommendation/htmlBuilder.js +53 -52
- package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
- package/dist/extensions/Blocks/Recommendation/block.js +60 -41
- package/dist/extensions/Blocks/Recommendation/canvasPreview.css.js +16 -0
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +345 -264
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +99 -87
- package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +162 -160
- package/dist/extensions/Blocks/Recommendation/extension.js +30 -29
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +3 -1
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +130 -96
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +43 -54
- package/dist/extensions/Blocks/Recommendation/templates/index.js +17 -14
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +86 -80
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +31 -40
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +155 -102
- package/dist/extensions/Blocks/Unsubscribe/block.js +40 -37
- package/dist/extensions/Blocks/Unsubscribe/control.js +19 -16
- package/dist/guido.css +1 -1
- package/dist/src/@types/config/schemas.d.ts +16 -0
- package/dist/src/composables/useConfig.d.ts +4 -0
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +3 -0
- package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +13 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +10 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +51 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
- package/dist/src/stores/config.d.ts +36 -0
- package/dist/src/stores/unsubscribe.d.ts +11 -1
- package/dist/stores/unsubscribe.js +8 -7
- package/package.json +1 -1
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { UIElementType as
|
|
5
|
-
import { CommonControl as
|
|
6
|
-
import { ATTR_PRODUCT_IMAGE as
|
|
7
|
-
import { DEFAULT_COMPOSITION as
|
|
8
|
-
import { RecommendationConfigService as
|
|
1
|
+
var tt = Object.defineProperty;
|
|
2
|
+
var et = (g, b, t) => b in g ? tt(g, b, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[b] = t;
|
|
3
|
+
var I = (g, b, t) => et(g, typeof b != "symbol" ? b + "" : b, t);
|
|
4
|
+
import { UIElementType as _, UEAttr as E, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as rt } from "../../../common-control.js";
|
|
6
|
+
import { ATTR_PRODUCT_IMAGE as k, ATTR_PRODUCT_NAME as it, ATTR_PRODUCT_PRICE as S, ATTR_PRODUCT_OLD_PRICE as v, ATTR_PRODUCT_OMNIBUS_PRICE as ot, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as F, ATTR_CUSTOM_PREFIX as p, BUILT_IN_DEFAULT_ATTRIBUTES as nt } from "../../constants/selectors.js";
|
|
7
|
+
import { DEFAULT_COMPOSITION as x, DEFAULT_VISIBILITY as M } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as P } from "../../services/configService.js";
|
|
9
9
|
import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
|
|
10
|
-
import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as
|
|
10
|
+
import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as dt, buildFillerCell as ut } from "../../templates/grid/elementRenderer.js";
|
|
11
11
|
import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
|
|
12
|
-
import {
|
|
13
|
-
import { getTableDisplayValue as
|
|
14
|
-
import { isPartnerManagedBlock as
|
|
15
|
-
const
|
|
12
|
+
import { resolveInlinePriceOrder as ht, toDisplayName as pt, isDefaultAttribute as gt, toDisplayableAttributeValue as bt, buildElementRenderer as V } from "../../templates/utils.js";
|
|
13
|
+
import { getTableDisplayValue as _t } from "../../utils/tagName.js";
|
|
14
|
+
import { isPartnerManagedBlock as ft, regenerateProductRowsWithStyles as yt, getCurrentLayout as St } from "../main/utils.js";
|
|
15
|
+
const Ct = "ui-elements-recommendation-card-composition", T = ".recommendation-attribute-row", H = ".product-card-wrapper > tbody", j = ".product-info-cell > table > tbody", W = "data-card-composition", y = "data-attribute-type", D = "data-visibility", K = {
|
|
16
16
|
ADD_ATTRIBUTE: "addAttribute"
|
|
17
|
-
},
|
|
18
|
-
{ key:
|
|
19
|
-
{ key:
|
|
20
|
-
{ key:
|
|
21
|
-
{ key:
|
|
17
|
+
}, f = 5, N = "reorderIcon_", At = '<svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><circle cx="2" cy="2.5" r="1.2"/><circle cx="7" cy="2.5" r="1.2"/><circle cx="12" cy="2.5" r="1.2"/><circle cx="2" cy="7.5" r="1.2"/><circle cx="7" cy="7.5" r="1.2"/><circle cx="12" cy="7.5" r="1.2"/></svg>', m = [
|
|
18
|
+
{ key: k, label: "Product Image" },
|
|
19
|
+
{ key: it, label: "Product Name" },
|
|
20
|
+
{ key: S, label: "Product Price" },
|
|
21
|
+
{ key: v, label: "Product Original Price" },
|
|
22
22
|
{ key: ot, label: "Omnibus Price" },
|
|
23
23
|
{ key: st, label: "Omnibus Discount" },
|
|
24
|
-
{ key:
|
|
25
|
-
],
|
|
26
|
-
class
|
|
24
|
+
{ key: U, label: "Product Button" }
|
|
25
|
+
], Tt = new Set(m.map((g) => g.key)), $ = "customAttr_", O = "deleteAttr_";
|
|
26
|
+
class qt extends rt {
|
|
27
27
|
constructor() {
|
|
28
28
|
super(...arguments);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
I(this, "store", lt());
|
|
30
|
+
I(this, "unsubscribeStore", null);
|
|
31
|
+
I(this, "eventController", null);
|
|
32
32
|
/**
|
|
33
33
|
* Guard flag: when true, onTemplateNodeUpdated skips _initializeComposition.
|
|
34
34
|
* Used during _onReorder to prevent multiple intermediate rebuilds.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
I(this, "reorderInProgress", !1);
|
|
37
37
|
}
|
|
38
38
|
getId() {
|
|
39
|
-
return
|
|
39
|
+
return Ct;
|
|
40
40
|
}
|
|
41
41
|
// ========================================================================
|
|
42
42
|
// Lifecycle
|
|
43
43
|
// ========================================================================
|
|
44
44
|
getTemplate() {
|
|
45
|
-
const t =
|
|
46
|
-
<div data-toggle-key="${
|
|
47
|
-
${this._GuToggle(`visibility_${
|
|
45
|
+
const t = m.map((a) => `
|
|
46
|
+
<div data-toggle-key="${a.key}" style="display: none;">
|
|
47
|
+
${this._GuToggle(`visibility_${a.key}`)}
|
|
48
48
|
</div>
|
|
49
49
|
`).join(""), r = Array.from(
|
|
50
|
-
{ length:
|
|
51
|
-
(
|
|
52
|
-
<div data-custom-select-key="${
|
|
50
|
+
{ length: f },
|
|
51
|
+
(a, d) => `
|
|
52
|
+
<div data-custom-select-key="${$}${d}" style="display: none;">
|
|
53
53
|
${this._GuSelect({
|
|
54
|
-
name: `${
|
|
54
|
+
name: `${$}${d}`,
|
|
55
55
|
placeholder: this.api.translate("Select Attribute"),
|
|
56
56
|
options: []
|
|
57
57
|
})}
|
|
58
58
|
</div>
|
|
59
59
|
`
|
|
60
|
-
).join(""), e =
|
|
60
|
+
).join(""), e = m.length + f, o = Array.from(
|
|
61
61
|
{ length: e },
|
|
62
|
-
(
|
|
63
|
-
<div data-reorder-icon-key="${
|
|
64
|
-
<${
|
|
62
|
+
(a, d) => `
|
|
63
|
+
<div data-reorder-icon-key="${N}${d}" style="display: none;">
|
|
64
|
+
<${_.BUTTON}
|
|
65
65
|
class="drag-handle-btn flat-inline flat-white"
|
|
66
|
-
${
|
|
66
|
+
${E.BUTTON.name}="${N}${d}"
|
|
67
67
|
>
|
|
68
|
-
<${
|
|
68
|
+
<${_.ICON}
|
|
69
69
|
src="reorder"
|
|
70
70
|
class="icon-button"
|
|
71
|
-
></${
|
|
72
|
-
</${
|
|
71
|
+
></${_.ICON}>
|
|
72
|
+
</${_.BUTTON}>
|
|
73
73
|
</div>
|
|
74
74
|
`
|
|
75
|
-
).join(""),
|
|
76
|
-
{ length:
|
|
77
|
-
(
|
|
78
|
-
<div data-custom-delete-key="${
|
|
79
|
-
<${
|
|
75
|
+
).join(""), i = Array.from(
|
|
76
|
+
{ length: f },
|
|
77
|
+
(a, d) => `
|
|
78
|
+
<div data-custom-delete-key="${O}${d}" style="display: none;">
|
|
79
|
+
<${_.BUTTON}
|
|
80
80
|
class="custom-attr-delete flat-inline flat-white"
|
|
81
|
-
${
|
|
81
|
+
${E.BUTTON.name}="${O}${d}"
|
|
82
82
|
>
|
|
83
|
-
<${
|
|
83
|
+
<${_.ICON}
|
|
84
84
|
src="delete"
|
|
85
85
|
class="icon-button"
|
|
86
|
-
></${
|
|
87
|
-
</${
|
|
86
|
+
></${_.ICON}>
|
|
87
|
+
</${_.BUTTON}>
|
|
88
88
|
</div>
|
|
89
89
|
`
|
|
90
|
-
).join(""),
|
|
90
|
+
).join(""), s = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
|
|
91
91
|
"Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
|
|
92
|
-
),
|
|
92
|
+
), c = this.api.translate("For more information, you can"), l = this.api.translate("visit Academy");
|
|
93
93
|
return `
|
|
94
94
|
<div class="recommendation-controls-container" data-card-composition-control>
|
|
95
95
|
<div class="container">
|
|
96
96
|
<p class="card-composition-description">
|
|
97
97
|
${n}
|
|
98
|
-
${
|
|
98
|
+
${c}
|
|
99
99
|
<!-- cspell:disable-next-line -->
|
|
100
|
-
<a href="${
|
|
100
|
+
<a href="${s}" target="_blank" rel="noopener noreferrer">${l}</a>.
|
|
101
101
|
</p>
|
|
102
102
|
</div>
|
|
103
103
|
|
|
@@ -110,7 +110,7 @@ class Ut extends Z {
|
|
|
110
110
|
</div>
|
|
111
111
|
|
|
112
112
|
<div class="custom-delete-store" style="display: none;">
|
|
113
|
-
${
|
|
113
|
+
${i}
|
|
114
114
|
</div>
|
|
115
115
|
|
|
116
116
|
<div class="reorder-icon-store" style="display: none;">
|
|
@@ -120,7 +120,7 @@ class Ut extends Z {
|
|
|
120
120
|
<div class="orderable-list" data-composition-list></div>
|
|
121
121
|
|
|
122
122
|
${this._GuButton({
|
|
123
|
-
name:
|
|
123
|
+
name: K.ADD_ATTRIBUTE,
|
|
124
124
|
label: this.api.translate("Add Attribute"),
|
|
125
125
|
id: "guido__btn-add-attribute"
|
|
126
126
|
})}
|
|
@@ -141,7 +141,7 @@ class Ut extends Z {
|
|
|
141
141
|
const t = (e = this.getContainer()) == null ? void 0 : e.querySelector("[data-card-composition-control]");
|
|
142
142
|
if (!t)
|
|
143
143
|
return;
|
|
144
|
-
const r =
|
|
144
|
+
const r = ft(this.currentNode);
|
|
145
145
|
t.style.pointerEvents = r ? "none" : "", t.style.opacity = r ? "0.5" : "";
|
|
146
146
|
}
|
|
147
147
|
onTemplateNodeUpdated(t) {
|
|
@@ -154,17 +154,17 @@ class Ut extends Z {
|
|
|
154
154
|
// Initialization
|
|
155
155
|
// ========================================================================
|
|
156
156
|
_initializeComposition() {
|
|
157
|
-
const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), o = this._renderOrderableItems(t, r),
|
|
158
|
-
this.api.updateValues(
|
|
157
|
+
const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), o = this._renderOrderableItems(t, r), i = this._buildVisibilityValues(e);
|
|
158
|
+
this.api.updateValues(i), o && this._initializeCustomSelects(r), this._updateAddButtonState();
|
|
159
159
|
}
|
|
160
160
|
_registerValueChangeListeners() {
|
|
161
|
-
|
|
161
|
+
m.forEach((t) => {
|
|
162
162
|
this.api.onValueChanged(`visibility_${t.key}`, (r) => {
|
|
163
163
|
this._applyVisibilityToBlock(t.key, r);
|
|
164
164
|
});
|
|
165
165
|
});
|
|
166
|
-
for (let t = 0; t <
|
|
167
|
-
const r = `${
|
|
166
|
+
for (let t = 0; t < f; t++) {
|
|
167
|
+
const r = `${$}${t}`, e = t;
|
|
168
168
|
this.api.onValueChanged(r, (o) => {
|
|
169
169
|
this._onCustomAttributeChanged(e, o);
|
|
170
170
|
});
|
|
@@ -175,14 +175,14 @@ class Ut extends Z {
|
|
|
175
175
|
// ========================================================================
|
|
176
176
|
_readCompositionFromNode() {
|
|
177
177
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
178
|
-
return [...
|
|
179
|
-
const t = this.currentNode.getAttribute(
|
|
180
|
-
return t ? t.split(",").filter(Boolean) : [...
|
|
178
|
+
return [...x];
|
|
179
|
+
const t = this.currentNode.getAttribute(W);
|
|
180
|
+
return t ? t.split(",").filter(Boolean) : [...x];
|
|
181
181
|
}
|
|
182
182
|
_readCustomAttributesFromNode() {
|
|
183
183
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
184
184
|
return [];
|
|
185
|
-
const t = this.currentNode.getAttribute(
|
|
185
|
+
const t = this.currentNode.getAttribute(F);
|
|
186
186
|
if (!t)
|
|
187
187
|
return [];
|
|
188
188
|
try {
|
|
@@ -194,31 +194,31 @@ class Ut extends Z {
|
|
|
194
194
|
_readVisibilityFromRows() {
|
|
195
195
|
if (!this.currentNode)
|
|
196
196
|
return this._getDefaultVisibilities();
|
|
197
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
197
|
+
const t = Array.from(this.currentNode.querySelectorAll(T)), r = this._extractVisibilityFromRows(t);
|
|
198
198
|
return this._mergeWithDefaults(r);
|
|
199
199
|
}
|
|
200
200
|
_getDefaultVisibilities() {
|
|
201
|
-
return { ...
|
|
201
|
+
return { ...M };
|
|
202
202
|
}
|
|
203
203
|
_extractVisibilityFromRows(t) {
|
|
204
204
|
const r = {};
|
|
205
205
|
return t.forEach((e) => {
|
|
206
206
|
if (!("getAttribute" in e))
|
|
207
207
|
return;
|
|
208
|
-
const o = e.getAttribute(y),
|
|
209
|
-
o &&
|
|
208
|
+
const o = e.getAttribute(y), i = e.getAttribute(D);
|
|
209
|
+
o && i !== null && (r[o] = this._parseVisibilityValue(i));
|
|
210
210
|
}), r;
|
|
211
211
|
}
|
|
212
212
|
_parseVisibilityValue(t) {
|
|
213
213
|
return t === "1" || t === "true";
|
|
214
214
|
}
|
|
215
215
|
_mergeWithDefaults(t) {
|
|
216
|
-
return Object.entries(
|
|
216
|
+
return Object.entries(M).forEach(([r, e]) => {
|
|
217
217
|
r in t || (t[r] = e);
|
|
218
218
|
}), t;
|
|
219
219
|
}
|
|
220
220
|
_buildVisibilityValues(t) {
|
|
221
|
-
return
|
|
221
|
+
return m.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
|
|
222
222
|
}
|
|
223
223
|
// ========================================================================
|
|
224
224
|
// UI Rendering (Orderable List)
|
|
@@ -233,23 +233,29 @@ class Ut extends Z {
|
|
|
233
233
|
if (!e)
|
|
234
234
|
return !1;
|
|
235
235
|
const o = e.querySelector("[data-composition-list]");
|
|
236
|
-
if (!o
|
|
236
|
+
if (!o)
|
|
237
237
|
return !1;
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
238
|
+
const i = !P.getConfig(this.currentNode).priceMovedToNextLine;
|
|
239
|
+
if (!(o.dataset.inlinePrices !== String(i)) && this._tryReorderInPlace(o, t))
|
|
240
|
+
return !1;
|
|
241
|
+
o.dataset.inlinePrices = String(i);
|
|
242
|
+
const n = new Set(r), c = ht(t);
|
|
243
|
+
let l = 0, a = 0;
|
|
244
|
+
const d = t.map((u) => {
|
|
245
|
+
if (i && (u === S || u === v))
|
|
246
|
+
return u === c.anchor ? this._createPriceGroupItemHtml(a++, c.originalFirst) : "";
|
|
247
|
+
if (Tt.has(u)) {
|
|
248
|
+
const h = m.find((C) => C.key === u);
|
|
249
|
+
return this._createBuiltInItemHtml(h, a++);
|
|
244
250
|
}
|
|
245
|
-
if (
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
return this._createCustomItemHtml(
|
|
251
|
+
if (u.startsWith(p)) {
|
|
252
|
+
const h = u.substring(p.length);
|
|
253
|
+
if (n.has(h))
|
|
254
|
+
return this._createCustomItemHtml(u, l++, a++);
|
|
249
255
|
}
|
|
250
256
|
return "";
|
|
251
257
|
}).join("");
|
|
252
|
-
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML =
|
|
258
|
+
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = d, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, a), !0;
|
|
253
259
|
}
|
|
254
260
|
/**
|
|
255
261
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -261,27 +267,27 @@ class Ut extends Z {
|
|
|
261
267
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
262
268
|
if (e.length !== r.length)
|
|
263
269
|
return !1;
|
|
264
|
-
const o = e.map((
|
|
270
|
+
const o = e.map((l) => l.dataset.key).filter(Boolean);
|
|
265
271
|
if (o.length !== r.length)
|
|
266
272
|
return !1;
|
|
267
|
-
const
|
|
268
|
-
if (
|
|
273
|
+
const i = [...o].sort().join(","), s = [...r].sort().join(",");
|
|
274
|
+
if (i !== s || r.some((l) => l.startsWith(p)))
|
|
269
275
|
return !1;
|
|
270
276
|
const n = /* @__PURE__ */ new Map();
|
|
271
|
-
e.forEach((
|
|
272
|
-
const { key:
|
|
273
|
-
if (
|
|
274
|
-
const
|
|
275
|
-
|
|
277
|
+
e.forEach((l) => {
|
|
278
|
+
const { key: a } = l.dataset;
|
|
279
|
+
if (a) {
|
|
280
|
+
const d = n.get(a) || [];
|
|
281
|
+
d.push(l), n.set(a, d);
|
|
276
282
|
}
|
|
277
283
|
});
|
|
278
|
-
const
|
|
279
|
-
return r.forEach((
|
|
280
|
-
const
|
|
281
|
-
if (!
|
|
284
|
+
const c = /* @__PURE__ */ new Map();
|
|
285
|
+
return r.forEach((l) => {
|
|
286
|
+
const a = n.get(l);
|
|
287
|
+
if (!a)
|
|
282
288
|
return;
|
|
283
|
-
const
|
|
284
|
-
|
|
289
|
+
const d = c.get(l) || 0;
|
|
290
|
+
c.set(l, d + 1), a[d] && t.appendChild(a[d]);
|
|
285
291
|
}), !0;
|
|
286
292
|
}
|
|
287
293
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -293,6 +299,33 @@ class Ut extends Z {
|
|
|
293
299
|
</div>
|
|
294
300
|
`;
|
|
295
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Inline mode: the merged "Product Prices" group item. It moves as a unit in
|
|
304
|
+
* the main list (both keys stay adjacent) and contains a nested 2-item drag
|
|
305
|
+
* to reorder Product Price ↔ Product Original Price — which flips the inline
|
|
306
|
+
* render order via `resolveInlinePriceOrder`. The group keeps a single
|
|
307
|
+
* visibility toggle (`data-action-for="productPrice"`). Nested sub-items use a
|
|
308
|
+
* plain drag handle (no UE button → untouched by the reorder-icon rescue).
|
|
309
|
+
*/
|
|
310
|
+
_createPriceGroupItemHtml(t, r) {
|
|
311
|
+
var n, c;
|
|
312
|
+
const e = ((n = m.find((l) => l.key === S)) == null ? void 0 : n.label) ?? "Product Price", o = ((c = m.find((l) => l.key === v)) == null ? void 0 : c.label) ?? "Product Original Price", i = (l, a) => `
|
|
313
|
+
<div class="price-suborderable-item" draggable="true" data-subkey="${l}">
|
|
314
|
+
<span class="sub-drag-handle">${At}</span>
|
|
315
|
+
<span class="item-label">${this.api.translate(a)}</span>
|
|
316
|
+
</div>`, s = r ? i(v, o) + i(S, e) : i(S, e) + i(v, o);
|
|
317
|
+
return `
|
|
318
|
+
<div class="orderable-item price-group-item" draggable="true"
|
|
319
|
+
data-key="${S}" data-group="prices">
|
|
320
|
+
<div class="price-group-header">
|
|
321
|
+
<span class="drag-handle" data-reorder-icon-slot="${t}"></span>
|
|
322
|
+
<span class="item-label">${this.api.translate("Product Prices")}</span>
|
|
323
|
+
<div class="item-action" data-action-for="${S}"></div>
|
|
324
|
+
</div>
|
|
325
|
+
<div class="price-suborderable-list">${s}</div>
|
|
326
|
+
</div>
|
|
327
|
+
`;
|
|
328
|
+
}
|
|
296
329
|
_createCustomItemHtml(t, r, e) {
|
|
297
330
|
return `
|
|
298
331
|
<div class="orderable-item" draggable="true"
|
|
@@ -313,10 +346,10 @@ class Ut extends Z {
|
|
|
313
346
|
_getSelectOptions(t, r = []) {
|
|
314
347
|
const e = this._getAddableFilters();
|
|
315
348
|
if (e.length > 0) {
|
|
316
|
-
const
|
|
317
|
-
return
|
|
318
|
-
text:
|
|
319
|
-
value:
|
|
349
|
+
const i = new Set(r);
|
|
350
|
+
return i.delete(t), e.filter((s) => !i.has(s.attributeName)).map((s) => ({
|
|
351
|
+
text: s.displayName,
|
|
352
|
+
value: s.attributeName
|
|
320
353
|
}));
|
|
321
354
|
}
|
|
322
355
|
return [{ text: this._getDisplayNameForAttribute(t), value: t }];
|
|
@@ -329,8 +362,8 @@ class Ut extends Z {
|
|
|
329
362
|
_initializeCustomSelects(t) {
|
|
330
363
|
t.length !== 0 && setTimeout(() => {
|
|
331
364
|
t.forEach((r, e) => {
|
|
332
|
-
const o = `${
|
|
333
|
-
this.api.setUIEAttribute(o,
|
|
365
|
+
const o = `${$}${e}`, i = this._getSelectOptions(r, t);
|
|
366
|
+
this.api.setUIEAttribute(o, E.SELECTPICKER.items, i), this.api.updateValues({ [o]: r });
|
|
334
367
|
});
|
|
335
368
|
}, 0);
|
|
336
369
|
}
|
|
@@ -339,11 +372,11 @@ class Ut extends Z {
|
|
|
339
372
|
* Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
|
|
340
373
|
*/
|
|
341
374
|
_moveTogglesIntoItems(t) {
|
|
342
|
-
|
|
375
|
+
m.forEach((r) => {
|
|
343
376
|
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
344
377
|
if (e && o) {
|
|
345
|
-
const
|
|
346
|
-
|
|
378
|
+
const i = e.querySelector("ue-switcher");
|
|
379
|
+
i && o.appendChild(i);
|
|
347
380
|
}
|
|
348
381
|
});
|
|
349
382
|
}
|
|
@@ -353,10 +386,10 @@ class Ut extends Z {
|
|
|
353
386
|
*/
|
|
354
387
|
_moveSelectsIntoItems(t, r) {
|
|
355
388
|
for (let e = 0; e < r; e++) {
|
|
356
|
-
const o = `${
|
|
357
|
-
if (
|
|
358
|
-
const n =
|
|
359
|
-
n &&
|
|
389
|
+
const o = `${$}${e}`, i = t.querySelector(`[data-custom-select-key="${o}"]`), s = t.querySelector(`[data-custom-select-slot="${e}"]`);
|
|
390
|
+
if (i && s) {
|
|
391
|
+
const n = i.querySelector("ue-select");
|
|
392
|
+
n && s.appendChild(n);
|
|
360
393
|
}
|
|
361
394
|
}
|
|
362
395
|
}
|
|
@@ -367,11 +400,11 @@ class Ut extends Z {
|
|
|
367
400
|
* previously-moved toggles, making them permanently lost.
|
|
368
401
|
*/
|
|
369
402
|
_rescueTogglesToStore(t) {
|
|
370
|
-
|
|
403
|
+
m.forEach((r) => {
|
|
371
404
|
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
372
405
|
if (o) {
|
|
373
|
-
const
|
|
374
|
-
|
|
406
|
+
const i = o.querySelector("ue-switcher");
|
|
407
|
+
i && e && e.appendChild(i);
|
|
375
408
|
}
|
|
376
409
|
});
|
|
377
410
|
}
|
|
@@ -380,11 +413,11 @@ class Ut extends Z {
|
|
|
380
413
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
381
414
|
*/
|
|
382
415
|
_rescueSelectsToStore(t) {
|
|
383
|
-
for (let r = 0; r <
|
|
384
|
-
const e = `${
|
|
385
|
-
if (
|
|
386
|
-
const
|
|
387
|
-
|
|
416
|
+
for (let r = 0; r < f; r++) {
|
|
417
|
+
const e = `${$}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), i = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
418
|
+
if (i) {
|
|
419
|
+
const s = i.querySelector("ue-select");
|
|
420
|
+
s && o && o.appendChild(s);
|
|
388
421
|
}
|
|
389
422
|
}
|
|
390
423
|
}
|
|
@@ -394,10 +427,10 @@ class Ut extends Z {
|
|
|
394
427
|
*/
|
|
395
428
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
396
429
|
for (let e = 0; e < r; e++) {
|
|
397
|
-
const o = `${
|
|
398
|
-
if (
|
|
399
|
-
const n =
|
|
400
|
-
n &&
|
|
430
|
+
const o = `${O}${e}`, i = t.querySelector(`[data-custom-delete-key="${o}"]`), s = t.querySelector(`[data-custom-delete-slot="${e}"]`);
|
|
431
|
+
if (i && s) {
|
|
432
|
+
const n = i.querySelector("ue-button");
|
|
433
|
+
n && s.appendChild(n);
|
|
401
434
|
}
|
|
402
435
|
}
|
|
403
436
|
}
|
|
@@ -406,11 +439,11 @@ class Ut extends Z {
|
|
|
406
439
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
407
440
|
*/
|
|
408
441
|
_rescueDeleteButtonsToStore(t) {
|
|
409
|
-
for (let r = 0; r <
|
|
410
|
-
const e = `${
|
|
411
|
-
if (
|
|
412
|
-
const
|
|
413
|
-
|
|
442
|
+
for (let r = 0; r < f; r++) {
|
|
443
|
+
const e = `${O}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), i = t.querySelector(`[data-custom-delete-slot="${r}"]`);
|
|
444
|
+
if (i) {
|
|
445
|
+
const s = i.querySelector("ue-button");
|
|
446
|
+
s && o && o.appendChild(s);
|
|
414
447
|
}
|
|
415
448
|
}
|
|
416
449
|
}
|
|
@@ -420,10 +453,10 @@ class Ut extends Z {
|
|
|
420
453
|
*/
|
|
421
454
|
_moveReorderIconsIntoItems(t, r) {
|
|
422
455
|
for (let e = 0; e < r; e++) {
|
|
423
|
-
const o = `${
|
|
424
|
-
if (
|
|
425
|
-
const n =
|
|
426
|
-
n &&
|
|
456
|
+
const o = `${N}${e}`, i = t.querySelector(`[data-reorder-icon-key="${o}"]`), s = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
457
|
+
if (i && s) {
|
|
458
|
+
const n = i.querySelector("ue-button");
|
|
459
|
+
n && s.appendChild(n);
|
|
427
460
|
}
|
|
428
461
|
}
|
|
429
462
|
}
|
|
@@ -432,12 +465,12 @@ class Ut extends Z {
|
|
|
432
465
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
433
466
|
*/
|
|
434
467
|
_rescueReorderIconsToStore(t) {
|
|
435
|
-
const r =
|
|
468
|
+
const r = m.length + f;
|
|
436
469
|
for (let e = 0; e < r; e++) {
|
|
437
|
-
const o = `${
|
|
438
|
-
if (
|
|
439
|
-
const n =
|
|
440
|
-
n &&
|
|
470
|
+
const o = `${N}${e}`, i = t.querySelector(`[data-reorder-icon-key="${o}"]`), s = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
471
|
+
if (s) {
|
|
472
|
+
const n = s.querySelector("ue-button");
|
|
473
|
+
n && i && i.appendChild(n);
|
|
441
474
|
}
|
|
442
475
|
}
|
|
443
476
|
}
|
|
@@ -451,39 +484,81 @@ class Ut extends Z {
|
|
|
451
484
|
return;
|
|
452
485
|
const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
|
|
453
486
|
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
|
|
454
|
-
const
|
|
455
|
-
|
|
487
|
+
const i = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !i.has(n.attributeName));
|
|
488
|
+
s && this._onAddAttribute(s.attributeName, s.displayName);
|
|
456
489
|
}, { signal: t });
|
|
457
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Builds the composition key order from the orderable list, expanding the
|
|
493
|
+
* inline "Product Prices" group into its two sub-keys (in nested DOM order)
|
|
494
|
+
* so both price keys stay adjacent and in the user-chosen order.
|
|
495
|
+
*/
|
|
496
|
+
_extractCompositionOrder(t) {
|
|
497
|
+
const r = [];
|
|
498
|
+
return t.querySelectorAll(".orderable-item").forEach((e) => {
|
|
499
|
+
const o = e;
|
|
500
|
+
o.dataset.group === "prices" ? o.querySelectorAll(".price-suborderable-item").forEach((i) => {
|
|
501
|
+
const s = i.dataset.subkey;
|
|
502
|
+
s && r.push(s);
|
|
503
|
+
}) : o.dataset.key && r.push(o.dataset.key);
|
|
504
|
+
}), r;
|
|
505
|
+
}
|
|
458
506
|
_setupDragAndDrop(t, r) {
|
|
459
|
-
|
|
460
|
-
|
|
507
|
+
this._registerDragHandlers(t, r, {
|
|
508
|
+
itemSelector: ".orderable-item",
|
|
509
|
+
ignoreSelector: ".price-suborderable-item",
|
|
510
|
+
getDropParent: () => t
|
|
511
|
+
}), this._registerDragHandlers(t, r, {
|
|
512
|
+
itemSelector: ".price-suborderable-item",
|
|
513
|
+
getDropParent: (e) => e.parentElement
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Wires drag/drop reordering for one item level on the shared list. Both the
|
|
518
|
+
* top-level items and the nested price sub-items use this; they never fight
|
|
519
|
+
* because each only sets its `dragged` ref when its own `itemSelector` matches
|
|
520
|
+
* at dragstart (and the top-level one additionally ignores drags originating
|
|
521
|
+
* inside `ignoreSelector`). Every drop re-reads the full composition via
|
|
522
|
+
* `_extractCompositionOrder`, so both levels commit through `_onReorder`
|
|
523
|
+
* identically.
|
|
524
|
+
*/
|
|
525
|
+
_registerDragHandlers(t, r, e) {
|
|
526
|
+
let o = null, i = null;
|
|
527
|
+
const s = (n) => n.target.closest(e.itemSelector);
|
|
528
|
+
t.addEventListener("dragstart", (n) => {
|
|
461
529
|
var a;
|
|
462
|
-
const
|
|
463
|
-
|
|
530
|
+
const c = n.target;
|
|
531
|
+
if (e.ignoreSelector && c.closest(e.ignoreSelector))
|
|
532
|
+
return;
|
|
533
|
+
const l = s(n);
|
|
534
|
+
l && (o = l, l.classList.add("dragging"), (a = n.dataTransfer) == null || a.setData("text/plain", l.dataset.key ?? l.dataset.subkey ?? ""));
|
|
464
535
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
465
|
-
|
|
466
|
-
}, { signal: r }), t.addEventListener("dragover", (
|
|
467
|
-
|
|
468
|
-
const n = s.target.closest(".orderable-item"), a = n && n !== e ? n : null;
|
|
469
|
-
a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
|
|
470
|
-
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
471
|
-
s.preventDefault();
|
|
472
|
-
const n = s.target.closest(".orderable-item");
|
|
473
|
-
if (!n || !e || n === e)
|
|
536
|
+
o == null || o.classList.remove("dragging"), i == null || i.classList.remove("drag-over"), o = null, i = null;
|
|
537
|
+
}, { signal: r }), t.addEventListener("dragover", (n) => {
|
|
538
|
+
if (!o)
|
|
474
539
|
return;
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
540
|
+
const c = s(n);
|
|
541
|
+
if (!c)
|
|
542
|
+
return;
|
|
543
|
+
n.preventDefault();
|
|
544
|
+
const l = c !== o ? c : null;
|
|
545
|
+
l !== i && (i == null || i.classList.remove("drag-over"), i = l, i == null || i.classList.add("drag-over"));
|
|
546
|
+
}, { signal: r }), t.addEventListener("drop", (n) => {
|
|
547
|
+
var d;
|
|
548
|
+
const c = o && s(n);
|
|
549
|
+
if (!o || !c || c === o)
|
|
550
|
+
return;
|
|
551
|
+
n.preventDefault();
|
|
552
|
+
const l = c.getBoundingClientRect(), a = n.clientY < l.top + l.height / 2;
|
|
553
|
+
(d = e.getDropParent(c)) == null || d.insertBefore(o, a ? c : c.nextSibling), i == null || i.classList.remove("drag-over"), o.classList.remove("dragging"), o = null, i = null, this._onReorder(this._extractCompositionOrder(t));
|
|
479
554
|
}, { signal: r });
|
|
480
555
|
}
|
|
481
556
|
_setupDeleteHandler(t, r) {
|
|
482
557
|
t.addEventListener("click", (e) => {
|
|
483
|
-
const
|
|
484
|
-
if (!
|
|
558
|
+
const i = e.target.closest(".custom-attr-delete");
|
|
559
|
+
if (!i)
|
|
485
560
|
return;
|
|
486
|
-
const
|
|
561
|
+
const s = i.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
|
|
487
562
|
n !== void 0 && this._onDeleteCustomAttribute(Number(n));
|
|
488
563
|
}, { signal: r });
|
|
489
564
|
}
|
|
@@ -491,10 +566,10 @@ class Ut extends Z {
|
|
|
491
566
|
// Actions (Add, Delete, Reorder)
|
|
492
567
|
// ========================================================================
|
|
493
568
|
_onAddAttribute(t, r) {
|
|
494
|
-
const e = `${
|
|
569
|
+
const e = `${p}${t}`, o = this._readCompositionFromNode();
|
|
495
570
|
o.push(e);
|
|
496
|
-
const
|
|
497
|
-
this._updateBothAttributes(o,
|
|
571
|
+
const i = [...this._readCustomAttributesFromNode(), t];
|
|
572
|
+
this._updateBothAttributes(o, i), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, i), this._initializeCustomSelects(i), this._updateAddButtonState();
|
|
498
573
|
}
|
|
499
574
|
/**
|
|
500
575
|
* Removes a single custom attribute by its index in the customAttrs array.
|
|
@@ -504,8 +579,8 @@ class Ut extends Z {
|
|
|
504
579
|
const r = this._readCustomAttributesFromNode();
|
|
505
580
|
if (r[t] === void 0)
|
|
506
581
|
return;
|
|
507
|
-
const o = this._readCompositionFromNode(),
|
|
508
|
-
this._updateBothAttributes(
|
|
582
|
+
const o = this._readCompositionFromNode(), i = this._findNthCustomKeyIndex(o, t), s = o.filter((c, l) => l !== i), n = r.filter((c, l) => l !== t);
|
|
583
|
+
this._updateBothAttributes(s, n), this._removeCustomAttributeHtml(s), this._renderOrderableItems(s, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
509
584
|
}
|
|
510
585
|
/**
|
|
511
586
|
* Handles changing a custom attribute's selection via its inline _GuSelect.
|
|
@@ -515,16 +590,21 @@ class Ut extends Z {
|
|
|
515
590
|
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
516
591
|
if (o === void 0 || o === r)
|
|
517
592
|
return;
|
|
518
|
-
const
|
|
519
|
-
n !== -1 && (
|
|
520
|
-
const
|
|
521
|
-
this._updateBothAttributes(
|
|
593
|
+
const i = `${p}${r}`, s = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(s, t);
|
|
594
|
+
n !== -1 && (s[n] = i), e[t] = r;
|
|
595
|
+
const c = this._getDisplayNameForAttribute(r);
|
|
596
|
+
this._updateBothAttributes(s, e), this._injectCustomAttributeHtml(r, c, i, s), this._renderOrderableItems(s, e), this._initializeCustomSelects(e);
|
|
522
597
|
}
|
|
523
598
|
_onReorder(t) {
|
|
524
|
-
const r = t.filter((e) => e.startsWith(
|
|
599
|
+
const r = t.filter((e) => e.startsWith(p)).map((e) => e.substring(p.length));
|
|
525
600
|
this.reorderInProgress = !0;
|
|
526
601
|
try {
|
|
527
|
-
this._updateBothAttributes(t, r)
|
|
602
|
+
this._updateBothAttributes(t, r);
|
|
603
|
+
const e = !P.getConfig(this.currentNode).priceMovedToNextLine;
|
|
604
|
+
this._getCurrentLayout() === "grid" && !e ? this._reorderProductAttributes(t) : this.currentNode && yt({
|
|
605
|
+
currentNode: this.currentNode,
|
|
606
|
+
documentModifier: this.api.getDocumentModifier()
|
|
607
|
+
});
|
|
528
608
|
} finally {
|
|
529
609
|
this.reorderInProgress = !1;
|
|
530
610
|
}
|
|
@@ -539,60 +619,60 @@ class Ut extends Z {
|
|
|
539
619
|
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
|
|
540
620
|
}
|
|
541
621
|
_injectGridAttributeRow(t, r, e, o) {
|
|
542
|
-
const
|
|
543
|
-
if (!(
|
|
622
|
+
const i = this.currentNode.querySelectorAll(H);
|
|
623
|
+
if (!(i != null && i.length))
|
|
544
624
|
return;
|
|
545
|
-
const
|
|
546
|
-
let
|
|
547
|
-
|
|
548
|
-
var
|
|
549
|
-
const
|
|
550
|
-
if (
|
|
551
|
-
const
|
|
552
|
-
{ length:
|
|
553
|
-
(
|
|
554
|
-
const
|
|
625
|
+
const s = P.getConfig(this.currentNode), c = `0 ${Math.floor(s.columnSpacing / 2)}px`, l = this.api.getDocumentModifier(), a = this.store.recommendationProducts.length;
|
|
626
|
+
let d = 0;
|
|
627
|
+
i.forEach((u) => {
|
|
628
|
+
var B;
|
|
629
|
+
const h = u.querySelector(T), C = ((B = h == null ? void 0 : h.querySelectorAll(`.${at}`)) == null ? void 0 : B.length) || 1, q = (100 / C).toFixed(2), { bgStyle: G, bgAttr: z } = this._extractSegmentBgFromCard(u), R = a > 0 ? Math.min(C, a - d) : C, Y = o.map((w) => {
|
|
630
|
+
if (w === e) {
|
|
631
|
+
const X = Array.from(
|
|
632
|
+
{ length: R },
|
|
633
|
+
($t, Q) => {
|
|
634
|
+
const Z = this._resolveAttributeContent(
|
|
555
635
|
t,
|
|
556
636
|
r,
|
|
557
|
-
|
|
637
|
+
d + Q
|
|
558
638
|
);
|
|
559
639
|
return this._getGridCellHtml(
|
|
560
640
|
t,
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
641
|
+
Z,
|
|
642
|
+
q,
|
|
643
|
+
G,
|
|
644
|
+
z,
|
|
645
|
+
c
|
|
566
646
|
);
|
|
567
647
|
}
|
|
568
|
-
).join(""),
|
|
569
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
648
|
+
).join(""), J = ut(q, c).repeat(C - R);
|
|
649
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${D}="1">${X}${J}</tr>`;
|
|
570
650
|
}
|
|
571
|
-
const
|
|
572
|
-
`${
|
|
651
|
+
const L = u.querySelector(
|
|
652
|
+
`${T}[${y}="${w}"]`
|
|
573
653
|
);
|
|
574
|
-
return
|
|
654
|
+
return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
|
|
575
655
|
}).join("");
|
|
576
|
-
|
|
577
|
-
}),
|
|
656
|
+
d += R, a > 0 && d >= a && (d = 0), l.modifyHtml(u).setInnerHtml(Y);
|
|
657
|
+
}), l.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
578
658
|
}
|
|
579
659
|
_injectListAttributeRow(t, r, e, o) {
|
|
580
|
-
const
|
|
581
|
-
if (!(
|
|
660
|
+
const i = this.currentNode.querySelectorAll(j);
|
|
661
|
+
if (!(i != null && i.length))
|
|
582
662
|
return;
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
const
|
|
586
|
-
if (
|
|
587
|
-
const
|
|
588
|
-
return this._getListRowHtml(t,
|
|
663
|
+
const s = o.filter((c) => c !== k && c !== U), n = this.api.getDocumentModifier();
|
|
664
|
+
i.forEach((c, l) => {
|
|
665
|
+
const a = s.map((d) => {
|
|
666
|
+
if (d === e) {
|
|
667
|
+
const h = this._resolveAttributeContent(t, r, l);
|
|
668
|
+
return this._getListRowHtml(t, h, e);
|
|
589
669
|
}
|
|
590
|
-
const
|
|
591
|
-
`${
|
|
670
|
+
const u = c.querySelector(
|
|
671
|
+
`${T}[${y}="${d}"]`
|
|
592
672
|
);
|
|
593
|
-
return
|
|
673
|
+
return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
|
|
594
674
|
}).join("");
|
|
595
|
-
n.modifyHtml(
|
|
675
|
+
n.modifyHtml(c).setInnerHtml(a);
|
|
596
676
|
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
597
677
|
}
|
|
598
678
|
/**
|
|
@@ -604,16 +684,16 @@ class Ut extends Z {
|
|
|
604
684
|
return;
|
|
605
685
|
const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
|
|
606
686
|
if (r === "grid") {
|
|
607
|
-
const o = this.currentNode.querySelectorAll(
|
|
608
|
-
o == null || o.forEach((
|
|
609
|
-
const
|
|
610
|
-
e.modifyHtml(
|
|
687
|
+
const o = this.currentNode.querySelectorAll(H);
|
|
688
|
+
o == null || o.forEach((i) => {
|
|
689
|
+
const s = this._buildCompositionHtml(i, t);
|
|
690
|
+
e.modifyHtml(i).setInnerHtml(s);
|
|
611
691
|
});
|
|
612
692
|
} else {
|
|
613
|
-
const o = t.filter((
|
|
614
|
-
|
|
615
|
-
const n = this._buildCompositionHtml(
|
|
616
|
-
e.modifyHtml(
|
|
693
|
+
const o = t.filter((s) => s !== k && s !== U), i = this.currentNode.querySelectorAll(j);
|
|
694
|
+
i == null || i.forEach((s) => {
|
|
695
|
+
const n = this._buildCompositionHtml(s, o);
|
|
696
|
+
e.modifyHtml(s).setInnerHtml(n);
|
|
617
697
|
});
|
|
618
698
|
}
|
|
619
699
|
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
@@ -629,7 +709,7 @@ class Ut extends Z {
|
|
|
629
709
|
* producing a flicker on the custom attribute dropdowns.
|
|
630
710
|
*/
|
|
631
711
|
_updateBothAttributes(t, r) {
|
|
632
|
-
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(
|
|
712
|
+
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(W, t.join(",")).setAttribute(F, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
|
|
633
713
|
}
|
|
634
714
|
/**
|
|
635
715
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -638,13 +718,13 @@ class Ut extends Z {
|
|
|
638
718
|
_reorderProductAttributes(t) {
|
|
639
719
|
if (!this.currentNode)
|
|
640
720
|
return;
|
|
641
|
-
const r = this.currentNode.querySelectorAll(
|
|
721
|
+
const r = this.currentNode.querySelectorAll(H);
|
|
642
722
|
if (!(r != null && r.length))
|
|
643
723
|
return;
|
|
644
724
|
const e = this.api.getDocumentModifier();
|
|
645
725
|
r.forEach((o) => {
|
|
646
|
-
const
|
|
647
|
-
e.modifyHtml(o).setInnerHtml(
|
|
726
|
+
const i = this._buildCompositionHtml(o, t);
|
|
727
|
+
e.modifyHtml(o).setInnerHtml(i);
|
|
648
728
|
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
649
729
|
}
|
|
650
730
|
/**
|
|
@@ -653,8 +733,8 @@ class Ut extends Z {
|
|
|
653
733
|
*/
|
|
654
734
|
_buildCompositionHtml(t, r) {
|
|
655
735
|
return r.reduce((e, o) => {
|
|
656
|
-
const
|
|
657
|
-
return
|
|
736
|
+
const i = t.querySelector(`${T}[${y}="${o}"]`);
|
|
737
|
+
return i && "getOuterHTML" in i ? e + i.getOuterHTML() : e;
|
|
658
738
|
}, "");
|
|
659
739
|
}
|
|
660
740
|
// ========================================================================
|
|
@@ -663,14 +743,14 @@ class Ut extends Z {
|
|
|
663
743
|
_applyVisibilityToBlock(t, r) {
|
|
664
744
|
if (!this.currentNode)
|
|
665
745
|
return;
|
|
666
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
746
|
+
const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
|
|
667
747
|
if (!(e != null && e.length))
|
|
668
748
|
return;
|
|
669
|
-
const o = r ? "1" : "0",
|
|
670
|
-
e.forEach((
|
|
671
|
-
const
|
|
672
|
-
n.modifyHtml(
|
|
673
|
-
}), n.apply(new A(
|
|
749
|
+
const o = r ? "1" : "0", i = r ? this.api.translate("visible") : this.api.translate("hidden"), s = `${this.api.translate("Set visibility")}: ${t} → ${i}`, n = this.api.getDocumentModifier();
|
|
750
|
+
e.forEach((c) => {
|
|
751
|
+
const l = _t(c), a = r ? l : "none";
|
|
752
|
+
n.modifyHtml(c).setStyle("display", a).setAttribute(D, o);
|
|
753
|
+
}), n.apply(new A(s));
|
|
674
754
|
}
|
|
675
755
|
// ========================================================================
|
|
676
756
|
// Utilities
|
|
@@ -683,7 +763,7 @@ class Ut extends Z {
|
|
|
683
763
|
_findNthCustomKeyIndex(t, r) {
|
|
684
764
|
let e = 0;
|
|
685
765
|
for (let o = 0; o < t.length; o++)
|
|
686
|
-
if (t[o].startsWith(
|
|
766
|
+
if (t[o].startsWith(p)) {
|
|
687
767
|
if (e === r)
|
|
688
768
|
return o;
|
|
689
769
|
e++;
|
|
@@ -691,7 +771,7 @@ class Ut extends Z {
|
|
|
691
771
|
return -1;
|
|
692
772
|
}
|
|
693
773
|
_getCurrentLayout() {
|
|
694
|
-
return this.store.recommendationConfigs.orientation ||
|
|
774
|
+
return this.store.recommendationConfigs.orientation || St(this.currentNode);
|
|
695
775
|
}
|
|
696
776
|
/**
|
|
697
777
|
* Extracts background color properties from existing card elements.
|
|
@@ -703,18 +783,18 @@ class Ut extends Z {
|
|
|
703
783
|
var o;
|
|
704
784
|
const r = t.querySelector(".product-card-segment");
|
|
705
785
|
if (r && "getAttribute" in r) {
|
|
706
|
-
const
|
|
707
|
-
if (
|
|
786
|
+
const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
|
|
787
|
+
if (s) {
|
|
708
788
|
const n = r.getAttribute("bgcolor") || "";
|
|
709
|
-
return { bgStyle: `background-color: ${
|
|
789
|
+
return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
|
|
710
790
|
}
|
|
711
791
|
}
|
|
712
792
|
const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
|
|
713
793
|
if (e && "getStyle" in e) {
|
|
714
|
-
const
|
|
715
|
-
if (
|
|
716
|
-
const
|
|
717
|
-
return { bgStyle: `background-color: ${
|
|
794
|
+
const i = e.getStyle("background-color");
|
|
795
|
+
if (i && i !== "transparent") {
|
|
796
|
+
const s = "getAttribute" in e && e.getAttribute("bgcolor") || "";
|
|
797
|
+
return { bgStyle: `background-color: ${i};`, bgAttr: s };
|
|
718
798
|
}
|
|
719
799
|
}
|
|
720
800
|
return { bgStyle: "", bgAttr: "" };
|
|
@@ -724,17 +804,18 @@ class Ut extends Z {
|
|
|
724
804
|
return t ? t.querySelector("[data-card-composition-control]") : null;
|
|
725
805
|
}
|
|
726
806
|
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
807
|
+
* Ensures composition reorder is enabled. Both grid and list layouts now
|
|
808
|
+
* support reordering — top-level items and the nested price sub-items are all
|
|
809
|
+
* draggable. (Items render with `draggable="true"`; this just clears any stale
|
|
810
|
+
* disabled state.)
|
|
730
811
|
*/
|
|
731
812
|
_updateOrderableState() {
|
|
732
|
-
const
|
|
733
|
-
if (!
|
|
813
|
+
const t = this._getControlContainer();
|
|
814
|
+
if (!t)
|
|
734
815
|
return;
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
816
|
+
const r = t.querySelector("[data-composition-list]");
|
|
817
|
+
r && (r.classList.remove("orderable-disabled"), r.querySelectorAll(".orderable-item").forEach((e) => {
|
|
818
|
+
e.setAttribute("draggable", "true");
|
|
738
819
|
}));
|
|
739
820
|
}
|
|
740
821
|
/**
|
|
@@ -742,11 +823,11 @@ class Ut extends Z {
|
|
|
742
823
|
* or when all available filters have already been added (no unused attributes left).
|
|
743
824
|
*/
|
|
744
825
|
_updateAddButtonState() {
|
|
745
|
-
const t = this._readCustomAttributesFromNode(), r = t.length >=
|
|
826
|
+
const t = this._readCustomAttributesFromNode(), r = t.length >= f, e = new Set(t), o = this._getAddableFilters(), i = o.length > 0 && o.every((s) => e.has(s.attributeName));
|
|
746
827
|
this.api.setUIEAttribute(
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
r ||
|
|
828
|
+
K.ADD_ATTRIBUTE,
|
|
829
|
+
E.BUTTON.disabled,
|
|
830
|
+
r || i ? "true" : "false"
|
|
750
831
|
);
|
|
751
832
|
}
|
|
752
833
|
/**
|
|
@@ -768,7 +849,7 @@ class Ut extends Z {
|
|
|
768
849
|
* excluding default attributes already covered by built-in toggle items.
|
|
769
850
|
*/
|
|
770
851
|
_getAddableFilters() {
|
|
771
|
-
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" &&
|
|
852
|
+
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && nt.has(t.attributeName)));
|
|
772
853
|
}
|
|
773
854
|
/**
|
|
774
855
|
* Looks up the display name for an attribute from the store's filterList.
|
|
@@ -776,7 +857,7 @@ class Ut extends Z {
|
|
|
776
857
|
*/
|
|
777
858
|
_getDisplayNameForAttribute(t) {
|
|
778
859
|
const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
|
|
779
|
-
return r ? r.displayName :
|
|
860
|
+
return r ? r.displayName : pt(t);
|
|
780
861
|
}
|
|
781
862
|
/**
|
|
782
863
|
* Resolves the display content for a custom attribute cell.
|
|
@@ -784,29 +865,29 @@ class Ut extends Z {
|
|
|
784
865
|
*/
|
|
785
866
|
_resolveAttributeContent(t, r, e) {
|
|
786
867
|
var n;
|
|
787
|
-
const
|
|
788
|
-
return
|
|
868
|
+
const i = this.store.recommendationProducts[e], s = gt(t, this.store.filterList) ? i == null ? void 0 : i[t] : (n = i == null ? void 0 : i.product_attributes) == null ? void 0 : n[t];
|
|
869
|
+
return bt(s) ?? r;
|
|
789
870
|
}
|
|
790
|
-
_getGridCellHtml(t, r, e, o = "",
|
|
791
|
-
const n = `${
|
|
871
|
+
_getGridCellHtml(t, r, e, o = "", i = "", s = "") {
|
|
872
|
+
const n = `${p}${t}`, c = V(ct, [n], this.store.filterList), l = {
|
|
792
873
|
[t]: r,
|
|
793
874
|
product_attributes: { [t]: r }
|
|
794
875
|
};
|
|
795
|
-
let
|
|
796
|
-
return
|
|
797
|
-
`padding: ${
|
|
798
|
-
`padding: ${
|
|
799
|
-
)), o && (
|
|
876
|
+
let a = c[n](l);
|
|
877
|
+
return a = a.replace("<td", `<td width="${e}%"`), s && (a = a.replace(
|
|
878
|
+
`padding: ${dt}`,
|
|
879
|
+
`padding: ${s}`
|
|
880
|
+
)), o && (a = a.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), i && (a = a.replace(/border="0"/, `border="0" bgcolor="${i}"`)), a;
|
|
800
881
|
}
|
|
801
882
|
_getListRowHtml(t, r, e) {
|
|
802
|
-
const o =
|
|
883
|
+
const o = V(mt, [e], this.store.filterList), i = {
|
|
803
884
|
[t]: r,
|
|
804
885
|
product_attributes: { [t]: r }
|
|
805
|
-
}, n = o[e](
|
|
806
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
886
|
+
}, n = o[e](i).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
887
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${D}="1">${n}</tr>`;
|
|
807
888
|
}
|
|
808
889
|
}
|
|
809
890
|
export {
|
|
810
|
-
|
|
811
|
-
|
|
891
|
+
Ct as COMPOSITION_CONTROL_BLOCK_ID,
|
|
892
|
+
qt as RecommendationCardCompositionControl
|
|
812
893
|
};
|