@useinsider/guido 2.1.0-beta.7d0f92a → 2.1.0-beta.7ffef92

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.
Files changed (62) hide show
  1. package/README.md +36 -0
  2. package/dist/@types/config/schemas.js +70 -65
  3. package/dist/components/Guido.vue.js +1 -1
  4. package/dist/components/Guido.vue2.js +69 -58
  5. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +11 -13
  6. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +55 -24
  7. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +3 -3
  8. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +34 -21
  9. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +9 -9
  10. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +44 -35
  11. package/dist/composables/useBlocksConfig.js +26 -16
  12. package/dist/composables/useHtmlValidator.js +107 -119
  13. package/dist/config/compiler/utils/recommendationCompilerUtils.js +27 -22
  14. package/dist/config/migrator/itemsBlockMigrator.js +101 -97
  15. package/dist/enums/defaults.js +8 -4
  16. package/dist/extensions/Blocks/Recommendation/block.js +26 -23
  17. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +27 -26
  18. package/dist/extensions/Blocks/Recommendation/constants/layout.js +6 -4
  19. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +12 -10
  20. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +124 -72
  21. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +87 -37
  22. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +138 -117
  23. package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +21 -0
  24. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +179 -133
  25. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +25 -30
  26. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +27 -30
  27. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +20 -25
  28. package/dist/extensions/Blocks/Recommendation/templates/utils.js +43 -31
  29. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
  30. package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +29 -0
  31. package/dist/extensions/ModulesTabIcons/extension.js +17 -0
  32. package/dist/guido.css +1 -1
  33. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +257 -187
  34. package/dist/services/recommendationApi.js +11 -9
  35. package/dist/services/stripoApi.js +20 -17
  36. package/dist/src/@types/config/schemas.d.ts +8 -0
  37. package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +1 -0
  38. package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +15 -1
  39. package/dist/src/composables/useConfig.d.ts +4 -0
  40. package/dist/src/enums/defaults.d.ts +4 -0
  41. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
  42. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -0
  43. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +4 -0
  44. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +17 -1
  45. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +22 -4
  46. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -2
  47. package/dist/src/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.d.ts +29 -0
  48. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +25 -2
  49. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +1 -1
  50. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +2 -0
  51. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +12 -3
  52. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
  53. package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +15 -0
  54. package/dist/src/extensions/ModulesTabIcons/extension.d.ts +2 -0
  55. package/dist/src/stores/config.d.ts +36 -0
  56. package/dist/static/styles/components/notification.css.js +1 -0
  57. package/dist/static/styles/components/version-history.css.js +10 -2
  58. package/dist/static/styles/components/wide-panel.css.js +18 -2
  59. package/dist/static/styles/customEditorStyle.css.js +10 -9
  60. package/dist/static/templates/empty/index.html.js +74 -0
  61. package/dist/static/templates/empty/style.css.js +779 -0
  62. package/package.json +1 -1
@@ -1,13 +1,15 @@
1
- import { RecommendationFeedSourceMaps as u, PriceAttributes as g } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as S } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as p } from "../../../../stores/config.js";
4
- import { defineStore as b } from "pinia";
5
- import { DEFAULT_CARDS_IN_ROW as I } from "../constants/layout.js";
6
- import { generateCompleteFilterQuery as d } from "../utils/filterUtil.js";
7
- const l = S();
8
- function f() {
1
+ import { RecommendationFeedSourceMaps as d, getOperatorOptions as S, PriceAttributes as p } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as b } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as I } from "../../../../stores/config.js";
4
+ import { defineStore as R } from "pinia";
5
+ import { DEFAULT_CARDS_IN_ROW as k } from "../constants/layout.js";
6
+ import { getDefaultProducts as C } from "../templates/utils.js";
7
+ import { generateCompleteFilterQuery as f } from "../utils/filterUtil.js";
8
+ import { isFilterValid as y } from "../validation/filterSchema.js";
9
+ const m = b();
10
+ function h() {
9
11
  return {
10
- cardsInRow: I,
12
+ cardsInRow: k,
11
13
  currencySettings: {
12
14
  name: "USD",
13
15
  value: "USD",
@@ -20,7 +22,7 @@ function f() {
20
22
  filters: [],
21
23
  productIds: [],
22
24
  id: 1,
23
- language: "tr_TR",
25
+ language: "en_US",
24
26
  orientation: "grid",
25
27
  recommendedProducts: [],
26
28
  sendProductRequestFlag: !1,
@@ -31,16 +33,18 @@ function f() {
31
33
  size: "6"
32
34
  };
33
35
  }
34
- function R() {
36
+ function G() {
35
37
  return {
36
- recommendationConfigs: f(),
38
+ recommendationConfigs: h(),
37
39
  recommendationProducts: [],
38
40
  filterStatus: !1,
39
41
  filterSelectionDrawerStatus: !1,
40
- filterGroup: 1
42
+ filterGroup: 1,
43
+ isInitialized: !1,
44
+ filterSnapshot: null
41
45
  };
42
46
  }
43
- const k = () => ({
47
+ const F = () => ({
44
48
  recommendationCampaignUrls: {},
45
49
  activePredictiveAlgorithms: [],
46
50
  languages: {},
@@ -49,8 +53,8 @@ const k = () => ({
49
53
  blockStates: {},
50
54
  currentRecommendationId: null,
51
55
  configVersion: 0
52
- }), D = b("guidoRecommendationExtension", {
53
- state: () => k(),
56
+ }), V = R("guidoRecommendationExtension", {
57
+ state: () => F(),
54
58
  getters: {
55
59
  // ====================================================================
56
60
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -59,32 +63,32 @@ const k = () => ({
59
63
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationConfigs
60
64
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
61
65
  */
62
- recommendationConfigs(e) {
63
- return e.currentRecommendationId !== null && e.blockStates[e.currentRecommendationId] ? e.blockStates[e.currentRecommendationId].recommendationConfigs : f();
66
+ recommendationConfigs(t) {
67
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : h();
64
68
  },
65
69
  /**
66
70
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
67
71
  */
68
- recommendationProducts(e) {
69
- return e.currentRecommendationId !== null && e.blockStates[e.currentRecommendationId] ? e.blockStates[e.currentRecommendationId].recommendationProducts : [];
72
+ recommendationProducts(t) {
73
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationProducts : [];
70
74
  },
71
75
  /**
72
76
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterSelectionDrawerStatus
73
77
  */
74
- filterSelectionDrawerStatus(e) {
75
- return e.currentRecommendationId !== null && e.blockStates[e.currentRecommendationId] ? e.blockStates[e.currentRecommendationId].filterSelectionDrawerStatus : !1;
78
+ filterSelectionDrawerStatus(t) {
79
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
76
80
  },
77
81
  /**
78
82
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
79
83
  */
80
- filterStatus(e) {
81
- return e.currentRecommendationId !== null && e.blockStates[e.currentRecommendationId] ? e.blockStates[e.currentRecommendationId].filterStatus : !1;
84
+ filterStatus(t) {
85
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterStatus : !1;
82
86
  },
83
87
  /**
84
88
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterGroup
85
89
  */
86
- filterGroup(e) {
87
- return e.currentRecommendationId !== null && e.blockStates[e.currentRecommendationId] ? e.blockStates[e.currentRecommendationId].filterGroup : 1;
90
+ filterGroup(t) {
91
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterGroup : 1;
88
92
  },
89
93
  // ====================================================================
90
94
  // Existing Getters (now reading through proxy)
@@ -92,40 +96,48 @@ const k = () => ({
92
96
  hasFilters() {
93
97
  return !!this.recommendationConfigs.filters.length;
94
98
  },
99
+ hasValidFilters() {
100
+ const { filters: t } = this.recommendationConfigs;
101
+ return t.length ? t.every((r) => r.isValid) : !1;
102
+ },
95
103
  getFilterGroupCount() {
96
- const { filters: e } = this.recommendationConfigs;
97
- return e.length && e[e.length - 1].filterGroup || 0;
104
+ const { filters: t } = this.recommendationConfigs;
105
+ return t.length ? new Set(t.map((r) => r.filterGroup)).size : 0;
106
+ },
107
+ getUniqueFilterGroups() {
108
+ const { filters: t } = this.recommendationConfigs;
109
+ return [...new Set(t.map((r) => r.filterGroup))].sort((r, e) => r - e);
98
110
  },
99
- getActivePredictiveAlgorithms: (e) => {
111
+ getActivePredictiveAlgorithms: (t) => {
100
112
  const r = [];
101
- return e.activePredictiveAlgorithms.forEach((t) => {
102
- r.push(...u.filter((n) => n.id === t));
103
- }), r.map((t) => ({
104
- text: t.name,
105
- value: t.key
113
+ return t.activePredictiveAlgorithms.forEach((e) => {
114
+ r.push(...d.filter((n) => n.id === e));
115
+ }), r.map((e) => ({
116
+ text: e.name,
117
+ value: e.key
106
118
  }));
107
119
  },
108
- getLanguages: (e) => Object.entries(e.languages).map(([r, t]) => ({
109
- text: t,
120
+ getLanguages: (t) => Object.entries(t.languages).map(([r, e]) => ({
121
+ text: e,
110
122
  value: r
111
123
  })),
112
- getCurrencySymbolList: (e) => e.currencyList.map((r) => ({
124
+ getCurrencySymbolList: (t) => t.currencyList.map((r) => ({
113
125
  text: r.text,
114
126
  value: r.text
115
127
  })),
116
128
  getFilterList() {
117
- return Object.values(this.filterList).map((e) => {
118
- const r = e.type === "defaultAttribute", t = g.includes(e.attributeName);
119
- let n = r ? e.attributeName : `product_attributes.${e.attributeName}`;
120
- return n = t ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
121
- text: e.displayName,
129
+ return Object.values(this.filterList).map((t) => {
130
+ const r = t.type === "defaultAttribute", e = p.includes(t.attributeName);
131
+ let n = r ? t.attributeName : `product_attributes.${t.attributeName}`;
132
+ return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
133
+ text: t.displayName,
122
134
  value: n,
123
- type: e.attributeType
135
+ type: t.attributeType
124
136
  };
125
137
  });
126
138
  },
127
139
  getSelectedFilterGroup() {
128
- return (e) => [...this.recommendationConfigs.filters].filter((r) => r.filterGroup === e);
140
+ return (t) => [...this.recommendationConfigs.filters].filter((r) => r.filterGroup === t);
129
141
  }
130
142
  },
131
143
  actions: {
@@ -136,69 +148,99 @@ const k = () => ({
136
148
  * Sets the currently active block ID.
137
149
  * Creates a new entry in blockStates if one doesn't exist.
138
150
  */
139
- setCurrentBlock(e) {
140
- this.blockStates[e] || (this.blockStates = {
151
+ setCurrentBlock(t) {
152
+ this.blockStates[t] || (this.blockStates = {
141
153
  ...this.blockStates,
142
- [e]: R()
143
- }), this.currentRecommendationId = e;
154
+ [t]: G()
155
+ }), this.currentRecommendationId = t;
144
156
  },
145
157
  /**
146
158
  * Removes a block's state from the store.
147
159
  * Resets currentRecommendationId if it was the deleted block.
148
160
  */
149
- removeBlockState(e) {
161
+ removeBlockState(t) {
150
162
  const r = { ...this.blockStates };
151
- if (delete r[e], this.blockStates = r, this.currentRecommendationId === e) {
152
- const t = Object.keys(this.blockStates).map(Number);
153
- this.currentRecommendationId = t.length > 0 ? t[0] : null;
163
+ if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
164
+ const e = Object.keys(this.blockStates).map(Number);
165
+ this.currentRecommendationId = e.length > 0 ? e[0] : null;
154
166
  }
155
167
  },
168
+ /**
169
+ * Marks a block as initialized (initial API data has been fetched).
170
+ * Automatically cleaned up when removeBlockState deletes the block entry.
171
+ */
172
+ markBlockInitialized(t) {
173
+ this.blockStates[t] && (this.blockStates[t].isInitialized = !0);
174
+ },
156
175
  /**
157
176
  * Patches the current block's recommendationConfigs.
158
177
  * Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
159
178
  */
160
- patchCurrentBlockConfig(e, r = {}) {
179
+ patchCurrentBlockConfig(t, r = {}) {
161
180
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
162
181
  return;
163
- const t = this.blockStates[this.currentRecommendationId];
164
- t.recommendationConfigs = {
165
- ...t.recommendationConfigs,
166
- ...e,
182
+ const e = this.blockStates[this.currentRecommendationId];
183
+ e.recommendationConfigs = {
184
+ ...e.recommendationConfigs,
185
+ ...t,
167
186
  currencySettings: {
168
- ...t.recommendationConfigs.currencySettings,
169
- ...e.currencySettings || {}
187
+ ...e.recommendationConfigs.currencySettings,
188
+ ...t.currencySettings || {}
170
189
  }
171
190
  };
172
191
  const { triggerRefetch: n = !0 } = r;
173
192
  n && this.configVersion++;
174
193
  },
175
194
  /**
176
- * Opens the filter selection drawer for the current block.
177
- * If no filters exist, initializes with a default empty filter
178
- * so the user has a starting point for input.
195
+ * Creates a filter with the first available attribute and operator pre-selected.
179
196
  */
180
- openFilterDrawer() {
181
- if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
182
- return;
183
- const e = this.blockStates[this.currentRecommendationId];
184
- e.recommendationConfigs.filters.length || (e.recommendationConfigs.filters = [{
197
+ createDefaultFilter(t, r) {
198
+ const [e] = this.getFilterList, [n] = S(e == null ? void 0 : e.type);
199
+ return {
185
200
  type: "standardFilter",
186
- attribute: "",
187
- operatorReplace: "",
188
- operator: "",
201
+ attribute: (e == null ? void 0 : e.value) ?? "",
202
+ operator: (n == null ? void 0 : n.value) ?? "",
189
203
  innerGroupOperator: "*",
190
204
  outerGroupOperator: "*",
191
- filterNumber: 1,
192
- filterGroup: 1,
205
+ filterNumber: r,
206
+ filterGroup: t,
193
207
  isValid: !1,
194
208
  value: ""
195
- }]), e.filterSelectionDrawerStatus = !0;
209
+ };
196
210
  },
197
211
  /**
198
- * Closes the filter selection drawer for the current block
212
+ * Opens the filter selection drawer for the current block.
213
+ * Saves a snapshot of current filters for cancel/revert.
214
+ * If no filters exist, initializes with a default filter
215
+ * so the user has a starting point for input.
216
+ */
217
+ openFilterDrawer() {
218
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
219
+ return;
220
+ const t = this.blockStates[this.currentRecommendationId];
221
+ t.filterSnapshot = JSON.parse(
222
+ JSON.stringify(t.recommendationConfigs.filters)
223
+ ), t.recommendationConfigs.filters.length || (t.recommendationConfigs.filters = [this.createDefaultFilter(1, 1)]), t.filterSelectionDrawerStatus = !0;
224
+ },
225
+ /**
226
+ * Closes the filter selection drawer for the current block.
227
+ * Called after successful apply — discards the snapshot.
199
228
  */
200
229
  closeFilterDrawer() {
201
- this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].filterSelectionDrawerStatus = !1);
230
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
231
+ return;
232
+ const t = this.blockStates[this.currentRecommendationId];
233
+ t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
234
+ },
235
+ /**
236
+ * Cancels the filter selection drawer and reverts filters
237
+ * to the snapshot taken when the drawer was opened.
238
+ */
239
+ cancelFilterDrawer() {
240
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
241
+ return;
242
+ const t = this.blockStates[this.currentRecommendationId];
243
+ t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
202
244
  },
203
245
  // ====================================================================
204
246
  // Shared Data Fetching (fetched once, used by all blocks)
@@ -207,98 +249,102 @@ const k = () => ({
207
249
  if (this.activePredictiveAlgorithms.length)
208
250
  return;
209
251
  const {
210
- activePredictiveAlgorithms: e,
252
+ activePredictiveAlgorithms: t,
211
253
  languages: r,
212
- currencies: t
213
- } = await l.fetchRecommendationCreateData();
214
- this.activePredictiveAlgorithms = e, this.languages = r;
215
- const [n] = t, o = n.value.includes(".") ? n.value.split(".")[1] : n.value;
216
- if (this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
217
- const i = this.blockStates[this.currentRecommendationId];
218
- i.recommendationConfigs.currencySettings.name = n.text, i.recommendationConfigs.currencySettings.value = o, i.filterStatus = !!i.recommendationConfigs.filters.length;
254
+ currencies: e
255
+ } = await m.fetchRecommendationCreateData();
256
+ if (this.activePredictiveAlgorithms = t, this.languages = r, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
257
+ const n = this.blockStates[this.currentRecommendationId];
258
+ n.filterStatus = !!n.recommendationConfigs.filters.length;
219
259
  }
220
- this.currencyList = t;
260
+ this.currencyList = e;
221
261
  },
222
262
  async fetchRecommendationFilters() {
223
- const e = await l.fetchRecommendationFilters();
224
- this.filterList = e;
263
+ const t = await m.fetchRecommendationFilters();
264
+ this.filterList = t;
225
265
  },
226
266
  // ====================================================================
227
267
  // Per-Block Filter Actions
228
268
  // ====================================================================
229
- addFilterGroup(e) {
230
- this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || this.blockStates[this.currentRecommendationId].recommendationConfigs.filters.push({
231
- type: "standardFilter",
232
- attribute: "",
233
- operatorReplace: "",
234
- operator: "",
235
- innerGroupOperator: "",
236
- outerGroupOperator: "",
237
- value: "",
238
- filterNumber: 1,
239
- isValid: !0,
240
- filterGroup: e
241
- });
269
+ addFilterGroup(t) {
270
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || this.blockStates[this.currentRecommendationId].recommendationConfigs.filters.push(
271
+ this.createDefaultFilter(t, 1)
272
+ );
273
+ },
274
+ deleteFilterGroup(t) {
275
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
276
+ return;
277
+ const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(e.map((i) => i.filterGroup))].sort((i, o) => i - o), s = new Map(n.map((i, o) => [i, o + 1]));
278
+ r.recommendationConfigs.filters = e.map((i) => ({
279
+ ...i,
280
+ filterGroup: s.get(i.filterGroup) ?? i.filterGroup
281
+ }));
242
282
  },
243
- updateFilter(e) {
283
+ updateFilter(t) {
244
284
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
245
285
  return;
246
- const r = this.blockStates[this.currentRecommendationId], t = r.recommendationConfigs.filters.findIndex((n) => n.filterNumber === e.filterNumber && n.filterGroup === e.filterGroup);
247
- if (t !== -1) {
286
+ const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
287
+ if (e !== -1) {
248
288
  const n = [...r.recommendationConfigs.filters];
249
- n[t] = e, e.value.length && e.operator && e.attribute && e.innerGroupOperator && e.outerGroupOperator ? n[t].isValid = !0 : n[t].isValid = !1, r.recommendationConfigs.filters = n;
289
+ n[e] = {
290
+ ...t,
291
+ isValid: y(t)
292
+ }, r.recommendationConfigs.filters = n;
250
293
  }
251
294
  },
252
- deleteFilter(e) {
295
+ deleteFilter(t) {
253
296
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
254
297
  return;
255
- const r = this.blockStates[this.currentRecommendationId], t = [...r.recommendationConfigs.filters].findIndex((n) => n.filterNumber === e.filterNumber && n.filterGroup === e.filterGroup);
256
- if (t !== -1) {
298
+ const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
299
+ if (e !== -1) {
257
300
  const n = [...r.recommendationConfigs.filters];
258
- n.splice(t, 1), r.recommendationConfigs.filters = n;
301
+ n.splice(e, 1), r.recommendationConfigs.filters = n;
259
302
  }
260
303
  },
261
- addFilter(e) {
304
+ addFilter(t) {
262
305
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
263
306
  return;
264
- const r = this.blockStates[this.currentRecommendationId], t = [...r.recommendationConfigs.filters], o = t.filter(
265
- (c) => c.filterGroup === e.filterGroup
266
- ).length + 1, i = t.findLastIndex((c) => c.filterGroup === e.filterGroup);
267
- i !== -1 ? t.splice(i + 1, 0, {
268
- ...e,
269
- filterNumber: o
270
- }) : t.push({
271
- ...e,
272
- filterNumber: o
273
- }), r.recommendationConfigs.filters = t;
307
+ const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters], s = e.filter(
308
+ (o) => o.filterGroup === t.filterGroup
309
+ ).length + 1, i = e.findLastIndex((o) => o.filterGroup === t.filterGroup);
310
+ i !== -1 ? e.splice(i + 1, 0, {
311
+ ...t,
312
+ filterNumber: s
313
+ }) : e.push({
314
+ ...t,
315
+ filterNumber: s
316
+ }), r.recommendationConfigs.filters = e;
274
317
  },
275
318
  generateFilterQuery() {
276
- return d(this.recommendationConfigs.filters);
319
+ return f(this.recommendationConfigs.filters);
277
320
  },
278
321
  // ====================================================================
279
322
  // Per-Block Product Fetching
280
323
  // ====================================================================
281
324
  async fetchRecommendationProducts() {
282
- var m;
325
+ var u;
283
326
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
284
327
  return;
285
- const e = this.currentRecommendationId, r = this.blockStates[e], { recommendationConfigs: t } = r, n = t.filters.filter((a) => a.isValid), o = d(n), i = ((m = u.find((a) => a.key === t.strategy)) == null ? void 0 : m.path) || "", c = p(), s = {
286
- locale: t.language,
287
- currency: t.currencySettings.value,
288
- partnerName: c.partnerName,
289
- size: t.size,
328
+ const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((l) => l.isValid), s = f(n), i = ((u = d.find((l) => l.key === e.strategy)) == null ? void 0 : u.path) || "", o = I(), c = {
329
+ locale: e.language,
330
+ currency: e.currencySettings.value,
331
+ partnerName: o.partnerName,
332
+ size: e.size,
290
333
  details: !0,
291
- campaignId: c.variationId
334
+ campaignId: o.variationId
292
335
  };
293
- t.strategy === "manualMerchandising" ? s.productId = t.productIds.join(",") : t.strategy === "similarViewed" && (s.productId = "{itemId}"), o && (s.filter = o), t.shuffleProducts && (s.shuffle = !0);
294
- const h = await l.fetchRecommendationProducts(
295
- i,
296
- s
297
- );
298
- this.blockStates[e] && (this.blockStates[e].recommendationProducts = h);
336
+ e.strategy === "manualMerchandising" ? c.productId = e.productIds.join(",") : e.strategy === "similarViewed" && (c.productId = "{itemId}"), s && (c.filter = s), e.shuffleProducts && (c.shuffle = !0);
337
+ const g = parseInt(e.size) || 6;
338
+ let a;
339
+ try {
340
+ a = await m.fetchRecommendationProducts(i, c);
341
+ } catch {
342
+ a = [];
343
+ }
344
+ this.blockStates[t] && (this.blockStates[t].recommendationProducts = a.length > 0 ? a : C(g));
299
345
  }
300
346
  }
301
347
  });
302
348
  export {
303
- D as useRecommendationExtensionStore
349
+ V as useRecommendationExtensionStore
304
350
  };
@@ -3,7 +3,7 @@ import { ATTR_PRODUCT_BUTTON as b, ATTR_PRODUCT_OMNIBUS_DISCOUNT as u, ATTR_PROD
3
3
  import { useRecommendationExtensionStore as T } from "../../store/recommendation.js";
4
4
  import { formatPrice as _ } from "../../utils/priceFormatter.js";
5
5
  import { sanitizeImageUrl as $ } from "../utils.js";
6
- const o = "0 5px", a = "attribute-cell";
6
+ const a = "0 5px", o = "attribute-cell";
7
7
  function p() {
8
8
  const t = T(), { currencySettings: e } = t.recommendationConfigs;
9
9
  return {
@@ -15,16 +15,16 @@ function p() {
15
15
  thousandSeparator: e.thousandSeparator
16
16
  };
17
17
  }
18
- function r(t, e = "price") {
19
- const n = p(), l = t[e], i = (l == null ? void 0 : l[n.code]) ?? Object.values(l ?? {})[0] ?? 0;
18
+ function c(t, e = "price") {
19
+ const n = p(), l = t[e], r = (l == null ? void 0 : l[n.code]) ?? Object.values(l ?? {})[0] ?? 0;
20
20
  return _({
21
- price: i,
21
+ price: r,
22
22
  currency: n
23
23
  });
24
24
  }
25
25
  const P = {
26
26
  [x]: (t) => `
27
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
27
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
28
28
  <table
29
29
  class="product-card-segment"
30
30
  width="100%"
@@ -38,18 +38,13 @@ const P = {
38
38
  class="esd-block-image product-image"
39
39
  align="center"
40
40
  esd-extension-block-id="${s.IMAGE}">
41
- <div style="position: relative; width: 100%; padding-bottom: 100%; overflow: hidden;">
42
- <a
43
- target="_blank"
44
- href="${t.url}"
45
- style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
46
- <img
47
- src="${$(t.image_url)}"
48
- alt="${t.name}"
49
- style="max-width: 100%; max-height: 100%; object-fit: contain; display: block;"
50
- class="adapt-img">
51
- </a>
52
- </div>
41
+ <a target="_blank" href="${t.url}">
42
+ <img
43
+ src="${$(t.image_url)}"
44
+ alt="${t.name}"
45
+ style="display: block; max-width: 100%; height: auto;"
46
+ class="adapt-img">
47
+ </a>
53
48
  </td>
54
49
  </tr>
55
50
  </tbody>
@@ -57,7 +52,7 @@ const P = {
57
52
  </td>
58
53
  `,
59
54
  [f]: (t) => `
60
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="middle">
55
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="middle">
61
56
  <table
62
57
  class="product-card-segment"
63
58
  width="100%"
@@ -82,7 +77,7 @@ const P = {
82
77
  </td>
83
78
  `,
84
79
  [y]: (t) => `
85
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
80
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
86
81
  <table
87
82
  class="product-card-segment"
88
83
  width="100%"
@@ -97,7 +92,7 @@ const P = {
97
92
  align="center"
98
93
  esd-extension-block-id="${s.PRICE}">
99
94
  <p contenteditable="false" style="font-size: 16px; color: #333333;">
100
- <strong>${r(t, "price")}</strong>
95
+ <strong>${c(t, "price")}</strong>
101
96
  </p>
102
97
  </td>
103
98
  </tr>
@@ -106,7 +101,7 @@ const P = {
106
101
  </td>
107
102
  `,
108
103
  [h]: (t) => `
109
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
104
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
110
105
  <table
111
106
  class="product-card-segment"
112
107
  width="100%"
@@ -121,7 +116,7 @@ const P = {
121
116
  align="center"
122
117
  esd-extension-block-id="${s.OLD_PRICE}">
123
118
  <p contenteditable="false" style="font-size: 14px; color: #999999;">
124
- <strong>${r(t, "original_price")}</strong>
119
+ <strong>${c(t, "original_price")}</strong>
125
120
  </p>
126
121
  </td>
127
122
  </tr>
@@ -130,7 +125,7 @@ const P = {
130
125
  </td>
131
126
  `,
132
127
  [m]: (t) => `
133
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
128
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
134
129
  <table
135
130
  class="product-card-segment"
136
131
  width="100%"
@@ -148,7 +143,7 @@ const P = {
148
143
  esd-extension-block-id="${s.OMNIBUS_PRICE}">
149
144
  <p style="font-size: 12px; color: #666666;">
150
145
  <span class="omnibus-text-before">Lowest 30-day price: </span>
151
- <span class="omnibus-price-value">${r(t, "original_price")}</span>
146
+ <span class="omnibus-price-value">${c(t, "original_price")}</span>
152
147
  <span class="omnibus-text-after"></span>
153
148
  </p>
154
149
  </td>
@@ -158,10 +153,10 @@ const P = {
158
153
  </td>
159
154
  `,
160
155
  [u]: (t) => {
161
- var d, c;
162
- const e = p(), n = ((d = t.original_price) == null ? void 0 : d[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, l = ((c = t.price) == null ? void 0 : c[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, i = n > 0 ? Math.round((n - l) / n * 100) : 0, g = i > 0 ? `-${i}%` : "0%";
156
+ var d, i;
157
+ const e = p(), n = ((d = t.original_price) == null ? void 0 : d[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, l = ((i = t.price) == null ? void 0 : i[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, r = n > 0 ? Math.round((n - l) / n * 100) : 0, g = r > 0 ? `-${r}%` : "0%";
163
158
  return `
164
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
159
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
165
160
  <table
166
161
  class="product-card-segment"
167
162
  width="100%"
@@ -190,7 +185,7 @@ const P = {
190
185
  `;
191
186
  },
192
187
  [b]: () => `
193
- <td class="${a}" style="padding: ${o}; height: 100%;" valign="top">
188
+ <td class="${o}" style="padding: ${a}; height: 100%;" valign="top">
194
189
  <table
195
190
  class="product-card-segment"
196
191
  width="100%"
@@ -227,7 +222,7 @@ const P = {
227
222
  `
228
223
  };
229
224
  export {
230
- a as ATTRIBUTE_CELL_CLASS,
231
- o as DEFAULT_CELL_PADDING,
225
+ o as ATTRIBUTE_CELL_CLASS,
226
+ a as DEFAULT_CELL_PADDING,
232
227
  P as gridElementRenderer
233
228
  };