@useinsider/guido 2.1.0-beta.f30d59a → 2.1.0-beta.f8696fd
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/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +15 -14
- package/dist/components/organisms/header/EditorActions.vue.js +12 -10
- package/dist/components/organisms/header/EditorActions.vue2.js +41 -31
- package/dist/components/organisms/header/MigrationConfirmModal.vue.js +21 -0
- package/dist/components/organisms/header/MigrationConfirmModal.vue2.js +38 -0
- package/dist/composables/useHtmlValidator.js +114 -104
- package/dist/composables/useRecommendation.js +54 -21
- package/dist/composables/useStripo.js +25 -23
- package/dist/composables/useVersionHistoryApi.js +1 -1
- package/dist/config/compiler/recommendationCompilerRules.js +45 -39
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +121 -0
- package/dist/config/i18n/en/index.js +11 -0
- package/dist/config/i18n/en/labels.json.js +12 -0
- package/dist/config/i18n/en/toasters.json.js +56 -0
- package/dist/config/i18n/en/tooltips.json.js +82 -0
- package/dist/config/i18n/index.js +7 -0
- package/dist/config/migrator/itemsBlockMigrator.js +128 -121
- package/dist/config/migrator/recommendationMigrator.js +42 -40
- package/dist/enums/extensions/recommendationBlock.js +1 -1
- package/dist/enums/recommendation.js +16 -15
- package/dist/extensions/Blocks/Items/block.js +45 -25
- package/dist/extensions/Blocks/Items/iconsRegistry.js +40 -5
- package/dist/extensions/Blocks/Items/items.css.js +48 -0
- package/dist/extensions/Blocks/Recommendation/block.js +153 -9
- package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +4 -0
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +4 -0
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +66 -0
- package/dist/extensions/Blocks/Recommendation/constants/layout.js +22 -0
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +21 -0
- package/dist/extensions/Blocks/Recommendation/controls/button/index.js +64 -0
- package/dist/extensions/Blocks/Recommendation/controls/cardBackground/index.js +80 -0
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +232 -0
- package/dist/extensions/Blocks/Recommendation/controls/image/index.js +19 -0
- package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +92 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +102 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +209 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/filters.js +52 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +250 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +70 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +160 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +67 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +307 -0
- package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +21 -0
- package/dist/extensions/Blocks/Recommendation/controls/name/index.js +46 -0
- package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +108 -0
- package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +44 -0
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +48 -0
- package/dist/extensions/Blocks/Recommendation/controls/{omnibusDiscountTextAfterControl.js → omnibusDiscount/textAfter.js} +16 -14
- package/dist/extensions/Blocks/Recommendation/controls/{omnibusDiscountTextBeforeControl.js → omnibusDiscount/textBefore.js} +16 -14
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +48 -0
- package/dist/extensions/Blocks/Recommendation/controls/{omnibusPriceTextAfterControl.js → omnibusPrice/textAfter.js} +16 -14
- package/dist/extensions/Blocks/Recommendation/controls/{omnibusPriceTextBeforeControl.js → omnibusPrice/textBefore.js} +14 -12
- package/dist/extensions/Blocks/Recommendation/controls/price/index.js +44 -0
- package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +222 -0
- package/dist/extensions/Blocks/Recommendation/extension.js +40 -17
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +54 -3
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +61 -4
- package/dist/extensions/Blocks/Recommendation/services/configService.js +240 -0
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +21 -10
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +254 -207
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +228 -0
- package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +251 -0
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +66 -0
- package/dist/extensions/Blocks/Recommendation/templates/index.js +12 -0
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +169 -0
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +73 -0
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +134 -0
- package/dist/extensions/Blocks/Recommendation/types/nodeConfig.js +6 -0
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +9 -9
- package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +26 -15
- package/dist/extensions/Blocks/Recommendation/utils/priceFormatter.js +29 -0
- package/dist/extensions/Blocks/Recommendation/utils/tagName.js +46 -0
- package/dist/extensions/Blocks/common-control.js +12 -4
- package/dist/extensions/Blocks/controlFactories.js +125 -93
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +242 -186
- package/dist/services/recommendationApi.js +11 -8
- package/dist/services/stripoApi.js +20 -17
- package/dist/services/templateLibraryApi.js +16 -13
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/MigrationConfirmModal.vue.d.ts +5 -0
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
- package/dist/src/components/wrappers/WpDrawer.vue.d.ts +1 -1
- package/dist/src/components/wrappers/WpModal.vue.d.ts +2 -2
- package/dist/src/composables/useRecommendation.d.ts +1 -0
- package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +17 -0
- package/dist/src/config/i18n/en/index.d.ts +1 -0
- package/dist/src/config/i18n/index.d.ts +16 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +68 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/{constants.d.ts → constants/controlIds.d.ts} +0 -24
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +49 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +41 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +35 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +143 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardBackground/index.d.ts +31 -0
- package/dist/src/extensions/Blocks/Recommendation/{cardCompositionControl.d.ts → controls/cardComposition/index.d.ts} +23 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +35 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +21 -589
- package/dist/src/extensions/Blocks/Recommendation/controls/layout/index.d.ts +37 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/algorithm.d.ts +29 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/currency.d.ts +52 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/filters.d.ts +22 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +79 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/locale.d.ts +24 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +60 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/shuffle.d.ts +23 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +221 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.d.ts +29 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +97 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +34 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +95 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +100 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.d.ts +15 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.d.ts +15 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +100 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.d.ts +15 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.d.ts +15 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +95 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +83 -0
- package/dist/src/extensions/Blocks/Recommendation/extension.d.ts +9 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +151 -0
- package/dist/src/extensions/Blocks/Recommendation/services/index.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +138 -468
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +20 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/{migrationTemplate.d.ts → grid/migration.d.ts} +11 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +33 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +41 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +8 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/list/migration.d.ts +25 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +18 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +66 -0
- package/dist/src/extensions/Blocks/Recommendation/types/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +166 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/priceFormatter.d.ts +33 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/stylePreserver.d.ts +113 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/tagName.d.ts +77 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +5 -0
- package/dist/src/stores/template.d.ts +3 -0
- package/dist/static/styles/components/notification.css.js +18 -0
- package/dist/static/styles/components/tools.css.js +6 -2
- package/dist/static/styles/customEditorStyle.css.js +35 -11
- package/dist/static/styles/variables.css.js +2 -0
- package/dist/static/templates/empty/index.html.js +74 -0
- package/dist/static/templates/empty/style.css.js +779 -0
- package/dist/stores/template.js +9 -0
- package/dist/utils/pairProductVariables.js +57 -56
- package/dist/utils/templatePreparation.js +15 -14
- package/package.json +1 -1
- package/dist/extensions/Blocks/Recommendation/cardCompositionControl.js +0 -187
- package/dist/extensions/Blocks/Recommendation/constants.js +0 -13
- package/dist/extensions/Blocks/Recommendation/control.js +0 -336
- package/dist/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.js +0 -68
- package/dist/extensions/Blocks/Recommendation/controls/index.js +0 -245
- package/dist/extensions/Blocks/Recommendation/controls/nameTextTrimControl.js +0 -74
- package/dist/extensions/Blocks/Recommendation/controls/spacingControl.js +0 -188
- package/dist/extensions/Blocks/Recommendation/templates/blockTemplate.js +0 -181
- package/dist/extensions/Blocks/Recommendation/templates/migrationTemplate.js +0 -189
- package/dist/extensions/Blocks/Recommendation/templates/templateUtils.js +0 -209
- package/dist/src/extensions/Blocks/Recommendation/control.d.ts +0 -38
- package/dist/src/extensions/Blocks/Recommendation/controls/nameTextTrimControl.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/templates/blockTemplate.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/templates/templateUtils.d.ts +0 -52
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
var G = Object.defineProperty;
|
|
2
|
+
var I = (o, n, t) => n in o ? G(o, n, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[n] = t;
|
|
3
|
+
var l = (o, n, t) => I(o, typeof n != "symbol" ? n + "" : n, t);
|
|
4
|
+
import { ModificationDescription as g } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as L } from "../../../common-control.js";
|
|
6
|
+
import { SPACING_STEP as b, MAX_SPACING as y, MIN_SPACING as A, DEFAULT_COLUMN_SPACING as a, DEFAULT_ROW_SPACING as m } from "../../constants/layout.js";
|
|
7
|
+
import { RecommendationConfigService as d } from "../../services/configService.js";
|
|
8
|
+
import { useRecommendationExtensionStore as w } from "../../store/recommendation.js";
|
|
9
|
+
import { safeGetStyle as S, safeGetParent as V } from "../../utils/tagName.js";
|
|
10
|
+
import { getCurrentLayout as C } from "../main/utils.js";
|
|
11
|
+
import { useDebounceFn as O } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
12
|
+
const R = "recommendation-spacing-control", s = {
|
|
13
|
+
COLUMN_SPACING: "columnSpacing",
|
|
14
|
+
COLUMN_SPACING_LABEL: "columnSpacingLabel",
|
|
15
|
+
ROW_SPACING: "rowSpacing"
|
|
16
|
+
}, P = {
|
|
17
|
+
COLUMN_SPACING: "data-column-spacing",
|
|
18
|
+
ROW_SPACING: "data-row-spacing"
|
|
19
|
+
};
|
|
20
|
+
function N(o, n) {
|
|
21
|
+
if (!o)
|
|
22
|
+
return n;
|
|
23
|
+
const t = parseFloat(o);
|
|
24
|
+
return Number.isNaN(t) ? n : t;
|
|
25
|
+
}
|
|
26
|
+
class $ extends L {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(...arguments);
|
|
29
|
+
l(this, "store", w());
|
|
30
|
+
l(this, "unsubscribeOrientation", null);
|
|
31
|
+
/**
|
|
32
|
+
* Debounced version of _onColumnSpacingChange
|
|
33
|
+
* Prevents excessive DOM updates when user rapidly adjusts the counter
|
|
34
|
+
*/
|
|
35
|
+
l(this, "_debouncedOnColumnSpacingChange", O((t) => {
|
|
36
|
+
this._onColumnSpacingChange(t);
|
|
37
|
+
}, 300));
|
|
38
|
+
/**
|
|
39
|
+
* Debounced version of _onRowSpacingChange
|
|
40
|
+
* Prevents excessive DOM updates when user rapidly adjusts the counter
|
|
41
|
+
*/
|
|
42
|
+
l(this, "_debouncedOnRowSpacingChange", O((t) => {
|
|
43
|
+
this._onRowSpacingChange(t);
|
|
44
|
+
}, 300));
|
|
45
|
+
}
|
|
46
|
+
getId() {
|
|
47
|
+
return R;
|
|
48
|
+
}
|
|
49
|
+
getTemplate() {
|
|
50
|
+
return `
|
|
51
|
+
<div class="spacing-control-container">
|
|
52
|
+
${this._GuTwoColumns([
|
|
53
|
+
this._GuLabel({ text: "Column Spacing (px)", name: s.COLUMN_SPACING_LABEL }),
|
|
54
|
+
this._GuCounter({
|
|
55
|
+
name: s.COLUMN_SPACING,
|
|
56
|
+
minValue: A,
|
|
57
|
+
maxValue: y,
|
|
58
|
+
step: b
|
|
59
|
+
}),
|
|
60
|
+
this._GuLabel({ text: "Row Spacing (px)" }),
|
|
61
|
+
this._GuCounter({
|
|
62
|
+
name: s.ROW_SPACING,
|
|
63
|
+
minValue: A,
|
|
64
|
+
maxValue: y,
|
|
65
|
+
step: b
|
|
66
|
+
})
|
|
67
|
+
])}
|
|
68
|
+
</div>
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
onRender() {
|
|
72
|
+
this._setFormValues(), this._updateColumnSpacingVisibility(), this._listenToFormUpdates(), this._subscribeToOrientationChanges();
|
|
73
|
+
}
|
|
74
|
+
onTemplateNodeUpdated(t) {
|
|
75
|
+
super.onTemplateNodeUpdated(t), this._setFormValues(), this._updateColumnSpacingVisibility();
|
|
76
|
+
}
|
|
77
|
+
onDestroy() {
|
|
78
|
+
this.unsubscribeOrientation && (this.unsubscribeOrientation(), this.unsubscribeOrientation = null);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Updates column spacing visibility based on layout orientation
|
|
82
|
+
* Column spacing is hidden for list layout (products are stacked vertically)
|
|
83
|
+
* Reads from node config first, falls back to store then DOM
|
|
84
|
+
*/
|
|
85
|
+
_updateColumnSpacingVisibility() {
|
|
86
|
+
if (!this.api)
|
|
87
|
+
return;
|
|
88
|
+
const t = d.getConfig(this.currentNode), e = this.store.recommendationConfigs.orientation, i = (t.layout || e || C(this.currentNode)) === "grid";
|
|
89
|
+
this.api.setVisibility(s.COLUMN_SPACING, i), this.api.setVisibility(s.COLUMN_SPACING_LABEL, i);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Reads spacing values from node config first, falls back to DOM styles
|
|
93
|
+
*/
|
|
94
|
+
_setFormValues() {
|
|
95
|
+
if (!this.api)
|
|
96
|
+
return;
|
|
97
|
+
const t = d.getConfig(this.currentNode), e = t.columnSpacing !== a ? t.columnSpacing : this._getStoredColumnSpacing(), r = t.rowSpacing !== m ? t.rowSpacing : this._getStoredRowSpacing();
|
|
98
|
+
this.api.updateValues({
|
|
99
|
+
[s.COLUMN_SPACING]: e,
|
|
100
|
+
[s.ROW_SPACING]: r
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Gets stored column spacing from the first attribute row cell's padding.
|
|
105
|
+
* For grid layout: cells inside .recommendation-attribute-row have padding applied.
|
|
106
|
+
* For list layout: the parent of .product-card-wrapper has the padding.
|
|
107
|
+
* The padding is applied as "0 {halfSpacing}px", so we extract and multiply by 2.
|
|
108
|
+
*/
|
|
109
|
+
_getStoredColumnSpacing() {
|
|
110
|
+
if (!this.currentNode)
|
|
111
|
+
return a;
|
|
112
|
+
if (C(this.currentNode) === "grid") {
|
|
113
|
+
const p = this.currentNode.querySelector(".recommendation-attribute-row"), c = p == null ? void 0 : p.querySelector("td"), f = S(c, "padding");
|
|
114
|
+
if (!f)
|
|
115
|
+
return a;
|
|
116
|
+
const _ = f.trim().split(/\s+/);
|
|
117
|
+
return _.length < 2 ? a : N(_[1], a / 2) * 2;
|
|
118
|
+
}
|
|
119
|
+
const e = this.currentNode.querySelector(".product-card-wrapper"), r = V(e), i = S(r, "padding");
|
|
120
|
+
if (!i)
|
|
121
|
+
return a;
|
|
122
|
+
const u = i.trim().split(/\s+/);
|
|
123
|
+
return u.length < 2 ? a : N(u[1], a / 2) * 2;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Gets stored row spacing from the first spacer element's height style
|
|
127
|
+
*/
|
|
128
|
+
_getStoredRowSpacing() {
|
|
129
|
+
if (!this.currentNode)
|
|
130
|
+
return m;
|
|
131
|
+
const t = this.currentNode.querySelector(".spacer"), e = S(t, "height");
|
|
132
|
+
return N(e, m);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Handles column spacing changes.
|
|
136
|
+
* For grid layout: applies horizontal padding to all cells inside attribute rows.
|
|
137
|
+
* For list layout: applies padding to parent of product card wrappers.
|
|
138
|
+
*/
|
|
139
|
+
_onColumnSpacingChange(t) {
|
|
140
|
+
if (!this.currentNode)
|
|
141
|
+
return;
|
|
142
|
+
d.updateConfig(
|
|
143
|
+
this.api,
|
|
144
|
+
this.currentNode,
|
|
145
|
+
{ columnSpacing: t },
|
|
146
|
+
`Changed column spacing to ${t}px`
|
|
147
|
+
), this._storeColumnSpacing(t);
|
|
148
|
+
const r = d.getConfig(this.currentNode).layout || C(this.currentNode), i = this.api.getDocumentModifier(), h = `0 ${t / 2}px`;
|
|
149
|
+
r === "grid" ? Array.from(
|
|
150
|
+
this.currentNode.querySelectorAll(".attribute-cell")
|
|
151
|
+
).forEach((c) => {
|
|
152
|
+
i.modifyHtml(c).setStyle("padding", h);
|
|
153
|
+
}) : Array.from(
|
|
154
|
+
this.currentNode.querySelectorAll(".product-card-wrapper")
|
|
155
|
+
).forEach((c) => {
|
|
156
|
+
"parent" in c && c.parent() && i.modifyHtml(c.parent()).setStyle("padding", h);
|
|
157
|
+
}), i.apply(new g(`Update column spacing to ${t}px`));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Handles row spacing changes
|
|
161
|
+
* Applies height to all spacer elements between product rows
|
|
162
|
+
*/
|
|
163
|
+
_onRowSpacingChange(t) {
|
|
164
|
+
if (!this.currentNode)
|
|
165
|
+
return;
|
|
166
|
+
d.updateConfig(
|
|
167
|
+
this.api,
|
|
168
|
+
this.currentNode,
|
|
169
|
+
{ rowSpacing: t },
|
|
170
|
+
`Changed row spacing to ${t}px`
|
|
171
|
+
), this._storeRowSpacing(t);
|
|
172
|
+
const e = Array.from(
|
|
173
|
+
this.currentNode.querySelectorAll(".spacer")
|
|
174
|
+
);
|
|
175
|
+
if (!e.length)
|
|
176
|
+
return;
|
|
177
|
+
const r = this.api.getDocumentModifier(), i = `${t}px`;
|
|
178
|
+
e.forEach((u) => {
|
|
179
|
+
r.modifyHtml(u).setStyle("height", i);
|
|
180
|
+
}), r.apply(new g(`Update row spacing to ${t}px`));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Stores column spacing value in block data attribute
|
|
184
|
+
*/
|
|
185
|
+
_storeColumnSpacing(t) {
|
|
186
|
+
if (!this.currentNode)
|
|
187
|
+
return;
|
|
188
|
+
const e = this.currentNode.querySelector(".ins-recommendation-v3-block-v2");
|
|
189
|
+
e && this.api.getDocumentModifier().modifyHtml(e).setAttribute(P.COLUMN_SPACING, t.toString()).apply(new g("Store column spacing"));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Stores row spacing value in block data attribute
|
|
193
|
+
*/
|
|
194
|
+
_storeRowSpacing(t) {
|
|
195
|
+
if (!this.currentNode)
|
|
196
|
+
return;
|
|
197
|
+
const e = this.currentNode.querySelector(".ins-recommendation-v3-block-v2");
|
|
198
|
+
e && this.api.getDocumentModifier().modifyHtml(e).setAttribute(P.ROW_SPACING, t.toString()).apply(new g("Store row spacing"));
|
|
199
|
+
}
|
|
200
|
+
_listenToFormUpdates() {
|
|
201
|
+
this.api.onValueChanged(s.COLUMN_SPACING, (t) => {
|
|
202
|
+
const e = parseInt(t);
|
|
203
|
+
Number.isNaN(e) || this._debouncedOnColumnSpacingChange(e);
|
|
204
|
+
}), this.api.onValueChanged(s.ROW_SPACING, (t) => {
|
|
205
|
+
const e = parseInt(t);
|
|
206
|
+
Number.isNaN(e) || this._debouncedOnRowSpacingChange(e);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Subscribe to store orientation changes
|
|
211
|
+
* Updates column spacing visibility when layout changes via the layout control
|
|
212
|
+
*/
|
|
213
|
+
_subscribeToOrientationChanges() {
|
|
214
|
+
this.unsubscribeOrientation && this.unsubscribeOrientation(), this.unsubscribeOrientation = this.store.$subscribe((t) => {
|
|
215
|
+
t.type === "patch object" && this._updateColumnSpacingVisibility();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
export {
|
|
220
|
+
R as SPACING_CONTROL_ID,
|
|
221
|
+
$ as SpacingControl
|
|
222
|
+
};
|
|
@@ -1,19 +1,42 @@
|
|
|
1
|
-
import { ExtensionBuilder as
|
|
2
|
-
import { RecommendationBlock as
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
1
|
+
import { ExtensionBuilder as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
+
import { RecommendationBlock as m } from "./block.js";
|
|
3
|
+
import { RecommendationBlockControl as n } from "./controls/main/index.js";
|
|
4
|
+
import "./store/recommendation.js";
|
|
5
|
+
import { NameControls as i } from "./controls/name/index.js";
|
|
6
|
+
import { PriceControls as e } from "./controls/price/index.js";
|
|
7
|
+
import { OldPriceControls as l } from "./controls/oldPrice/index.js";
|
|
8
|
+
import { OmnibusPriceControls as s } from "./controls/omnibusPrice/index.js";
|
|
9
|
+
import { OmnibusDiscountControls as a } from "./controls/omnibusDiscount/index.js";
|
|
10
|
+
import { ButtonControls as p } from "./controls/button/index.js";
|
|
11
|
+
import { ImageControls as c } from "./controls/image/index.js";
|
|
12
|
+
import { SpacingControl as C } from "./controls/spacing/index.js";
|
|
13
|
+
import { CardBackgroundColorControl as d } from "./controls/cardBackground/index.js";
|
|
14
|
+
import { LayoutControl as f } from "./controls/layout/index.js";
|
|
15
|
+
import { RecommendationCardCompositionControl as u } from "./controls/cardComposition/index.js";
|
|
16
|
+
import { RecommendationIconsRegistry as g } from "./iconsRegistry.js";
|
|
17
|
+
import R from "./recommendation.css.js";
|
|
18
|
+
import { SettingsPanel as y } from "./settingsPanel.js";
|
|
19
|
+
const B = [
|
|
20
|
+
i,
|
|
21
|
+
e,
|
|
22
|
+
l,
|
|
23
|
+
s,
|
|
24
|
+
a,
|
|
25
|
+
p,
|
|
26
|
+
c
|
|
27
|
+
], P = [
|
|
28
|
+
n,
|
|
29
|
+
d,
|
|
30
|
+
f,
|
|
31
|
+
C,
|
|
32
|
+
u
|
|
33
|
+
], b = [
|
|
34
|
+
...P,
|
|
35
|
+
...B.flatMap((o) => Object.values(o))
|
|
36
|
+
], F = b.reduce(
|
|
37
|
+
(o, t) => o.addControl(t),
|
|
38
|
+
new r().addBlock(m).withSettingsPanelRegistry(y)
|
|
39
|
+
).addStyles(R).withIconsRegistry(g).build();
|
|
17
40
|
export {
|
|
18
|
-
|
|
41
|
+
F as default
|
|
19
42
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IconsRegistry as
|
|
2
|
-
class
|
|
1
|
+
import { IconsRegistry as t } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
+
class o extends t {
|
|
3
3
|
registerIconsSvg(C) {
|
|
4
4
|
C["recommendation-icon"] = `
|
|
5
5
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
@@ -43,9 +43,60 @@ class n extends o {
|
|
|
43
43
|
3.40029 12.0082 3.25285 11.7656 3.15234C11.365 2.98638 11.0001 2.64849 11 2.21484V2Z"
|
|
44
44
|
fill="currentColor"/>
|
|
45
45
|
</svg>
|
|
46
|
+
`, C["grid-orientation"] = `
|
|
47
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
|
|
48
|
+
<rect x="1" y="1" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
49
|
+
<rect x="12" y="1" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
50
|
+
<rect x="1" y="12" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
51
|
+
<rect x="12" y="12" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
52
|
+
</svg>
|
|
53
|
+
`, C["list-orientation"] = `
|
|
54
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
|
|
55
|
+
<circle cx="3" cy="4" r="1" stroke="currentColor" stroke-width="1"/>
|
|
56
|
+
<rect x="7" y="3" width="11" height="2" rx="1"/>
|
|
57
|
+
<circle cx="3" cy="10" r="1" stroke="currentColor" stroke-width="1"/>
|
|
58
|
+
<rect x="7" y="9" width="11" height="2" rx="1"/>
|
|
59
|
+
<circle cx="3" cy="16" r="1" stroke="currentColor" stroke-width="1"/>
|
|
60
|
+
<rect x="7" y="15" width="11" height="2" rx="1"/>
|
|
61
|
+
</svg>
|
|
62
|
+
`, C["migration-info-icon"] = `
|
|
63
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
64
|
+
<g transform="translate(3, 2.5)">
|
|
65
|
+
<path d="M6.87812 0.141942C10.7873 -0.580665 14.6797 1.51065 16.201 5.16436C17.7344
|
|
66
|
+
8.84685 16.432 13.0909 13.0906 15.3015C9.77511 17.4946 5.36819 17.08 2.52785
|
|
67
|
+
14.3193L2.46105 14.2536C0.882709 12.6854 -0.00259777 10.5591 5.72603e-06
|
|
68
|
+
8.34301L0.000643642 8.24974C0.0491816 4.30543 2.87651 0.926565 6.78576
|
|
69
|
+
0.159555L6.87812 0.141942ZM14.5911 5.82406C13.3749 2.90345 10.2486 1.24158 7.12372
|
|
70
|
+
1.85468C3.99888 2.46779 1.74568 5.18516 1.74194 8.34505C1.73988 10.1027 2.44203
|
|
71
|
+
11.789 3.69379 13.0328C5.94435 15.269 9.4739 15.617 12.1241 13.8638C14.7742 12.1106
|
|
72
|
+
15.8071 8.74458 14.5911 5.82406Z" fill="#258DDE"/>
|
|
73
|
+
<path d="M12.5195 13.5806C12.8537 13.2479 13.3933 13.2417 13.7351 13.5628L13.7512
|
|
74
|
+
13.5783L17.7437 17.5239C18.0845 17.8607 18.0856 18.4077 17.7461 18.7458C17.4066
|
|
75
|
+
19.0838 16.8551 19.0849 16.5143 18.7481L12.5218 14.8025L12.5061 14.7866C12.1811
|
|
76
|
+
14.4487 12.1853 13.9134 12.5195 13.5806Z" fill="#258DDE"/>
|
|
77
|
+
<path d="M6.71262 5.42913C6.37248 5.09172 5.82105 5.09172 5.48092 5.42913C5.14079
|
|
78
|
+
5.76655 5.14079 6.3136 5.48092 6.65104L6.71262 5.42913ZM7.80353 8.95504C8.14367
|
|
79
|
+
9.29246 8.69506 9.29246 9.0352 8.95504C9.37534 8.61762 9.37534 8.07053 9.0352
|
|
80
|
+
7.73311L7.80353 8.95504ZM9.0352 7.73311C8.69506 7.39569 8.14367 7.39569 7.80353
|
|
81
|
+
7.73311C7.46339 8.07053 7.46339 8.61762 7.80353 8.95504L9.0352 7.73311ZM10.1261
|
|
82
|
+
11.259C10.4663 11.5965 11.0176 11.5965 11.3578 11.259C11.6979 10.9216 11.6979
|
|
83
|
+
10.3745 11.3578 10.0371L10.1261 11.259ZM9.0352 8.95504C9.37534 8.61762 9.37534
|
|
84
|
+
8.07053 9.0352 7.73311C8.69506 7.39569 8.14367 7.39569 7.80353 7.73311L9.0352
|
|
85
|
+
8.95504ZM5.48092 10.0371C5.14079 10.3745 5.14079 10.9216 5.48092 11.259C5.82105
|
|
86
|
+
11.5965 6.37248 11.5965 6.71262 11.259L5.48092 10.0371ZM7.80353 7.73311C7.46339
|
|
87
|
+
8.07053 7.46339 8.61762 7.80353 8.95504C8.14367 9.29246 8.69506 9.29246 9.0352
|
|
88
|
+
8.95504L7.80353 7.73311ZM11.3578 6.65104C11.6979 6.3136 11.6979 5.76655 11.3578
|
|
89
|
+
5.42913C11.0176 5.09172 10.4663 5.09172 10.1261 5.42913L11.3578 6.65104ZM5.48092
|
|
90
|
+
6.65104L7.80353 8.95504L9.0352 7.73311L6.71262 5.42913L5.48092 6.65104ZM7.80353
|
|
91
|
+
8.95504L10.1261 11.259L11.3578 10.0371L9.0352 7.73311L7.80353 8.95504ZM7.80353
|
|
92
|
+
7.73311L5.48092 10.0371L6.71262 11.259L9.0352 8.95504L7.80353 7.73311ZM9.0352
|
|
93
|
+
8.95504L11.3578 6.65104L10.1261 5.42913L7.80353 7.73311L9.0352 8.95504Z"
|
|
94
|
+
fill="#258DDE"/>
|
|
95
|
+
</g>
|
|
96
|
+
</svg>
|
|
46
97
|
`;
|
|
47
98
|
}
|
|
48
99
|
}
|
|
49
100
|
export {
|
|
50
|
-
|
|
101
|
+
o as RecommendationIconsRegistry
|
|
51
102
|
};
|
|
@@ -1,18 +1,75 @@
|
|
|
1
1
|
const n = `/* Utils */
|
|
2
2
|
.es-180w { width: 180px; }
|
|
3
3
|
|
|
4
|
-
/* Recommendation Controls */
|
|
5
|
-
.recommendation-controls-container >
|
|
6
|
-
|
|
4
|
+
/* Recommendation Controls - Main settings panel separators */
|
|
5
|
+
.recommendation-controls-container > div {
|
|
6
|
+
border-bottom: 1px solid #e0e0e0;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.recommendation-controls-container >
|
|
9
|
+
.recommendation-controls-container > div:first-child {
|
|
10
10
|
padding-top: 0;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
.recommendation-controls-container > div:last-child {
|
|
14
|
+
border-bottom: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
.container:has(.recommendation-controls-container) {
|
|
14
18
|
padding: 0
|
|
15
19
|
}
|
|
20
|
+
|
|
21
|
+
/* Hide drag icon for list layout (ordering disabled) */
|
|
22
|
+
ue-orderable.orderable-disabled .droppable-icon {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ─── Migration Info Box ─────────────────────────────────────────────── */
|
|
27
|
+
/* Shown in the settings panel title when a block was migrated from legacy */
|
|
28
|
+
|
|
29
|
+
/* Layout variables for positioning the absolutely-placed info box */
|
|
30
|
+
:host {
|
|
31
|
+
--rec-migration-padding: 16px;
|
|
32
|
+
--rec-migration-title-height: 61px;
|
|
33
|
+
--rec-migration-box-height: 98px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Push tabs down when info box is present inside the control panel header */
|
|
37
|
+
.control-panel-header:has(.recommendation-migration-info) {
|
|
38
|
+
position: relative;
|
|
39
|
+
margin-bottom: calc(2 * var(--rec-migration-padding) + var(--rec-migration-box-height));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Info box container */
|
|
43
|
+
.recommendation-migration-info {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: flex-start;
|
|
46
|
+
gap: 8px;
|
|
47
|
+
padding: 12px;
|
|
48
|
+
background: var(--guido-color-background-onpage-message-info);
|
|
49
|
+
border: 1px solid var(--guido-color-border-onpage-message-info);
|
|
50
|
+
border-radius: 4px;
|
|
51
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: var(--rec-migration-padding);
|
|
54
|
+
right: var(--rec-migration-padding);
|
|
55
|
+
top: calc(var(--rec-migration-padding) + var(--rec-migration-title-height));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
|
|
59
|
+
.recommendation-migration-info__icon {
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
width: 24px;
|
|
62
|
+
height: 24px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Text content */
|
|
66
|
+
.recommendation-migration-info__text {
|
|
67
|
+
margin: 4px 0;
|
|
68
|
+
white-space: normal;
|
|
69
|
+
font-size: 13px;
|
|
70
|
+
font-weight: 400;
|
|
71
|
+
line-height: 16px;
|
|
72
|
+
}
|
|
16
73
|
`;
|
|
17
74
|
export {
|
|
18
75
|
n as default
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { ModificationDescription as f } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
+
import { CURRENT_CONFIG_VERSION as u, DEFAULT_NODE_CONFIG as e } from "../constants/defaultConfig.js";
|
|
3
|
+
import { setCurrencyAttributes as g } from "../controls/main/utils.js";
|
|
4
|
+
import { hasMinimalConfig as a } from "../types/nodeConfig.js";
|
|
5
|
+
class C {
|
|
6
|
+
// ========================================================================
|
|
7
|
+
// Read Operations
|
|
8
|
+
// ========================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Get configuration from a node, with defaults for missing values
|
|
11
|
+
*
|
|
12
|
+
* This is the primary way to read configuration from a block.
|
|
13
|
+
* Always returns a complete config object with defaults merged in.
|
|
14
|
+
* @example
|
|
15
|
+
* const config = RecommendationConfigService.getConfig(this.currentNode);
|
|
16
|
+
* console.log(config.strategy); // 'mostPopular'
|
|
17
|
+
* @param node - The immutable HTML node to read config from
|
|
18
|
+
* @returns Complete configuration with defaults for missing values
|
|
19
|
+
*/
|
|
20
|
+
static getConfig(i) {
|
|
21
|
+
if (!i)
|
|
22
|
+
return this.cloneDefaults();
|
|
23
|
+
if (!("getNodeConfig" in i) || typeof i.getNodeConfig != "function")
|
|
24
|
+
return this.cloneDefaults();
|
|
25
|
+
try {
|
|
26
|
+
const t = i.getNodeConfig();
|
|
27
|
+
return t ? this.mergeWithDefaults(t) : this.cloneDefaults();
|
|
28
|
+
} catch {
|
|
29
|
+
return this.cloneDefaults();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if a node has valid configuration stored
|
|
34
|
+
*
|
|
35
|
+
* Used for migration detection - returns false for legacy templates
|
|
36
|
+
* that need their configuration migrated.
|
|
37
|
+
* @param node - The immutable HTML node to check
|
|
38
|
+
* @returns True if node has valid config with version number
|
|
39
|
+
*/
|
|
40
|
+
static hasConfig(i) {
|
|
41
|
+
if (!i || !("getNodeConfig" in i) || typeof i.getNodeConfig != "function")
|
|
42
|
+
return !1;
|
|
43
|
+
try {
|
|
44
|
+
const t = i.getNodeConfig();
|
|
45
|
+
return a(t);
|
|
46
|
+
} catch {
|
|
47
|
+
return !1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the configuration version from a node
|
|
52
|
+
* @param node - The immutable HTML node to check
|
|
53
|
+
* @returns Config version number, or 0 if no config exists
|
|
54
|
+
*/
|
|
55
|
+
static getConfigVersion(i) {
|
|
56
|
+
return this.hasConfig(i) && this.getConfig(i).configVersion || 0;
|
|
57
|
+
}
|
|
58
|
+
// ========================================================================
|
|
59
|
+
// Write Operations
|
|
60
|
+
// ========================================================================
|
|
61
|
+
/**
|
|
62
|
+
* Update specific configuration values
|
|
63
|
+
*
|
|
64
|
+
* Merges the updates with existing config and persists to node.
|
|
65
|
+
* This is the primary way to update configuration from controls.
|
|
66
|
+
* @example
|
|
67
|
+
* RecommendationConfigService.updateConfig(
|
|
68
|
+
* this.api,
|
|
69
|
+
* this.currentNode,
|
|
70
|
+
* { strategy: 'complementaryItems' },
|
|
71
|
+
* 'Changed recommendation algorithm'
|
|
72
|
+
* );
|
|
73
|
+
* @param api - Stripo extension API with document modifier
|
|
74
|
+
* @param node - The immutable HTML node to update
|
|
75
|
+
* @param updates - Partial config with values to update
|
|
76
|
+
* @param description - Human-readable description for undo/redo
|
|
77
|
+
* @returns The new complete configuration
|
|
78
|
+
*/
|
|
79
|
+
static updateConfig(i, t, o, n) {
|
|
80
|
+
const s = this.getConfig(t), r = this.deepMerge(s, o);
|
|
81
|
+
return this.saveConfig(i, t, r, n), r;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initialize configuration for a new block
|
|
85
|
+
*
|
|
86
|
+
* Called when a block is first created (dropped into template).
|
|
87
|
+
* Can optionally merge in partial config from migration.
|
|
88
|
+
* @example
|
|
89
|
+
* // In Block.onCreated lifecycle
|
|
90
|
+
* RecommendationConfigService.initializeConfig(this.api, node);
|
|
91
|
+
* @param api - Stripo extension API with document modifier
|
|
92
|
+
* @param node - The immutable HTML node to initialize
|
|
93
|
+
* @param partialConfig - Optional partial config to merge with defaults
|
|
94
|
+
* @returns The initialized configuration
|
|
95
|
+
*/
|
|
96
|
+
static initializeConfig(i, t, o) {
|
|
97
|
+
const n = o ? this.mergeWithDefaults(o) : this.cloneDefaults();
|
|
98
|
+
return this.saveConfig(i, t, n, "Initialize recommendation block"), g({
|
|
99
|
+
currentNode: t,
|
|
100
|
+
documentModifier: i.getDocumentModifier(),
|
|
101
|
+
currency: n.currency
|
|
102
|
+
}), n;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Save complete configuration to a node
|
|
106
|
+
*
|
|
107
|
+
* Low-level method - prefer `updateConfig` or `initializeConfig` in most cases.
|
|
108
|
+
* @param api - Stripo extension API with document modifier
|
|
109
|
+
* @param node - The immutable HTML node to save to
|
|
110
|
+
* @param config - Complete configuration to save
|
|
111
|
+
* @param description - Human-readable description for undo/redo
|
|
112
|
+
*/
|
|
113
|
+
static saveConfig(i, t, o, n) {
|
|
114
|
+
try {
|
|
115
|
+
i.getDocumentModifier().modifyHtml(t).setNodeConfig(o).apply(new f(n));
|
|
116
|
+
} catch (s) {
|
|
117
|
+
console.warn("[RecommendationConfigService] Failed to save config:", s);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ========================================================================
|
|
121
|
+
// Migration Helpers
|
|
122
|
+
// ========================================================================
|
|
123
|
+
/**
|
|
124
|
+
* Migrate configuration from legacy data-attributes
|
|
125
|
+
*
|
|
126
|
+
* Reads existing data-attributes and creates a proper node config.
|
|
127
|
+
* Used when loading templates created before node config was implemented.
|
|
128
|
+
* @param api - Stripo extension API with document modifier
|
|
129
|
+
* @param node - The block node to migrate
|
|
130
|
+
* @returns The migrated configuration
|
|
131
|
+
*/
|
|
132
|
+
static migrateFromDataAttributes(i, t) {
|
|
133
|
+
const o = {
|
|
134
|
+
configVersion: u
|
|
135
|
+
};
|
|
136
|
+
if ("getAttribute" in t && typeof t.getAttribute == "function") {
|
|
137
|
+
const n = t.getAttribute("data-layout");
|
|
138
|
+
n === "list" || n === "horizontal" ? o.layout = "list" : (n === "grid" || n === "vertical") && (o.layout = "grid");
|
|
139
|
+
const s = t.getAttribute("data-card-composition");
|
|
140
|
+
s && (o.composition = s.split(",").filter(Boolean));
|
|
141
|
+
const r = t.getAttribute("data-column-spacing");
|
|
142
|
+
r && (o.columnSpacing = parseInt(r) || e.columnSpacing);
|
|
143
|
+
const c = t.getAttribute("data-row-spacing");
|
|
144
|
+
c && (o.rowSpacing = parseInt(c) || e.rowSpacing);
|
|
145
|
+
}
|
|
146
|
+
return this.initializeConfig(i, t, o);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if configuration needs migration
|
|
150
|
+
* @param node - The block node to check
|
|
151
|
+
* @returns True if migration is needed
|
|
152
|
+
*/
|
|
153
|
+
static needsMigration(i) {
|
|
154
|
+
return i ? this.hasConfig(i) ? this.getConfigVersion(i) < u : !0 : !1;
|
|
155
|
+
}
|
|
156
|
+
// ========================================================================
|
|
157
|
+
// Internal Helpers
|
|
158
|
+
// ========================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Clone default config to avoid mutations
|
|
161
|
+
*/
|
|
162
|
+
static cloneDefaults() {
|
|
163
|
+
return {
|
|
164
|
+
...e,
|
|
165
|
+
currency: { ...e.currency },
|
|
166
|
+
omnibusPrice: { ...e.omnibusPrice },
|
|
167
|
+
omnibusDiscount: { ...e.omnibusDiscount },
|
|
168
|
+
composition: [...e.composition],
|
|
169
|
+
visibility: { ...e.visibility },
|
|
170
|
+
filters: [],
|
|
171
|
+
productIds: [],
|
|
172
|
+
recommendationId: 0
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Merge partial config with defaults
|
|
177
|
+
*
|
|
178
|
+
* Deep merges nested objects like currency, omnibus settings.
|
|
179
|
+
*/
|
|
180
|
+
static mergeWithDefaults(i) {
|
|
181
|
+
const t = this.cloneDefaults();
|
|
182
|
+
return {
|
|
183
|
+
...t,
|
|
184
|
+
...i,
|
|
185
|
+
currency: {
|
|
186
|
+
...t.currency,
|
|
187
|
+
...i.currency || {}
|
|
188
|
+
},
|
|
189
|
+
omnibusPrice: {
|
|
190
|
+
...t.omnibusPrice,
|
|
191
|
+
...i.omnibusPrice || {}
|
|
192
|
+
},
|
|
193
|
+
omnibusDiscount: {
|
|
194
|
+
...t.omnibusDiscount,
|
|
195
|
+
...i.omnibusDiscount || {}
|
|
196
|
+
},
|
|
197
|
+
visibility: {
|
|
198
|
+
...t.visibility,
|
|
199
|
+
...i.visibility || {}
|
|
200
|
+
},
|
|
201
|
+
composition: i.composition || t.composition,
|
|
202
|
+
filters: i.filters || [],
|
|
203
|
+
productIds: i.productIds || []
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Deep merge for nested objects
|
|
208
|
+
*
|
|
209
|
+
* Recursively merges source into target, preserving existing values
|
|
210
|
+
* that aren't explicitly overwritten.
|
|
211
|
+
*/
|
|
212
|
+
static deepMerge(i, t) {
|
|
213
|
+
return {
|
|
214
|
+
...i,
|
|
215
|
+
...t,
|
|
216
|
+
currency: {
|
|
217
|
+
...i.currency,
|
|
218
|
+
...t.currency || {}
|
|
219
|
+
},
|
|
220
|
+
omnibusPrice: {
|
|
221
|
+
...i.omnibusPrice,
|
|
222
|
+
...t.omnibusPrice || {}
|
|
223
|
+
},
|
|
224
|
+
omnibusDiscount: {
|
|
225
|
+
...i.omnibusDiscount,
|
|
226
|
+
...t.omnibusDiscount || {}
|
|
227
|
+
},
|
|
228
|
+
visibility: {
|
|
229
|
+
...i.visibility,
|
|
230
|
+
...t.visibility || {}
|
|
231
|
+
},
|
|
232
|
+
composition: t.composition ?? i.composition,
|
|
233
|
+
filters: t.filters ?? i.filters,
|
|
234
|
+
productIds: t.productIds ?? i.productIds
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
export {
|
|
239
|
+
C as RecommendationConfigService
|
|
240
|
+
};
|