@useinsider/guido 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -1
- package/dist/@types/config/schemas.js +153 -95
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +90 -88
- package/dist/components/organisms/AutoSaveController.vue.js +17 -0
- package/dist/components/organisms/AutoSaveController.vue2.js +13 -0
- package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
- package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
- package/dist/components/organisms/header/RightSlot.vue.js +8 -8
- package/dist/components/organisms/header/RightSlot.vue2.js +9 -8
- package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
- package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
- package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
- package/dist/composables/useActionsApi.js +4 -4
- package/dist/composables/useAutoSave.js +71 -0
- package/dist/composables/useFullStoryBridge.js +14 -0
- package/dist/composables/useRecommendation.js +46 -26
- package/dist/composables/useRibbonOffset.js +21 -0
- package/dist/composables/useSave.js +19 -16
- package/dist/composables/useStripo.js +40 -40
- package/dist/composables/validators/useCouponBlockValidator.js +24 -0
- package/dist/config/compiler/recommendationCompilerRules.js +79 -74
- package/dist/config/compiler/unsubscribeCompilerRules.js +40 -37
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +107 -71
- package/dist/config/migrator/index.js +9 -9
- package/dist/config/migrator/radioButtonMigrator.js +64 -44
- package/dist/config/migrator/recommendation/compositionMapper.js +98 -0
- package/dist/config/migrator/recommendation/extractors.js +27 -0
- package/dist/config/migrator/recommendation/htmlBuilder.js +496 -0
- package/dist/config/migrator/recommendation/parseLegacyConfig.js +33 -0
- package/dist/config/migrator/recommendation/settingsMapper.js +70 -0
- package/dist/config/migrator/recommendation/themeMapper.js +93 -0
- package/dist/config/migrator/recommendationMigrator.js +74 -290
- package/dist/enums/extensions/recommendationBlock.js +2 -1
- package/dist/enums/onboarding.js +7 -2
- package/dist/enums/unsubscribe.js +34 -27
- package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +38 -38
- package/dist/extensions/Blocks/Items/enums/productEnums.js +19 -7
- package/dist/extensions/Blocks/RadioButton/template.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +35 -32
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +5 -5
- package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
- package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +27 -26
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +228 -181
- package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
- package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
- package/dist/extensions/Blocks/Recommendation/services/configService.js +65 -29
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +123 -79
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +19 -10
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +8 -8
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +25 -15
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +11 -11
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +1 -1
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +21 -0
- package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +13 -22
- package/dist/extensions/Blocks/Unsubscribe/block.js +11 -11
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
- package/dist/node_modules/valibot/dist/index.js +450 -235
- package/dist/package.json.js +1 -1
- package/dist/services/templateLibraryApi.js +5 -4
- package/dist/src/@types/config/defaults.d.ts +5 -1
- package/dist/src/@types/config/index.d.ts +3 -3
- package/dist/src/@types/config/schemas.d.ts +217 -0
- package/dist/src/@types/config/types.d.ts +9 -1
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/AutoSaveController.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/AutoSaveToggle.vue.d.ts +2 -0
- 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/RightSlot.vue.d.ts +1 -1
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useActionsApi.d.ts +1 -1
- package/dist/src/composables/useAutoSave.d.ts +3 -0
- package/dist/src/composables/useConfig.d.ts +58 -0
- package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
- package/dist/src/composables/useRecommendation.d.ts +10 -1
- package/dist/src/composables/useRecommendation.test.d.ts +1 -0
- package/dist/src/composables/useRibbonOffset.d.ts +4 -0
- package/dist/src/composables/useSave.d.ts +1 -1
- package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
- package/dist/src/config/migrator/index.d.ts +2 -1
- package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +2 -0
- package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +7 -0
- package/dist/src/config/migrator/recommendation/extractors.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +11 -0
- package/dist/src/config/migrator/recommendation/parseLegacyConfig.d.ts +15 -0
- package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +7 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/themeMapper.d.ts +5 -0
- package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/types.d.ts +205 -0
- package/dist/src/config/migrator/recommendationMigrator.d.ts +13 -1
- package/dist/src/config/migrator/recommendationMigrator.test.d.ts +1 -0
- package/dist/src/enums/onboarding.d.ts +6 -0
- package/dist/src/enums/unsubscribe.d.ts +5 -0
- package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
- package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +34 -0
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +21 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -3
- package/dist/src/library.d.ts +1 -1
- package/dist/src/stores/autosave.d.ts +12 -0
- package/dist/src/stores/config.d.ts +522 -0
- package/dist/src/stores/editor.d.ts +23 -0
- package/dist/src/stores/onboarding.d.ts +4 -0
- package/dist/src/utils/htmlEscape.d.ts +5 -0
- package/dist/src/utils/htmlEscape.test.d.ts +1 -0
- package/dist/src/utils/timeUtil.d.ts +8 -0
- package/dist/static/styles/components/button.css.js +16 -9
- package/dist/static/styles/components/loader.css.js +4 -0
- package/dist/static/styles/components/narrow-panel.css.js +52 -0
- package/dist/stores/autosave.js +17 -0
- package/dist/stores/editor.js +3 -1
- package/dist/stores/onboarding.js +4 -0
- package/dist/utils/htmlEscape.js +13 -0
- package/dist/utils/pairProductVariables.js +89 -88
- package/dist/utils/templatePreparation.js +72 -32
- package/dist/utils/timeUtil.js +19 -0
- package/package.json +7 -3
- package/dist/enums/displayConditions.js +0 -80
- package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +0 -251
- package/dist/src/enums/displayConditions.d.ts +0 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { RecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import { defineStore as
|
|
1
|
+
import { RecommendationFeedSourceMaps as S, getOperatorOptions as R, PriceAttributes as y } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as C } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
5
5
|
import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
|
|
6
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
7
|
-
import { getDefaultProducts as
|
|
6
|
+
import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
|
|
7
|
+
import { getDefaultProducts as g } from "../templates/utils.js";
|
|
8
8
|
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
9
|
-
import { isFilterValid as
|
|
10
|
-
const h =
|
|
9
|
+
import { isFilterValid as w } from "../validation/filterSchema.js";
|
|
10
|
+
const h = C();
|
|
11
11
|
let u = null, m = null, d = null;
|
|
12
|
-
function
|
|
12
|
+
function k() {
|
|
13
13
|
return {
|
|
14
14
|
cardsInRow: F,
|
|
15
15
|
currencySettings: {
|
|
@@ -37,9 +37,9 @@ function I() {
|
|
|
37
37
|
customAttributes: []
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function
|
|
40
|
+
function I() {
|
|
41
41
|
return {
|
|
42
|
-
recommendationConfigs:
|
|
42
|
+
recommendationConfigs: k(),
|
|
43
43
|
recommendationProducts: [],
|
|
44
44
|
filterStatus: !1,
|
|
45
45
|
filterSelectionDrawerStatus: !1,
|
|
@@ -57,7 +57,7 @@ const v = () => ({
|
|
|
57
57
|
blockStates: {},
|
|
58
58
|
currentRecommendationId: null,
|
|
59
59
|
configVersion: 0
|
|
60
|
-
}),
|
|
60
|
+
}), _ = P("guidoRecommendationExtension", {
|
|
61
61
|
state: () => v(),
|
|
62
62
|
getters: {
|
|
63
63
|
// ====================================================================
|
|
@@ -68,7 +68,7 @@ const v = () => ({
|
|
|
68
68
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
69
69
|
*/
|
|
70
70
|
recommendationConfigs(t) {
|
|
71
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
71
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
|
|
72
72
|
},
|
|
73
73
|
/**
|
|
74
74
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -102,46 +102,45 @@ const v = () => ({
|
|
|
102
102
|
},
|
|
103
103
|
hasValidFilters() {
|
|
104
104
|
const { filters: t } = this.recommendationConfigs;
|
|
105
|
-
return t.length ? t.every((
|
|
105
|
+
return t.length ? t.every((e) => e.isValid) : !1;
|
|
106
106
|
},
|
|
107
107
|
getFilterGroupCount() {
|
|
108
108
|
const { filters: t } = this.recommendationConfigs;
|
|
109
|
-
return t.length ? new Set(t.map((
|
|
109
|
+
return t.length ? new Set(t.map((e) => e.filterGroup)).size : 0;
|
|
110
110
|
},
|
|
111
111
|
getUniqueFilterGroups() {
|
|
112
112
|
const { filters: t } = this.recommendationConfigs;
|
|
113
|
-
return [...new Set(t.map((
|
|
113
|
+
return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
|
|
114
114
|
},
|
|
115
115
|
getActivePredictiveAlgorithms: (t) => {
|
|
116
|
-
const
|
|
117
|
-
return t.activePredictiveAlgorithms.filter((
|
|
118
|
-
|
|
119
|
-
}),
|
|
120
|
-
text:
|
|
121
|
-
value:
|
|
116
|
+
const e = [];
|
|
117
|
+
return t.activePredictiveAlgorithms.filter((r) => !D.includes(r)).forEach((r) => {
|
|
118
|
+
e.push(...S.filter((n) => n.id === r));
|
|
119
|
+
}), e.map((r) => ({
|
|
120
|
+
text: r.name,
|
|
121
|
+
value: r.key
|
|
122
122
|
}));
|
|
123
123
|
},
|
|
124
|
-
getLanguages: (t) => Object.entries(t.languages).map(([
|
|
125
|
-
text:
|
|
126
|
-
value:
|
|
124
|
+
getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
|
|
125
|
+
text: r,
|
|
126
|
+
value: e
|
|
127
127
|
})),
|
|
128
|
-
getCurrencySymbolList: (t) => t.currencyList.map((
|
|
129
|
-
text:
|
|
130
|
-
value:
|
|
128
|
+
getCurrencySymbolList: (t) => t.currencyList.map((e) => ({
|
|
129
|
+
text: e.text,
|
|
130
|
+
value: e.text
|
|
131
131
|
})),
|
|
132
132
|
getFilterList() {
|
|
133
133
|
return Object.values(this.filterList).map((t) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
|
|
134
|
+
let e;
|
|
135
|
+
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : y.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
137
136
|
text: t.displayName,
|
|
138
|
-
value:
|
|
137
|
+
value: e,
|
|
139
138
|
type: t.attributeType
|
|
140
139
|
};
|
|
141
140
|
});
|
|
142
141
|
},
|
|
143
142
|
getSelectedFilterGroup() {
|
|
144
|
-
return (t) => [...this.recommendationConfigs.filters].filter((
|
|
143
|
+
return (t) => [...this.recommendationConfigs.filters].filter((e) => e.filterGroup === t);
|
|
145
144
|
}
|
|
146
145
|
},
|
|
147
146
|
actions: {
|
|
@@ -155,7 +154,7 @@ const v = () => ({
|
|
|
155
154
|
setCurrentBlock(t) {
|
|
156
155
|
this.blockStates[t] || (this.blockStates = {
|
|
157
156
|
...this.blockStates,
|
|
158
|
-
[t]:
|
|
157
|
+
[t]: I()
|
|
159
158
|
}), this.currentRecommendationId = t;
|
|
160
159
|
},
|
|
161
160
|
/**
|
|
@@ -163,10 +162,15 @@ const v = () => ({
|
|
|
163
162
|
* Resets currentRecommendationId if it was the deleted block.
|
|
164
163
|
*/
|
|
165
164
|
removeBlockState(t) {
|
|
165
|
+
const e = t.toString();
|
|
166
|
+
if (this.recommendationCampaignUrls[e]) {
|
|
167
|
+
const n = { ...this.recommendationCampaignUrls };
|
|
168
|
+
delete n[e], this.recommendationCampaignUrls = n;
|
|
169
|
+
}
|
|
166
170
|
const r = { ...this.blockStates };
|
|
167
171
|
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
168
|
-
const
|
|
169
|
-
this.currentRecommendationId =
|
|
172
|
+
const n = Object.keys(this.blockStates).map(Number);
|
|
173
|
+
this.currentRecommendationId = n.length > 0 ? n[0] : null;
|
|
170
174
|
}
|
|
171
175
|
},
|
|
172
176
|
/**
|
|
@@ -176,37 +180,75 @@ const v = () => ({
|
|
|
176
180
|
markBlockInitialized(t) {
|
|
177
181
|
this.blockStates[t] && (this.blockStates[t].isInitialized = !0);
|
|
178
182
|
},
|
|
183
|
+
/**
|
|
184
|
+
* Seeds the URL-relevant fields of a block from a persisted node config.
|
|
185
|
+
*
|
|
186
|
+
* Used at save-time to ensure the campaign URL is built from the
|
|
187
|
+
* persisted truth (the `esd-ext-config` blob in the raw HTML) even when
|
|
188
|
+
* the user never selected the block in this editor session — without
|
|
189
|
+
* this seed, `_syncNodeConfigToStore` would never have run for that
|
|
190
|
+
* block and the store would hold default values (USD/en_US/mostPopular)
|
|
191
|
+
* instead of the real config.
|
|
192
|
+
*
|
|
193
|
+
* Creates the block entry if missing; otherwise patches only the URL-
|
|
194
|
+
* relevant subset and leaves runtime fields (e.g., `recommendedProducts`,
|
|
195
|
+
* `isInitialized`) alone.
|
|
196
|
+
*/
|
|
197
|
+
seedBlockUrlConfig(t, e) {
|
|
198
|
+
const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
|
|
199
|
+
name: e.currencyCode,
|
|
200
|
+
value: e.currencyCode,
|
|
201
|
+
symbol: e.currencyCode,
|
|
202
|
+
alignment: e.currencyAlignment === "before" ? "0" : "1",
|
|
203
|
+
decimalCount: String(e.currencyDecimalCount),
|
|
204
|
+
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
205
|
+
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
206
|
+
}, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
|
|
207
|
+
i.recommendationConfigs = {
|
|
208
|
+
...i.recommendationConfigs,
|
|
209
|
+
strategy: e.strategy,
|
|
210
|
+
language: e.language,
|
|
211
|
+
size: e.size,
|
|
212
|
+
productIds: e.productIds,
|
|
213
|
+
filters: e.filters,
|
|
214
|
+
shuffleProducts: e.shuffleProducts,
|
|
215
|
+
currencySettings: n
|
|
216
|
+
}, c && (this.blockStates = {
|
|
217
|
+
...this.blockStates,
|
|
218
|
+
[t]: i
|
|
219
|
+
});
|
|
220
|
+
},
|
|
179
221
|
/**
|
|
180
222
|
* Patches the current block's recommendationConfigs.
|
|
181
223
|
* Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
|
|
182
224
|
*/
|
|
183
|
-
patchCurrentBlockConfig(t,
|
|
225
|
+
patchCurrentBlockConfig(t, e = {}) {
|
|
184
226
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
185
227
|
return;
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
...
|
|
228
|
+
const r = this.blockStates[this.currentRecommendationId];
|
|
229
|
+
r.recommendationConfigs = {
|
|
230
|
+
...r.recommendationConfigs,
|
|
189
231
|
...t,
|
|
190
232
|
currencySettings: {
|
|
191
|
-
...
|
|
233
|
+
...r.recommendationConfigs.currencySettings,
|
|
192
234
|
...t.currencySettings || {}
|
|
193
235
|
}
|
|
194
236
|
};
|
|
195
|
-
const { triggerRefetch: n = !0 } =
|
|
237
|
+
const { triggerRefetch: n = !0 } = e;
|
|
196
238
|
n && this.configVersion++;
|
|
197
239
|
},
|
|
198
240
|
/**
|
|
199
241
|
* Creates a filter with the first available attribute and operator pre-selected.
|
|
200
242
|
*/
|
|
201
|
-
createDefaultFilter(t,
|
|
202
|
-
const [
|
|
243
|
+
createDefaultFilter(t, e) {
|
|
244
|
+
const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
|
|
203
245
|
return {
|
|
204
246
|
type: "standardFilter",
|
|
205
|
-
attribute: (
|
|
247
|
+
attribute: (r == null ? void 0 : r.value) ?? "",
|
|
206
248
|
operator: (n == null ? void 0 : n.value) ?? "",
|
|
207
249
|
innerGroupOperator: "*",
|
|
208
250
|
outerGroupOperator: "*",
|
|
209
|
-
filterNumber:
|
|
251
|
+
filterNumber: e,
|
|
210
252
|
filterGroup: t,
|
|
211
253
|
isValid: !1,
|
|
212
254
|
value: ""
|
|
@@ -258,14 +300,14 @@ const v = () => ({
|
|
|
258
300
|
u = (async () => {
|
|
259
301
|
const {
|
|
260
302
|
activePredictiveAlgorithms: t,
|
|
261
|
-
languages:
|
|
262
|
-
currencies:
|
|
303
|
+
languages: e,
|
|
304
|
+
currencies: r
|
|
263
305
|
} = await h.fetchRecommendationCreateData();
|
|
264
|
-
if (this.activePredictiveAlgorithms = t, this.languages =
|
|
306
|
+
if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
265
307
|
const n = this.blockStates[this.currentRecommendationId];
|
|
266
308
|
n.filterStatus = !!n.recommendationConfigs.filters.length;
|
|
267
309
|
}
|
|
268
|
-
this.currencyList =
|
|
310
|
+
this.currencyList = r;
|
|
269
311
|
})();
|
|
270
312
|
try {
|
|
271
313
|
await u;
|
|
@@ -302,8 +344,8 @@ const v = () => ({
|
|
|
302
344
|
deleteFilterGroup(t) {
|
|
303
345
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
304
346
|
return;
|
|
305
|
-
const
|
|
306
|
-
|
|
347
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
|
|
348
|
+
e.recommendationConfigs.filters = r.map((i) => ({
|
|
307
349
|
...i,
|
|
308
350
|
filterGroup: c.get(i.filterGroup) ?? i.filterGroup
|
|
309
351
|
}));
|
|
@@ -311,47 +353,47 @@ const v = () => ({
|
|
|
311
353
|
updateFilter(t) {
|
|
312
354
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
313
355
|
return;
|
|
314
|
-
const
|
|
315
|
-
if (
|
|
316
|
-
const n = [...
|
|
317
|
-
n[
|
|
356
|
+
const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
357
|
+
if (r !== -1) {
|
|
358
|
+
const n = [...e.recommendationConfigs.filters];
|
|
359
|
+
n[r] = {
|
|
318
360
|
...t,
|
|
319
|
-
isValid:
|
|
320
|
-
},
|
|
361
|
+
isValid: w(t)
|
|
362
|
+
}, e.recommendationConfigs.filters = n;
|
|
321
363
|
}
|
|
322
364
|
},
|
|
323
365
|
deleteFilter(t) {
|
|
324
366
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
325
367
|
return;
|
|
326
|
-
const
|
|
327
|
-
if (
|
|
328
|
-
let n = [...
|
|
329
|
-
if (n.splice(
|
|
368
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
369
|
+
if (r !== -1) {
|
|
370
|
+
let n = [...e.recommendationConfigs.filters];
|
|
371
|
+
if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
|
|
330
372
|
let i = 1;
|
|
331
373
|
n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
|
|
332
374
|
} else {
|
|
333
|
-
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s,
|
|
375
|
+
const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
|
|
334
376
|
n = n.map((s) => ({
|
|
335
377
|
...s,
|
|
336
378
|
filterGroup: o.get(s.filterGroup) ?? s.filterGroup
|
|
337
379
|
}));
|
|
338
380
|
}
|
|
339
|
-
|
|
381
|
+
e.recommendationConfigs.filters = n;
|
|
340
382
|
}
|
|
341
383
|
},
|
|
342
384
|
addFilter(t) {
|
|
343
385
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
344
386
|
return;
|
|
345
|
-
const
|
|
387
|
+
const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
|
|
346
388
|
(o) => o.filterGroup === t.filterGroup
|
|
347
|
-
).length + 1, i =
|
|
348
|
-
i !== -1 ?
|
|
389
|
+
).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
|
|
390
|
+
i !== -1 ? r.splice(i + 1, 0, {
|
|
349
391
|
...t,
|
|
350
392
|
filterNumber: c
|
|
351
|
-
}) :
|
|
393
|
+
}) : r.push({
|
|
352
394
|
...t,
|
|
353
395
|
filterNumber: c
|
|
354
|
-
}),
|
|
396
|
+
}), e.recommendationConfigs.filters = r;
|
|
355
397
|
},
|
|
356
398
|
generateFilterQuery() {
|
|
357
399
|
return b(this.recommendationConfigs.filters);
|
|
@@ -375,29 +417,31 @@ const v = () => ({
|
|
|
375
417
|
},
|
|
376
418
|
async _doFetchProducts() {
|
|
377
419
|
var p;
|
|
378
|
-
const t = this.currentRecommendationId,
|
|
379
|
-
locale:
|
|
380
|
-
currency:
|
|
420
|
+
const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = S.find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
|
|
421
|
+
locale: r.language,
|
|
422
|
+
currency: r.currencySettings.value,
|
|
381
423
|
partnerName: o.partnerName,
|
|
382
|
-
size:
|
|
424
|
+
size: r.size,
|
|
383
425
|
details: !0,
|
|
384
426
|
campaignId: o.variationId
|
|
385
427
|
};
|
|
386
|
-
|
|
387
|
-
const l = parseInt(e.size) || 6;
|
|
428
|
+
r.strategy === "manualMerchandising" ? a.productId = r.productIds.slice(0, s).join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0);
|
|
388
429
|
let f;
|
|
389
430
|
try {
|
|
390
|
-
f = await h.fetchRecommendationProducts(i,
|
|
431
|
+
f = await h.fetchRecommendationProducts(i, a);
|
|
391
432
|
} catch {
|
|
392
433
|
f = [];
|
|
393
434
|
}
|
|
394
435
|
if (this.blockStates[t]) {
|
|
395
|
-
const
|
|
396
|
-
this.blockStates[t].recommendationProducts =
|
|
436
|
+
const l = f.length > 0 ? f : g(s);
|
|
437
|
+
l.length < s ? this.blockStates[t].recommendationProducts = [
|
|
438
|
+
...l,
|
|
439
|
+
...g(s - l.length)
|
|
440
|
+
] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
|
|
397
441
|
}
|
|
398
442
|
}
|
|
399
443
|
}
|
|
400
444
|
});
|
|
401
445
|
export {
|
|
402
|
-
|
|
446
|
+
_ as useRecommendationExtensionStore
|
|
403
447
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RecommendationBlockId as s } from "../../constants/blockIds.js";
|
|
2
|
-
import { ATTR_PRODUCT_ATTR as
|
|
2
|
+
import { ATTR_PRODUCT_ATTR as b, ATTR_PRODUCT_BUTTON as u, ATTR_PRODUCT_OMNIBUS_DISCOUNT as m, ATTR_PRODUCT_OMNIBUS_PRICE as h, ATTR_PRODUCT_OLD_PRICE as y, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_NAME as f, ATTR_PRODUCT_IMAGE as x } from "../../constants/selectors.js";
|
|
3
3
|
import { useRecommendationExtensionStore as _ } from "../../store/recommendation.js";
|
|
4
4
|
import { formatPrice as $ } from "../../utils/priceFormatter.js";
|
|
5
5
|
import { sanitizeImageUrl as C, CUSTOM_CELL_HTML as R } from "../utils.js";
|
|
@@ -15,7 +15,7 @@ function p() {
|
|
|
15
15
|
thousandSeparator: e.thousandSeparator
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function i(t, e = "price") {
|
|
19
19
|
const o = p(), n = t[e], d = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
|
|
20
20
|
return $({
|
|
21
21
|
price: d,
|
|
@@ -92,7 +92,7 @@ const I = {
|
|
|
92
92
|
align="center"
|
|
93
93
|
esd-extension-block-id="${s.PRICE}">
|
|
94
94
|
<p contenteditable="false" style="font-size: 16px; color: #333333;">
|
|
95
|
-
<strong>${
|
|
95
|
+
<strong>${i(t, "price")}</strong>
|
|
96
96
|
</p>
|
|
97
97
|
</td>
|
|
98
98
|
</tr>
|
|
@@ -116,7 +116,7 @@ const I = {
|
|
|
116
116
|
align="center"
|
|
117
117
|
esd-extension-block-id="${s.OLD_PRICE}">
|
|
118
118
|
<p contenteditable="false" style="font-size: 14px; color: #999999;">
|
|
119
|
-
<strong>${
|
|
119
|
+
<strong>${i(t, "original_price")}</strong>
|
|
120
120
|
</p>
|
|
121
121
|
</td>
|
|
122
122
|
</tr>
|
|
@@ -143,7 +143,7 @@ const I = {
|
|
|
143
143
|
esd-extension-block-id="${s.OMNIBUS_PRICE}">
|
|
144
144
|
<p contenteditable="false" style="font-size: 12px; color: #666666;">
|
|
145
145
|
<span class="omnibus-text-before">Lowest 30-day price: </span>
|
|
146
|
-
<span class="omnibus-price-value">${
|
|
146
|
+
<span class="omnibus-price-value">${i(t, "original_price")}</span>
|
|
147
147
|
<span class="omnibus-text-after"></span>
|
|
148
148
|
</p>
|
|
149
149
|
</td>
|
|
@@ -153,8 +153,8 @@ const I = {
|
|
|
153
153
|
</td>
|
|
154
154
|
`,
|
|
155
155
|
[m]: (t) => {
|
|
156
|
-
var
|
|
157
|
-
const e = p(), o = ((
|
|
156
|
+
var r, c;
|
|
157
|
+
const e = p(), o = ((r = t.original_price) == null ? void 0 : r[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((c = t.price) == null ? void 0 : c[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, d = o > 0 ? Math.round((o - n) / o * 100) : 0, g = d > 0 ? `-${d}%` : "0%";
|
|
158
158
|
return `
|
|
159
159
|
<td class="${l}" style="padding: ${a}; height: 100%;" valign="top">
|
|
160
160
|
<table
|
|
@@ -174,7 +174,7 @@ const I = {
|
|
|
174
174
|
esd-extension-block-id="${s.OMNIBUS_DISCOUNT}">
|
|
175
175
|
<p contenteditable="false" style="font-size: 12px; color: #666666;">
|
|
176
176
|
<span class="omnibus-text-before"></span>
|
|
177
|
-
<span class="omnibus-discount-value">${
|
|
177
|
+
<span class="omnibus-discount-value">${g}</span>
|
|
178
178
|
<span class="omnibus-text-after"></span>
|
|
179
179
|
</p>
|
|
180
180
|
</td>
|
|
@@ -210,7 +210,16 @@ const I = {
|
|
|
210
210
|
href="#"
|
|
211
211
|
class="es-button buy-button"
|
|
212
212
|
target="_blank"
|
|
213
|
-
style="
|
|
213
|
+
style="
|
|
214
|
+
color: rgb(56, 118, 29);
|
|
215
|
+
background: rgb(217, 234, 211);
|
|
216
|
+
font-family: arial, 'helvetica neue', helvetica, sans-serif;
|
|
217
|
+
font-size: 16px;
|
|
218
|
+
font-weight: normal;
|
|
219
|
+
line-height: 120%;
|
|
220
|
+
mso-border-alt: 10px solid rgb(217, 234, 211);
|
|
221
|
+
mso-padding-alt: 0;
|
|
222
|
+
">
|
|
214
223
|
Buy
|
|
215
224
|
</a>
|
|
216
225
|
</span>
|
|
@@ -240,7 +249,7 @@ const I = {
|
|
|
240
249
|
<tbody>
|
|
241
250
|
<tr valign="top">
|
|
242
251
|
<td
|
|
243
|
-
${
|
|
252
|
+
${b}="${t}"
|
|
244
253
|
class="esd-block-text product-custom-attribute es-p0t es-p0b es-p15l es-p15r"
|
|
245
254
|
align="center"
|
|
246
255
|
esd-extension-block-id="${s.CUSTOM_ATTRIBUTE}">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_PRODUCTS_PER_ROW as L } from "../../constants/layout.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { getDefaultProducts as E, createBlockTemplate as I, DEFAULTS as _, DEFAULT_CARD_COMPOSITION as S, spacer as b, buildElementRenderer as A, DEFAULT_CARD_VISIBILITY as f } from "../utils.js";
|
|
3
|
+
import { ATTRIBUTE_CELL_CLASS as w, DEFAULT_CELL_PADDING as D, gridElementRenderer as C } from "./elementRenderer.js";
|
|
4
4
|
const O = `
|
|
5
5
|
<tr class="recommendation-product-row">
|
|
6
6
|
<td>
|
|
@@ -27,8 +27,8 @@ const O = `
|
|
|
27
27
|
{-{-CELLS-}-}
|
|
28
28
|
</tr>
|
|
29
29
|
`;
|
|
30
|
-
function P(t, e, o, r =
|
|
31
|
-
const c = (100 / e).toFixed(2), i = e - t.length, l = `<td class="${
|
|
30
|
+
function P(t, e, o, r = S, n = {}) {
|
|
31
|
+
const c = (100 / e).toFixed(2), i = e - t.length, l = `<td class="${w}" style="padding: ${D};" width="${c}%"></td>`, d = i > 0 ? l.repeat(i) : "", a = A(o, r, n);
|
|
32
32
|
return r.filter((s) => a[s]).map((s) => {
|
|
33
33
|
const T = f[s] ?? !0, u = T ? "" : 'style="display: none;"', R = t.map((m) => a[s](m).replace("<td", `<td width="${c}%"`)).join("");
|
|
34
34
|
return g.replace("{-{-ATTR_TYPE-}-}", s).replace("{-{-VISIBILITY-}-}", T ? "1" : "0").replace("{-{-DISPLAY_STYLE-}-}", u).replace("{-{-CELLS-}-}", R + d);
|
|
@@ -46,15 +46,15 @@ function U(t, e, o, r, n = {}) {
|
|
|
46
46
|
r,
|
|
47
47
|
n
|
|
48
48
|
), p = O.replace("{-{-ATTRIBUTE_ROWS-}-}", a);
|
|
49
|
-
return d > 0 ?
|
|
49
|
+
return d > 0 ? b + p : p;
|
|
50
50
|
}).join("");
|
|
51
51
|
}
|
|
52
52
|
function h(t, e, o, r = {}) {
|
|
53
|
-
return U(t, e,
|
|
53
|
+
return U(t, e, C, o, r);
|
|
54
54
|
}
|
|
55
55
|
function F(t) {
|
|
56
|
-
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o =
|
|
57
|
-
return o.replace("{-{-TITLE-}-}",
|
|
56
|
+
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o = I("grid", e), r = E(), n = h(r, L);
|
|
57
|
+
return o.replace("{-{-TITLE-}-}", _.TITLE).replace("{-{-PRODUCT_ROWS-}-}", n).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
|
|
58
58
|
}
|
|
59
59
|
export {
|
|
60
60
|
F as getDefaultTemplate,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RecommendationBlockId as o } from "../../constants/blockIds.js";
|
|
2
|
-
import { ATTR_PRODUCT_ATTR as
|
|
2
|
+
import { ATTR_PRODUCT_ATTR as m, ATTR_PRODUCT_BUTTON as c, ATTR_PRODUCT_IMAGE as d, ATTR_PRODUCT_OMNIBUS_DISCOUNT as u, ATTR_PRODUCT_OMNIBUS_PRICE as g, ATTR_PRODUCT_OLD_PRICE as f, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_NAME as x } from "../../constants/selectors.js";
|
|
3
3
|
import { useRecommendationExtensionStore as _ } from "../../store/recommendation.js";
|
|
4
4
|
import { formatPrice as R } from "../../utils/priceFormatter.js";
|
|
5
|
-
import { sanitizeImageUrl as
|
|
5
|
+
import { sanitizeImageUrl as y, CUSTOM_CELL_HTML as C } from "../utils.js";
|
|
6
6
|
function p() {
|
|
7
7
|
const t = _(), { currencySettings: e } = t.recommendationConfigs;
|
|
8
8
|
return {
|
|
@@ -15,13 +15,13 @@ function p() {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
function s(t, e = "price") {
|
|
18
|
-
const n = p(),
|
|
18
|
+
const n = p(), a = t[e], r = (a == null ? void 0 : a[n.code]) ?? Object.values(a ?? {})[0] ?? 0;
|
|
19
19
|
return R({
|
|
20
|
-
price:
|
|
20
|
+
price: r,
|
|
21
21
|
currency: n
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
-
const
|
|
24
|
+
const U = {
|
|
25
25
|
/**
|
|
26
26
|
* Image cell - left column (120px fixed width)
|
|
27
27
|
* Has recommendation-attribute-row class and data attributes for Card Composition control
|
|
@@ -37,7 +37,7 @@ const I = {
|
|
|
37
37
|
valign="middle">
|
|
38
38
|
<a target="_blank" href="${t.url}">
|
|
39
39
|
<img
|
|
40
|
-
src="${
|
|
40
|
+
src="${y(t.image_url)}"
|
|
41
41
|
alt="${t.name}"
|
|
42
42
|
style="display: block; max-width: 100%; height: auto;"
|
|
43
43
|
class="adapt-img product-image">
|
|
@@ -113,9 +113,9 @@ const I = {
|
|
|
113
113
|
/**
|
|
114
114
|
* Omnibus discount element - row for info cell table
|
|
115
115
|
*/
|
|
116
|
-
[
|
|
117
|
-
var i,
|
|
118
|
-
const e = p(), n = ((i = t.original_price) == null ? void 0 : i[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0,
|
|
116
|
+
[u]: (t) => {
|
|
117
|
+
var i, l;
|
|
118
|
+
const e = p(), n = ((i = t.original_price) == null ? void 0 : i[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, a = ((l = t.price) == null ? void 0 : l[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, r = n > 0 ? Math.round((n - a) / n * 100) : 0, b = r > 0 ? `-${r}%` : "0%";
|
|
119
119
|
return `
|
|
120
120
|
<tr>
|
|
121
121
|
<td
|
|
@@ -137,12 +137,12 @@ const I = {
|
|
|
137
137
|
* Button cell - right column (100px fixed width)
|
|
138
138
|
* Has recommendation-attribute-row class and data attributes for Card Composition control
|
|
139
139
|
*/
|
|
140
|
-
[
|
|
140
|
+
[c]: (t) => `
|
|
141
141
|
<td
|
|
142
142
|
width="100"
|
|
143
143
|
class="esd-block-button button-cell recommendation-attribute-row product-button es-p5l es-p5r"
|
|
144
144
|
esd-extension-block-id="${o.BUTTON}"
|
|
145
|
-
data-attribute-type="${
|
|
145
|
+
data-attribute-type="${c}"
|
|
146
146
|
data-visibility="1"
|
|
147
147
|
align="center"
|
|
148
148
|
valign="middle">
|
|
@@ -157,7 +157,17 @@ const I = {
|
|
|
157
157
|
href="${t.url}"
|
|
158
158
|
target="_blank"
|
|
159
159
|
class="es-button buy-button"
|
|
160
|
-
style="
|
|
160
|
+
style="
|
|
161
|
+
color: rgb(56, 118, 29);
|
|
162
|
+
background: rgb(217, 234, 211);
|
|
163
|
+
font-family: arial, 'helvetica neue', helvetica, sans-serif;
|
|
164
|
+
font-size: 16px;
|
|
165
|
+
font-weight: normal;
|
|
166
|
+
line-height: 120%;
|
|
167
|
+
padding: 5px 30px;
|
|
168
|
+
mso-border-alt: 10px solid rgb(217, 234, 211);
|
|
169
|
+
mso-padding-alt: 0;
|
|
170
|
+
">
|
|
161
171
|
Buy
|
|
162
172
|
</a>
|
|
163
173
|
</span>
|
|
@@ -169,10 +179,10 @@ const I = {
|
|
|
169
179
|
* @param productAttrValue - Resolved product-attr value (e.g., "brand" for default, "product_attribute.rating_star" for custom)
|
|
170
180
|
* @param content - Display content for the cell
|
|
171
181
|
*/
|
|
172
|
-
[
|
|
182
|
+
[C]: (t, e) => `
|
|
173
183
|
<tr>
|
|
174
184
|
<td
|
|
175
|
-
${
|
|
185
|
+
${m}="${t}"
|
|
176
186
|
class="esd-block-text product-custom-attribute"
|
|
177
187
|
esd-extension-block-id="${o.CUSTOM_ATTRIBUTE}"
|
|
178
188
|
align="left">
|
|
@@ -182,5 +192,5 @@ const I = {
|
|
|
182
192
|
`
|
|
183
193
|
};
|
|
184
194
|
export {
|
|
185
|
-
|
|
195
|
+
U as listElementRenderer
|
|
186
196
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ATTR_PRODUCT_IMAGE as
|
|
2
|
-
import { DEFAULT_CARD_COMPOSITION as
|
|
3
|
-
import { listElementRenderer as
|
|
4
|
-
function
|
|
1
|
+
import { ATTR_PRODUCT_IMAGE as a, ATTR_PRODUCT_BUTTON as d } from "../../constants/selectors.js";
|
|
2
|
+
import { DEFAULT_CARD_COMPOSITION as b, spacer as m, buildElementRenderer as C, DEFAULT_CARD_VISIBILITY as T } from "../utils.js";
|
|
3
|
+
import { listElementRenderer as f } from "./elementRenderer.js";
|
|
4
|
+
function R(r, n, l) {
|
|
5
5
|
const t = l ? "" : ' style="display: none;"', o = r.replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
6
6
|
return `<tr
|
|
7
7
|
class="recommendation-attribute-row"
|
|
@@ -26,26 +26,26 @@ const y = `
|
|
|
26
26
|
</td>
|
|
27
27
|
</tr>
|
|
28
28
|
`;
|
|
29
|
-
function O(r, n =
|
|
30
|
-
const t =
|
|
29
|
+
function O(r, n = b, l = {}) {
|
|
30
|
+
const t = C(f, n, l), o = t[a](r), c = `
|
|
31
31
|
<td class="product-info-cell" valign="middle" style="padding: 15px;">
|
|
32
|
-
<table cellpadding="0" cellspacing="0" role="presentation" width="100%">
|
|
32
|
+
<table cellpadding="0" cellspacing="0" role="presentation" width="100%" style="table-layout: fixed;">
|
|
33
33
|
<tbody>
|
|
34
|
-
${n.filter((e) => e !==
|
|
34
|
+
${n.filter((e) => e !== a && e !== d).filter((e) => t[e]).map((e) => {
|
|
35
35
|
const u = T[e] ?? !0;
|
|
36
|
-
return
|
|
36
|
+
return R(t[e](r), e, u);
|
|
37
37
|
}).join(`
|
|
38
38
|
`)}
|
|
39
39
|
</tbody>
|
|
40
40
|
</table>
|
|
41
41
|
</td>
|
|
42
|
-
`, s = t[
|
|
42
|
+
`, s = t[d](r), p = o + c + s;
|
|
43
43
|
return y.replace("{-{-PRODUCT_CONTENT-}-}", p);
|
|
44
44
|
}
|
|
45
45
|
function D(r, n, l = {}) {
|
|
46
46
|
return r.map((t, o) => {
|
|
47
47
|
const i = O(t, n, l);
|
|
48
|
-
return o > 0 ?
|
|
48
|
+
return o > 0 ? m + i : i;
|
|
49
49
|
}).join("");
|
|
50
50
|
}
|
|
51
51
|
export {
|