@useinsider/guido 3.8.1 → 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/useHtmlCompiler.js +13 -10
- package/dist/composables/useHtmlValidator.js +180 -133
- 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/htmlCompilerRules.js +38 -10
- package/dist/config/compiler/recommendationCompilerRules.js +84 -109
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +98 -89
- package/dist/config/compiler/utils/recommendationIgnoreUtils.js +15 -0
- package/dist/config/migrator/recommendation/extractors.js +44 -22
- package/dist/config/migrator/recommendation/htmlBuilder.js +170 -163
- package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
- package/dist/config/migrator/recommendationMigrator.js +30 -31
- 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/constants/selectors.js +26 -20
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +359 -264
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +96 -83
- package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +43 -31
- package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +55 -45
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +175 -166
- package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
- package/dist/extensions/Blocks/Recommendation/extension.js +31 -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/settingsPanel.js +3 -2
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +6 -3
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +130 -96
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +43 -53
- package/dist/extensions/Blocks/Recommendation/templates/index.js +20 -16
- 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/useHtmlValidator.d.ts +27 -0
- package/dist/src/composables/useHtmlValidator.test.d.ts +1 -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/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
- package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +15 -0
- package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +8 -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/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +21 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +36 -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/layoutOrientation.d.ts +5 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -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/src/utils/ampErrorFilter.d.ts +1 -0
- package/dist/stores/unsubscribe.js +8 -7
- package/dist/utils/ampErrorFilter.js +6 -5
- 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 { getCurrentLayout 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
24
|
{ key: U, label: "Product Button" }
|
|
25
|
-
],
|
|
26
|
-
class
|
|
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
|
})}
|
|
@@ -128,10 +128,24 @@ class Ut extends Z {
|
|
|
128
128
|
`;
|
|
129
129
|
}
|
|
130
130
|
onRender() {
|
|
131
|
-
this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges();
|
|
131
|
+
this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges(), this._syncDisabledState();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Card composition restructures the block (toggles/reorders/adds attribute
|
|
135
|
+
* cells), which would corrupt a partner-managed (`ins-skip-compile`) block's
|
|
136
|
+
* preserved markup. There is no native tab-disable API, so the whole control
|
|
137
|
+
* container is rendered inert (greyed + non-interactive) instead.
|
|
138
|
+
*/
|
|
139
|
+
_syncDisabledState() {
|
|
140
|
+
var e;
|
|
141
|
+
const t = (e = this.getContainer()) == null ? void 0 : e.querySelector("[data-card-composition-control]");
|
|
142
|
+
if (!t)
|
|
143
|
+
return;
|
|
144
|
+
const r = ft(this.currentNode);
|
|
145
|
+
t.style.pointerEvents = r ? "none" : "", t.style.opacity = r ? "0.5" : "";
|
|
132
146
|
}
|
|
133
147
|
onTemplateNodeUpdated(t) {
|
|
134
|
-
super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState());
|
|
148
|
+
super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState(), this._syncDisabledState());
|
|
135
149
|
}
|
|
136
150
|
onDestroy() {
|
|
137
151
|
super.onDestroy(), this.eventController && (this.eventController.abort(), this.eventController = null), this.unsubscribeStore && (this.unsubscribeStore(), this.unsubscribeStore = null);
|
|
@@ -140,17 +154,17 @@ class Ut extends Z {
|
|
|
140
154
|
// Initialization
|
|
141
155
|
// ========================================================================
|
|
142
156
|
_initializeComposition() {
|
|
143
|
-
const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), o = this._renderOrderableItems(t, r),
|
|
144
|
-
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();
|
|
145
159
|
}
|
|
146
160
|
_registerValueChangeListeners() {
|
|
147
|
-
|
|
161
|
+
m.forEach((t) => {
|
|
148
162
|
this.api.onValueChanged(`visibility_${t.key}`, (r) => {
|
|
149
163
|
this._applyVisibilityToBlock(t.key, r);
|
|
150
164
|
});
|
|
151
165
|
});
|
|
152
|
-
for (let t = 0; t <
|
|
153
|
-
const r = `${
|
|
166
|
+
for (let t = 0; t < f; t++) {
|
|
167
|
+
const r = `${$}${t}`, e = t;
|
|
154
168
|
this.api.onValueChanged(r, (o) => {
|
|
155
169
|
this._onCustomAttributeChanged(e, o);
|
|
156
170
|
});
|
|
@@ -161,14 +175,14 @@ class Ut extends Z {
|
|
|
161
175
|
// ========================================================================
|
|
162
176
|
_readCompositionFromNode() {
|
|
163
177
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
164
|
-
return [...
|
|
165
|
-
const t = this.currentNode.getAttribute(
|
|
166
|
-
return t ? t.split(",").filter(Boolean) : [...
|
|
178
|
+
return [...x];
|
|
179
|
+
const t = this.currentNode.getAttribute(W);
|
|
180
|
+
return t ? t.split(",").filter(Boolean) : [...x];
|
|
167
181
|
}
|
|
168
182
|
_readCustomAttributesFromNode() {
|
|
169
183
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
170
184
|
return [];
|
|
171
|
-
const t = this.currentNode.getAttribute(
|
|
185
|
+
const t = this.currentNode.getAttribute(F);
|
|
172
186
|
if (!t)
|
|
173
187
|
return [];
|
|
174
188
|
try {
|
|
@@ -180,31 +194,31 @@ class Ut extends Z {
|
|
|
180
194
|
_readVisibilityFromRows() {
|
|
181
195
|
if (!this.currentNode)
|
|
182
196
|
return this._getDefaultVisibilities();
|
|
183
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
197
|
+
const t = Array.from(this.currentNode.querySelectorAll(T)), r = this._extractVisibilityFromRows(t);
|
|
184
198
|
return this._mergeWithDefaults(r);
|
|
185
199
|
}
|
|
186
200
|
_getDefaultVisibilities() {
|
|
187
|
-
return { ...
|
|
201
|
+
return { ...M };
|
|
188
202
|
}
|
|
189
203
|
_extractVisibilityFromRows(t) {
|
|
190
204
|
const r = {};
|
|
191
205
|
return t.forEach((e) => {
|
|
192
206
|
if (!("getAttribute" in e))
|
|
193
207
|
return;
|
|
194
|
-
const o = e.getAttribute(y),
|
|
195
|
-
o &&
|
|
208
|
+
const o = e.getAttribute(y), i = e.getAttribute(D);
|
|
209
|
+
o && i !== null && (r[o] = this._parseVisibilityValue(i));
|
|
196
210
|
}), r;
|
|
197
211
|
}
|
|
198
212
|
_parseVisibilityValue(t) {
|
|
199
213
|
return t === "1" || t === "true";
|
|
200
214
|
}
|
|
201
215
|
_mergeWithDefaults(t) {
|
|
202
|
-
return Object.entries(
|
|
216
|
+
return Object.entries(M).forEach(([r, e]) => {
|
|
203
217
|
r in t || (t[r] = e);
|
|
204
218
|
}), t;
|
|
205
219
|
}
|
|
206
220
|
_buildVisibilityValues(t) {
|
|
207
|
-
return
|
|
221
|
+
return m.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
|
|
208
222
|
}
|
|
209
223
|
// ========================================================================
|
|
210
224
|
// UI Rendering (Orderable List)
|
|
@@ -219,23 +233,29 @@ class Ut extends Z {
|
|
|
219
233
|
if (!e)
|
|
220
234
|
return !1;
|
|
221
235
|
const o = e.querySelector("[data-composition-list]");
|
|
222
|
-
if (!o
|
|
236
|
+
if (!o)
|
|
237
|
+
return !1;
|
|
238
|
+
const i = !P.getConfig(this.currentNode).priceMovedToNextLine;
|
|
239
|
+
if (!(o.dataset.inlinePrices !== String(i)) && this._tryReorderInPlace(o, t))
|
|
223
240
|
return !1;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
return this.
|
|
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++);
|
|
230
250
|
}
|
|
231
|
-
if (
|
|
232
|
-
const
|
|
233
|
-
if (
|
|
234
|
-
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++);
|
|
235
255
|
}
|
|
236
256
|
return "";
|
|
237
257
|
}).join("");
|
|
238
|
-
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;
|
|
239
259
|
}
|
|
240
260
|
/**
|
|
241
261
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -247,27 +267,27 @@ class Ut extends Z {
|
|
|
247
267
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
248
268
|
if (e.length !== r.length)
|
|
249
269
|
return !1;
|
|
250
|
-
const o = e.map((
|
|
270
|
+
const o = e.map((l) => l.dataset.key).filter(Boolean);
|
|
251
271
|
if (o.length !== r.length)
|
|
252
272
|
return !1;
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
273
|
+
const i = [...o].sort().join(","), s = [...r].sort().join(",");
|
|
274
|
+
if (i !== s || r.some((l) => l.startsWith(p)))
|
|
255
275
|
return !1;
|
|
256
276
|
const n = /* @__PURE__ */ new Map();
|
|
257
|
-
e.forEach((
|
|
258
|
-
const { key:
|
|
259
|
-
if (
|
|
260
|
-
const
|
|
261
|
-
|
|
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);
|
|
262
282
|
}
|
|
263
283
|
});
|
|
264
|
-
const
|
|
265
|
-
return r.forEach((
|
|
266
|
-
const
|
|
267
|
-
if (!
|
|
284
|
+
const c = /* @__PURE__ */ new Map();
|
|
285
|
+
return r.forEach((l) => {
|
|
286
|
+
const a = n.get(l);
|
|
287
|
+
if (!a)
|
|
268
288
|
return;
|
|
269
|
-
const
|
|
270
|
-
|
|
289
|
+
const d = c.get(l) || 0;
|
|
290
|
+
c.set(l, d + 1), a[d] && t.appendChild(a[d]);
|
|
271
291
|
}), !0;
|
|
272
292
|
}
|
|
273
293
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -279,6 +299,33 @@ class Ut extends Z {
|
|
|
279
299
|
</div>
|
|
280
300
|
`;
|
|
281
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
|
+
}
|
|
282
329
|
_createCustomItemHtml(t, r, e) {
|
|
283
330
|
return `
|
|
284
331
|
<div class="orderable-item" draggable="true"
|
|
@@ -299,10 +346,10 @@ class Ut extends Z {
|
|
|
299
346
|
_getSelectOptions(t, r = []) {
|
|
300
347
|
const e = this._getAddableFilters();
|
|
301
348
|
if (e.length > 0) {
|
|
302
|
-
const
|
|
303
|
-
return
|
|
304
|
-
text:
|
|
305
|
-
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
|
|
306
353
|
}));
|
|
307
354
|
}
|
|
308
355
|
return [{ text: this._getDisplayNameForAttribute(t), value: t }];
|
|
@@ -315,8 +362,8 @@ class Ut extends Z {
|
|
|
315
362
|
_initializeCustomSelects(t) {
|
|
316
363
|
t.length !== 0 && setTimeout(() => {
|
|
317
364
|
t.forEach((r, e) => {
|
|
318
|
-
const o = `${
|
|
319
|
-
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 });
|
|
320
367
|
});
|
|
321
368
|
}, 0);
|
|
322
369
|
}
|
|
@@ -325,11 +372,11 @@ class Ut extends Z {
|
|
|
325
372
|
* Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
|
|
326
373
|
*/
|
|
327
374
|
_moveTogglesIntoItems(t) {
|
|
328
|
-
|
|
375
|
+
m.forEach((r) => {
|
|
329
376
|
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
330
377
|
if (e && o) {
|
|
331
|
-
const
|
|
332
|
-
|
|
378
|
+
const i = e.querySelector("ue-switcher");
|
|
379
|
+
i && o.appendChild(i);
|
|
333
380
|
}
|
|
334
381
|
});
|
|
335
382
|
}
|
|
@@ -339,10 +386,10 @@ class Ut extends Z {
|
|
|
339
386
|
*/
|
|
340
387
|
_moveSelectsIntoItems(t, r) {
|
|
341
388
|
for (let e = 0; e < r; e++) {
|
|
342
|
-
const o = `${
|
|
343
|
-
if (
|
|
344
|
-
const n =
|
|
345
|
-
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);
|
|
346
393
|
}
|
|
347
394
|
}
|
|
348
395
|
}
|
|
@@ -353,11 +400,11 @@ class Ut extends Z {
|
|
|
353
400
|
* previously-moved toggles, making them permanently lost.
|
|
354
401
|
*/
|
|
355
402
|
_rescueTogglesToStore(t) {
|
|
356
|
-
|
|
403
|
+
m.forEach((r) => {
|
|
357
404
|
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
358
405
|
if (o) {
|
|
359
|
-
const
|
|
360
|
-
|
|
406
|
+
const i = o.querySelector("ue-switcher");
|
|
407
|
+
i && e && e.appendChild(i);
|
|
361
408
|
}
|
|
362
409
|
});
|
|
363
410
|
}
|
|
@@ -366,11 +413,11 @@ class Ut extends Z {
|
|
|
366
413
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
367
414
|
*/
|
|
368
415
|
_rescueSelectsToStore(t) {
|
|
369
|
-
for (let r = 0; r <
|
|
370
|
-
const e = `${
|
|
371
|
-
if (
|
|
372
|
-
const
|
|
373
|
-
|
|
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);
|
|
374
421
|
}
|
|
375
422
|
}
|
|
376
423
|
}
|
|
@@ -380,10 +427,10 @@ class Ut extends Z {
|
|
|
380
427
|
*/
|
|
381
428
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
382
429
|
for (let e = 0; e < r; e++) {
|
|
383
|
-
const o = `${
|
|
384
|
-
if (
|
|
385
|
-
const n =
|
|
386
|
-
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);
|
|
387
434
|
}
|
|
388
435
|
}
|
|
389
436
|
}
|
|
@@ -392,11 +439,11 @@ class Ut extends Z {
|
|
|
392
439
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
393
440
|
*/
|
|
394
441
|
_rescueDeleteButtonsToStore(t) {
|
|
395
|
-
for (let r = 0; r <
|
|
396
|
-
const e = `${
|
|
397
|
-
if (
|
|
398
|
-
const
|
|
399
|
-
|
|
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);
|
|
400
447
|
}
|
|
401
448
|
}
|
|
402
449
|
}
|
|
@@ -406,10 +453,10 @@ class Ut extends Z {
|
|
|
406
453
|
*/
|
|
407
454
|
_moveReorderIconsIntoItems(t, r) {
|
|
408
455
|
for (let e = 0; e < r; e++) {
|
|
409
|
-
const o = `${
|
|
410
|
-
if (
|
|
411
|
-
const n =
|
|
412
|
-
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);
|
|
413
460
|
}
|
|
414
461
|
}
|
|
415
462
|
}
|
|
@@ -418,12 +465,12 @@ class Ut extends Z {
|
|
|
418
465
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
419
466
|
*/
|
|
420
467
|
_rescueReorderIconsToStore(t) {
|
|
421
|
-
const r =
|
|
468
|
+
const r = m.length + f;
|
|
422
469
|
for (let e = 0; e < r; e++) {
|
|
423
|
-
const o = `${
|
|
424
|
-
if (
|
|
425
|
-
const n =
|
|
426
|
-
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);
|
|
427
474
|
}
|
|
428
475
|
}
|
|
429
476
|
}
|
|
@@ -437,39 +484,81 @@ class Ut extends Z {
|
|
|
437
484
|
return;
|
|
438
485
|
const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
|
|
439
486
|
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
|
|
440
|
-
const
|
|
441
|
-
|
|
487
|
+
const i = new Set(this._readCustomAttributesFromNode()), s = this._getAddableFilters().find((n) => !i.has(n.attributeName));
|
|
488
|
+
s && this._onAddAttribute(s.attributeName, s.displayName);
|
|
442
489
|
}, { signal: t });
|
|
443
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
|
+
}
|
|
444
506
|
_setupDragAndDrop(t, r) {
|
|
445
|
-
|
|
446
|
-
|
|
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) => {
|
|
447
529
|
var a;
|
|
448
|
-
const
|
|
449
|
-
|
|
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 ?? ""));
|
|
450
535
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
451
|
-
|
|
452
|
-
}, { signal: r }), t.addEventListener("dragover", (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
s.preventDefault();
|
|
458
|
-
const n = s.target.closest(".orderable-item");
|
|
459
|
-
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)
|
|
539
|
+
return;
|
|
540
|
+
const c = s(n);
|
|
541
|
+
if (!c)
|
|
460
542
|
return;
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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));
|
|
465
554
|
}, { signal: r });
|
|
466
555
|
}
|
|
467
556
|
_setupDeleteHandler(t, r) {
|
|
468
557
|
t.addEventListener("click", (e) => {
|
|
469
|
-
const
|
|
470
|
-
if (!
|
|
558
|
+
const i = e.target.closest(".custom-attr-delete");
|
|
559
|
+
if (!i)
|
|
471
560
|
return;
|
|
472
|
-
const
|
|
561
|
+
const s = i.closest("[data-custom-index]"), n = s == null ? void 0 : s.dataset.customIndex;
|
|
473
562
|
n !== void 0 && this._onDeleteCustomAttribute(Number(n));
|
|
474
563
|
}, { signal: r });
|
|
475
564
|
}
|
|
@@ -477,10 +566,10 @@ class Ut extends Z {
|
|
|
477
566
|
// Actions (Add, Delete, Reorder)
|
|
478
567
|
// ========================================================================
|
|
479
568
|
_onAddAttribute(t, r) {
|
|
480
|
-
const e = `${
|
|
569
|
+
const e = `${p}${t}`, o = this._readCompositionFromNode();
|
|
481
570
|
o.push(e);
|
|
482
|
-
const
|
|
483
|
-
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();
|
|
484
573
|
}
|
|
485
574
|
/**
|
|
486
575
|
* Removes a single custom attribute by its index in the customAttrs array.
|
|
@@ -490,8 +579,8 @@ class Ut extends Z {
|
|
|
490
579
|
const r = this._readCustomAttributesFromNode();
|
|
491
580
|
if (r[t] === void 0)
|
|
492
581
|
return;
|
|
493
|
-
const o = this._readCompositionFromNode(),
|
|
494
|
-
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();
|
|
495
584
|
}
|
|
496
585
|
/**
|
|
497
586
|
* Handles changing a custom attribute's selection via its inline _GuSelect.
|
|
@@ -501,16 +590,21 @@ class Ut extends Z {
|
|
|
501
590
|
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
502
591
|
if (o === void 0 || o === r)
|
|
503
592
|
return;
|
|
504
|
-
const
|
|
505
|
-
n !== -1 && (
|
|
506
|
-
const
|
|
507
|
-
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);
|
|
508
597
|
}
|
|
509
598
|
_onReorder(t) {
|
|
510
|
-
const r = t.filter((e) => e.startsWith(
|
|
599
|
+
const r = t.filter((e) => e.startsWith(p)).map((e) => e.substring(p.length));
|
|
511
600
|
this.reorderInProgress = !0;
|
|
512
601
|
try {
|
|
513
|
-
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
|
+
});
|
|
514
608
|
} finally {
|
|
515
609
|
this.reorderInProgress = !1;
|
|
516
610
|
}
|
|
@@ -525,60 +619,60 @@ class Ut extends Z {
|
|
|
525
619
|
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
|
|
526
620
|
}
|
|
527
621
|
_injectGridAttributeRow(t, r, e, o) {
|
|
528
|
-
const
|
|
529
|
-
if (!(
|
|
622
|
+
const i = this.currentNode.querySelectorAll(H);
|
|
623
|
+
if (!(i != null && i.length))
|
|
530
624
|
return;
|
|
531
|
-
const
|
|
532
|
-
let
|
|
533
|
-
|
|
534
|
-
var
|
|
535
|
-
const
|
|
536
|
-
if (
|
|
537
|
-
const
|
|
538
|
-
{ length:
|
|
539
|
-
(
|
|
540
|
-
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(
|
|
541
635
|
t,
|
|
542
636
|
r,
|
|
543
|
-
|
|
637
|
+
d + Q
|
|
544
638
|
);
|
|
545
639
|
return this._getGridCellHtml(
|
|
546
640
|
t,
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
641
|
+
Z,
|
|
642
|
+
q,
|
|
643
|
+
G,
|
|
644
|
+
z,
|
|
645
|
+
c
|
|
552
646
|
);
|
|
553
647
|
}
|
|
554
|
-
).join(""),
|
|
555
|
-
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>`;
|
|
556
650
|
}
|
|
557
|
-
const
|
|
558
|
-
`${
|
|
651
|
+
const L = u.querySelector(
|
|
652
|
+
`${T}[${y}="${w}"]`
|
|
559
653
|
);
|
|
560
|
-
return
|
|
654
|
+
return L && "getOuterHTML" in L ? L.getOuterHTML() : "";
|
|
561
655
|
}).join("");
|
|
562
|
-
|
|
563
|
-
}),
|
|
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}`));
|
|
564
658
|
}
|
|
565
659
|
_injectListAttributeRow(t, r, e, o) {
|
|
566
|
-
const
|
|
567
|
-
if (!(
|
|
660
|
+
const i = this.currentNode.querySelectorAll(j);
|
|
661
|
+
if (!(i != null && i.length))
|
|
568
662
|
return;
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
const
|
|
572
|
-
if (
|
|
573
|
-
const
|
|
574
|
-
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);
|
|
575
669
|
}
|
|
576
|
-
const
|
|
577
|
-
`${
|
|
670
|
+
const u = c.querySelector(
|
|
671
|
+
`${T}[${y}="${d}"]`
|
|
578
672
|
);
|
|
579
|
-
return
|
|
673
|
+
return u && "getOuterHTML" in u ? u.getOuterHTML() : "";
|
|
580
674
|
}).join("");
|
|
581
|
-
n.modifyHtml(
|
|
675
|
+
n.modifyHtml(c).setInnerHtml(a);
|
|
582
676
|
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
583
677
|
}
|
|
584
678
|
/**
|
|
@@ -590,16 +684,16 @@ class Ut extends Z {
|
|
|
590
684
|
return;
|
|
591
685
|
const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
|
|
592
686
|
if (r === "grid") {
|
|
593
|
-
const o = this.currentNode.querySelectorAll(
|
|
594
|
-
o == null || o.forEach((
|
|
595
|
-
const
|
|
596
|
-
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);
|
|
597
691
|
});
|
|
598
692
|
} else {
|
|
599
|
-
const o = t.filter((
|
|
600
|
-
|
|
601
|
-
const n = this._buildCompositionHtml(
|
|
602
|
-
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);
|
|
603
697
|
});
|
|
604
698
|
}
|
|
605
699
|
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
@@ -615,7 +709,7 @@ class Ut extends Z {
|
|
|
615
709
|
* producing a flicker on the custom attribute dropdowns.
|
|
616
710
|
*/
|
|
617
711
|
_updateBothAttributes(t, r) {
|
|
618
|
-
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")));
|
|
619
713
|
}
|
|
620
714
|
/**
|
|
621
715
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -624,13 +718,13 @@ class Ut extends Z {
|
|
|
624
718
|
_reorderProductAttributes(t) {
|
|
625
719
|
if (!this.currentNode)
|
|
626
720
|
return;
|
|
627
|
-
const r = this.currentNode.querySelectorAll(
|
|
721
|
+
const r = this.currentNode.querySelectorAll(H);
|
|
628
722
|
if (!(r != null && r.length))
|
|
629
723
|
return;
|
|
630
724
|
const e = this.api.getDocumentModifier();
|
|
631
725
|
r.forEach((o) => {
|
|
632
|
-
const
|
|
633
|
-
e.modifyHtml(o).setInnerHtml(
|
|
726
|
+
const i = this._buildCompositionHtml(o, t);
|
|
727
|
+
e.modifyHtml(o).setInnerHtml(i);
|
|
634
728
|
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
635
729
|
}
|
|
636
730
|
/**
|
|
@@ -639,8 +733,8 @@ class Ut extends Z {
|
|
|
639
733
|
*/
|
|
640
734
|
_buildCompositionHtml(t, r) {
|
|
641
735
|
return r.reduce((e, o) => {
|
|
642
|
-
const
|
|
643
|
-
return
|
|
736
|
+
const i = t.querySelector(`${T}[${y}="${o}"]`);
|
|
737
|
+
return i && "getOuterHTML" in i ? e + i.getOuterHTML() : e;
|
|
644
738
|
}, "");
|
|
645
739
|
}
|
|
646
740
|
// ========================================================================
|
|
@@ -649,14 +743,14 @@ class Ut extends Z {
|
|
|
649
743
|
_applyVisibilityToBlock(t, r) {
|
|
650
744
|
if (!this.currentNode)
|
|
651
745
|
return;
|
|
652
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
746
|
+
const e = this.currentNode.querySelectorAll(`${T}[${y}="${t}"]`);
|
|
653
747
|
if (!(e != null && e.length))
|
|
654
748
|
return;
|
|
655
|
-
const o = r ? "1" : "0",
|
|
656
|
-
e.forEach((
|
|
657
|
-
const
|
|
658
|
-
n.modifyHtml(
|
|
659
|
-
}), 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));
|
|
660
754
|
}
|
|
661
755
|
// ========================================================================
|
|
662
756
|
// Utilities
|
|
@@ -669,7 +763,7 @@ class Ut extends Z {
|
|
|
669
763
|
_findNthCustomKeyIndex(t, r) {
|
|
670
764
|
let e = 0;
|
|
671
765
|
for (let o = 0; o < t.length; o++)
|
|
672
|
-
if (t[o].startsWith(
|
|
766
|
+
if (t[o].startsWith(p)) {
|
|
673
767
|
if (e === r)
|
|
674
768
|
return o;
|
|
675
769
|
e++;
|
|
@@ -677,7 +771,7 @@ class Ut extends Z {
|
|
|
677
771
|
return -1;
|
|
678
772
|
}
|
|
679
773
|
_getCurrentLayout() {
|
|
680
|
-
return this.store.recommendationConfigs.orientation ||
|
|
774
|
+
return this.store.recommendationConfigs.orientation || St(this.currentNode);
|
|
681
775
|
}
|
|
682
776
|
/**
|
|
683
777
|
* Extracts background color properties from existing card elements.
|
|
@@ -689,18 +783,18 @@ class Ut extends Z {
|
|
|
689
783
|
var o;
|
|
690
784
|
const r = t.querySelector(".product-card-segment");
|
|
691
785
|
if (r && "getAttribute" in r) {
|
|
692
|
-
const
|
|
693
|
-
if (
|
|
786
|
+
const s = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
|
|
787
|
+
if (s) {
|
|
694
788
|
const n = r.getAttribute("bgcolor") || "";
|
|
695
|
-
return { bgStyle: `background-color: ${
|
|
789
|
+
return { bgStyle: `background-color: ${s[1].trim()};`, bgAttr: n };
|
|
696
790
|
}
|
|
697
791
|
}
|
|
698
792
|
const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
|
|
699
793
|
if (e && "getStyle" in e) {
|
|
700
|
-
const
|
|
701
|
-
if (
|
|
702
|
-
const
|
|
703
|
-
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 };
|
|
704
798
|
}
|
|
705
799
|
}
|
|
706
800
|
return { bgStyle: "", bgAttr: "" };
|
|
@@ -710,17 +804,18 @@ class Ut extends Z {
|
|
|
710
804
|
return t ? t.querySelector("[data-card-composition-control]") : null;
|
|
711
805
|
}
|
|
712
806
|
/**
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
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.)
|
|
716
811
|
*/
|
|
717
812
|
_updateOrderableState() {
|
|
718
|
-
const
|
|
719
|
-
if (!
|
|
813
|
+
const t = this._getControlContainer();
|
|
814
|
+
if (!t)
|
|
720
815
|
return;
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
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");
|
|
724
819
|
}));
|
|
725
820
|
}
|
|
726
821
|
/**
|
|
@@ -728,11 +823,11 @@ class Ut extends Z {
|
|
|
728
823
|
* or when all available filters have already been added (no unused attributes left).
|
|
729
824
|
*/
|
|
730
825
|
_updateAddButtonState() {
|
|
731
|
-
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));
|
|
732
827
|
this.api.setUIEAttribute(
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
r ||
|
|
828
|
+
K.ADD_ATTRIBUTE,
|
|
829
|
+
E.BUTTON.disabled,
|
|
830
|
+
r || i ? "true" : "false"
|
|
736
831
|
);
|
|
737
832
|
}
|
|
738
833
|
/**
|
|
@@ -754,7 +849,7 @@ class Ut extends Z {
|
|
|
754
849
|
* excluding default attributes already covered by built-in toggle items.
|
|
755
850
|
*/
|
|
756
851
|
_getAddableFilters() {
|
|
757
|
-
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)));
|
|
758
853
|
}
|
|
759
854
|
/**
|
|
760
855
|
* Looks up the display name for an attribute from the store's filterList.
|
|
@@ -762,7 +857,7 @@ class Ut extends Z {
|
|
|
762
857
|
*/
|
|
763
858
|
_getDisplayNameForAttribute(t) {
|
|
764
859
|
const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
|
|
765
|
-
return r ? r.displayName :
|
|
860
|
+
return r ? r.displayName : pt(t);
|
|
766
861
|
}
|
|
767
862
|
/**
|
|
768
863
|
* Resolves the display content for a custom attribute cell.
|
|
@@ -770,29 +865,29 @@ class Ut extends Z {
|
|
|
770
865
|
*/
|
|
771
866
|
_resolveAttributeContent(t, r, e) {
|
|
772
867
|
var n;
|
|
773
|
-
const
|
|
774
|
-
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;
|
|
775
870
|
}
|
|
776
|
-
_getGridCellHtml(t, r, e, o = "",
|
|
777
|
-
const n = `${
|
|
871
|
+
_getGridCellHtml(t, r, e, o = "", i = "", s = "") {
|
|
872
|
+
const n = `${p}${t}`, c = V(ct, [n], this.store.filterList), l = {
|
|
778
873
|
[t]: r,
|
|
779
874
|
product_attributes: { [t]: r }
|
|
780
875
|
};
|
|
781
|
-
let
|
|
782
|
-
return
|
|
783
|
-
`padding: ${
|
|
784
|
-
`padding: ${
|
|
785
|
-
)), 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;
|
|
786
881
|
}
|
|
787
882
|
_getListRowHtml(t, r, e) {
|
|
788
|
-
const o =
|
|
883
|
+
const o = V(mt, [e], this.store.filterList), i = {
|
|
789
884
|
[t]: r,
|
|
790
885
|
product_attributes: { [t]: r }
|
|
791
|
-
}, n = o[e](
|
|
792
|
-
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>`;
|
|
793
888
|
}
|
|
794
889
|
}
|
|
795
890
|
export {
|
|
796
|
-
|
|
797
|
-
|
|
891
|
+
Ct as COMPOSITION_CONTROL_BLOCK_ID,
|
|
892
|
+
qt as RecommendationCardCompositionControl
|
|
798
893
|
};
|