@useinsider/guido 2.1.0-beta.216503 → 2.1.0-beta.29e4650
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/extensions/Blocks/Recommendation/block.js +20 -18
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +42 -42
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +114 -102
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +4 -4
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +19 -23
- package/dist/services/recommendationApi.js +11 -11
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
var u = Object.defineProperty;
|
|
2
|
-
var p = (r,
|
|
3
|
-
var g = (r,
|
|
2
|
+
var p = (r, o, t) => o in r ? u(r, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[o] = t;
|
|
3
|
+
var g = (r, o, t) => p(r, typeof o != "symbol" ? o + "" : o, t);
|
|
4
4
|
import { Block as f, BlockCompositionType as I, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
-
import { RecommendationConfigService as
|
|
5
|
+
import { RecommendationConfigService as c } from "./services/configService.js";
|
|
6
6
|
import { useRecommendationExtensionStore as d } from "./store/recommendation.js";
|
|
7
7
|
import { getDefaultTemplate as _ } from "./templates/grid/template.js";
|
|
8
|
-
const k = "recommendation-block",
|
|
8
|
+
const k = "recommendation-block", s = "ins-recommendation-v3-block-v2", a = "recommendation-id";
|
|
9
9
|
class b extends f {
|
|
10
10
|
constructor() {
|
|
11
11
|
super();
|
|
@@ -50,7 +50,9 @@ class b extends f {
|
|
|
50
50
|
*/
|
|
51
51
|
onCreated(t) {
|
|
52
52
|
const e = this._pendingBlockId ?? this._generateNextId();
|
|
53
|
-
this._pendingBlockId = null, this._assignRecommendationId(t, e)
|
|
53
|
+
this._pendingBlockId = null, this._assignRecommendationId(t, e);
|
|
54
|
+
const n = c.initializeConfig(this.api, t, { recommendationId: e }), i = d();
|
|
55
|
+
i.setCurrentBlock(e), i.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
|
|
54
56
|
}
|
|
55
57
|
/**
|
|
56
58
|
* Called when the document changes or template is loaded
|
|
@@ -63,14 +65,14 @@ class b extends f {
|
|
|
63
65
|
if (!(!t || !("getNodeConfig" in t))) {
|
|
64
66
|
if (!this._getRecommendationId(t)) {
|
|
65
67
|
const e = this._generateNextId();
|
|
66
|
-
this._assignRecommendationId(t, e),
|
|
68
|
+
this._assignRecommendationId(t, e), c.hasConfig(t) && c.updateConfig(
|
|
67
69
|
this.api,
|
|
68
70
|
t,
|
|
69
71
|
{ recommendationId: e },
|
|
70
72
|
"Assign recommendation ID to legacy block"
|
|
71
73
|
);
|
|
72
74
|
}
|
|
73
|
-
|
|
75
|
+
c.needsMigration(t) && this._migrateFromLegacy(t);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
/**
|
|
@@ -91,9 +93,9 @@ class b extends f {
|
|
|
91
93
|
let t = 0;
|
|
92
94
|
try {
|
|
93
95
|
const e = this.api.getDocumentRoot();
|
|
94
|
-
e && "querySelectorAll" in e && e.querySelectorAll(`.${
|
|
95
|
-
if ("getAttribute" in
|
|
96
|
-
const
|
|
96
|
+
e && "querySelectorAll" in e && e.querySelectorAll(`.${s}`).forEach((i) => {
|
|
97
|
+
if ("getAttribute" in i) {
|
|
98
|
+
const m = i.getAttribute(a), l = m ? parseInt(m) : 0;
|
|
97
99
|
l > t && (t = l);
|
|
98
100
|
}
|
|
99
101
|
});
|
|
@@ -111,8 +113,8 @@ class b extends f {
|
|
|
111
113
|
const n = this._getBlockElement(t);
|
|
112
114
|
if (!n)
|
|
113
115
|
return;
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
+
const i = this.api.getDocumentModifier();
|
|
117
|
+
i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new h(`Assign recommendation ID ${e}`));
|
|
116
118
|
}
|
|
117
119
|
/**
|
|
118
120
|
* Gets the recommendation-id from a block node
|
|
@@ -121,11 +123,11 @@ class b extends f {
|
|
|
121
123
|
const e = this._getBlockElement(t);
|
|
122
124
|
if (!e || !("getAttribute" in e))
|
|
123
125
|
return null;
|
|
124
|
-
const n = e.getAttribute(
|
|
126
|
+
const n = e.getAttribute(a);
|
|
125
127
|
if (!n)
|
|
126
128
|
return null;
|
|
127
|
-
const
|
|
128
|
-
return Number.isNaN(
|
|
129
|
+
const i = parseInt(n);
|
|
130
|
+
return Number.isNaN(i) ? null : i;
|
|
129
131
|
}
|
|
130
132
|
/**
|
|
131
133
|
* Gets the block element (the element with BLOCK_CLASS)
|
|
@@ -133,16 +135,16 @@ class b extends f {
|
|
|
133
135
|
_getBlockElement(t) {
|
|
134
136
|
if ("getAttribute" in t) {
|
|
135
137
|
const e = t.getAttribute("class");
|
|
136
|
-
if (e && e.includes(
|
|
138
|
+
if (e && e.includes(s))
|
|
137
139
|
return t;
|
|
138
140
|
}
|
|
139
|
-
return "querySelector" in t ? t.querySelector(`.${
|
|
141
|
+
return "querySelector" in t ? t.querySelector(`.${s}`) : null;
|
|
140
142
|
}
|
|
141
143
|
/**
|
|
142
144
|
* Migrate configuration from legacy format
|
|
143
145
|
*/
|
|
144
146
|
_migrateFromLegacy(t) {
|
|
145
|
-
|
|
147
|
+
c.migrateFromDataAttributes(this.api, t);
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var d = Object.defineProperty;
|
|
2
|
-
var m = (
|
|
3
|
-
var
|
|
2
|
+
var m = (c, s, t) => s in c ? d(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
|
|
3
|
+
var n = (c, s, t) => m(c, typeof s != "symbol" ? s + "" : s, t);
|
|
4
4
|
import { CommonControl as h } from "../../../common-control.js";
|
|
5
5
|
import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
|
|
6
6
|
import { AlgorithmControl as f } from "./algorithm.js";
|
|
@@ -15,36 +15,34 @@ import { ProductLayoutControl as _ } from "./productLayout.js";
|
|
|
15
15
|
import { PRODUCT_LAYOUT_CONTROL_ID as K } from "./productLayout.js";
|
|
16
16
|
import { ShuffleControl as N } from "./shuffle.js";
|
|
17
17
|
import { SHUFFLE_CONTROL_ID as J } from "./shuffle.js";
|
|
18
|
-
import { regenerateProductRowsWithStyles as
|
|
19
|
-
import { formatProductPrice as X, getCardComposition as Z, getCurrentLayout as tt, reapplySpacing as et, regenerateProductRows as ot, setCurrencyAttributes as rt, updatePricesInPlace as
|
|
20
|
-
import { useDebounceFn as
|
|
21
|
-
const
|
|
22
|
-
class
|
|
18
|
+
import { regenerateProductRowsWithStyles as b, getBlockElement as P, updateProductContentInPlace as y } from "./utils.js";
|
|
19
|
+
import { formatProductPrice as X, getCardComposition as Z, getCurrentLayout as tt, reapplySpacing as et, regenerateProductRows as ot, setCurrencyAttributes as rt, updatePricesInPlace as nt, updateSingleProductContent as it } from "./utils.js";
|
|
20
|
+
import { useDebounceFn as a } from "../../../../../node_modules/@vueuse/shared/index.js";
|
|
21
|
+
const I = "recommendation-id", T = "ui-elements-recommendation-block";
|
|
22
|
+
class B extends h {
|
|
23
23
|
constructor() {
|
|
24
24
|
super(...arguments);
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
n(this, "store", C());
|
|
26
|
+
n(this, "storeUnsubscription", () => {
|
|
27
27
|
});
|
|
28
|
-
// Track if initial data has been fetched per block ID to avoid redundant API calls
|
|
29
|
-
i(this, "initializedBlocks", /* @__PURE__ */ new Map());
|
|
30
28
|
// Sub-control instances for lifecycle management
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
n(this, "algorithmControl", null);
|
|
30
|
+
n(this, "localeControl", null);
|
|
31
|
+
n(this, "currencyControl", null);
|
|
32
|
+
n(this, "productLayoutControl", null);
|
|
33
|
+
n(this, "filtersControl", null);
|
|
34
|
+
n(this, "shuffleControl", null);
|
|
37
35
|
/**
|
|
38
36
|
* Debounced product fetch to prevent rapid API calls during config changes
|
|
39
37
|
*/
|
|
40
|
-
|
|
38
|
+
n(this, "_debouncedFetchProducts", a(() => {
|
|
41
39
|
this.store.fetchRecommendationProducts();
|
|
42
40
|
}, 500));
|
|
43
41
|
/**
|
|
44
42
|
* Debounced regeneration when products arrive from API
|
|
45
43
|
* Tries in-place update first to preserve styles, falls back to full regeneration
|
|
46
44
|
*/
|
|
47
|
-
|
|
45
|
+
n(this, "_debouncedRegenerateWithProducts", a(() => {
|
|
48
46
|
const t = this.store.recommendationProducts;
|
|
49
47
|
if (!this.currentNode || !this.api)
|
|
50
48
|
return;
|
|
@@ -57,7 +55,7 @@ class x extends h {
|
|
|
57
55
|
}, 100));
|
|
58
56
|
}
|
|
59
57
|
getId() {
|
|
60
|
-
return
|
|
58
|
+
return T;
|
|
61
59
|
}
|
|
62
60
|
getTemplate() {
|
|
63
61
|
return this.algorithmControl = new f(), this.localeControl = new R(), this.currencyControl = new p(), this.productLayoutControl = new _(), this.filtersControl = new g(), this.shuffleControl = new N(), `
|
|
@@ -72,8 +70,9 @@ class x extends h {
|
|
|
72
70
|
`;
|
|
73
71
|
}
|
|
74
72
|
async onRender() {
|
|
73
|
+
var e;
|
|
75
74
|
const t = this._getRecommendationIdFromNode(this.currentNode) ?? this.store.currentRecommendationId;
|
|
76
|
-
if (t !== null && this.store.setCurrentBlock(t), this._listenStateUpdates(), t !== null && this.
|
|
75
|
+
if (t !== null && this.store.setCurrentBlock(t), this._listenStateUpdates(), t !== null && ((e = this.store.blockStates[t]) != null && e.isInitialized)) {
|
|
77
76
|
this._initializeSubControls();
|
|
78
77
|
return;
|
|
79
78
|
}
|
|
@@ -88,16 +87,17 @@ class x extends h {
|
|
|
88
87
|
console.warn("[Recommendation] Cannot regenerate - missing currentNode or api");
|
|
89
88
|
return;
|
|
90
89
|
}
|
|
91
|
-
|
|
90
|
+
b({
|
|
92
91
|
currentNode: this.currentNode,
|
|
93
92
|
documentModifier: this.api.getDocumentModifier(),
|
|
94
93
|
products: t
|
|
95
94
|
});
|
|
96
95
|
}
|
|
97
96
|
onTemplateNodeUpdated(t) {
|
|
97
|
+
var i;
|
|
98
98
|
super.onTemplateNodeUpdated(t);
|
|
99
99
|
const e = this._getRecommendationIdFromNode(t);
|
|
100
|
-
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.
|
|
100
|
+
e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !((i = this.store.blockStates[e]) != null && i.isInitialized) && this._fetchBlockData(e), [
|
|
101
101
|
this.algorithmControl,
|
|
102
102
|
this.localeControl,
|
|
103
103
|
this.currencyControl,
|
|
@@ -105,8 +105,8 @@ class x extends h {
|
|
|
105
105
|
this.filtersControl,
|
|
106
106
|
this.shuffleControl
|
|
107
107
|
].forEach((r) => {
|
|
108
|
-
var
|
|
109
|
-
r != null && r.api && (r.currentNode = t, (
|
|
108
|
+
var l;
|
|
109
|
+
r != null && r.api && (r.currentNode = t, (l = r.onTemplateNodeUpdated) == null || l.call(r, t));
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
onDestroy() {
|
|
@@ -145,30 +145,30 @@ class x extends h {
|
|
|
145
145
|
* Marks the block as initialized to prevent redundant fetches on re-selection.
|
|
146
146
|
*/
|
|
147
147
|
async _fetchBlockData(t) {
|
|
148
|
-
t !== null && this.
|
|
148
|
+
t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
|
|
149
149
|
this.store.fetchRecommendationFilters(),
|
|
150
150
|
this.store.fetchRecommendationCreateData(),
|
|
151
151
|
this.store.fetchRecommendationProducts()
|
|
152
|
-
])).forEach((o,
|
|
152
|
+
])).forEach((o, i) => {
|
|
153
153
|
o.status === "rejected" && console.warn(`Recommendation block: ${[
|
|
154
154
|
"fetchRecommendationFilters",
|
|
155
155
|
"fetchRecommendationCreateData",
|
|
156
156
|
"fetchRecommendationProducts"
|
|
157
|
-
][
|
|
157
|
+
][i]} failed`, o.reason);
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
160
|
/**
|
|
161
161
|
* Reads the recommendation-id attribute from the block element within the node
|
|
162
162
|
*/
|
|
163
163
|
_getRecommendationIdFromNode(t) {
|
|
164
|
-
const e =
|
|
164
|
+
const e = P(t);
|
|
165
165
|
if (!e || !("getAttribute" in e))
|
|
166
166
|
return null;
|
|
167
|
-
const o = e.getAttribute(
|
|
167
|
+
const o = e.getAttribute(I);
|
|
168
168
|
if (!o)
|
|
169
169
|
return null;
|
|
170
|
-
const
|
|
171
|
-
return Number.isNaN(
|
|
170
|
+
const i = parseInt(o);
|
|
171
|
+
return Number.isNaN(i) ? null : i;
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Listen to store changes that require product refresh or regeneration.
|
|
@@ -181,17 +181,17 @@ class x extends h {
|
|
|
181
181
|
const { store: t } = this;
|
|
182
182
|
let e = t.recommendationProducts, o = t.$state.configVersion;
|
|
183
183
|
this.storeUnsubscription = t.$subscribe(() => {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
184
|
+
const i = t.$state.configVersion;
|
|
185
|
+
i !== o && (o = i, this._debouncedFetchProducts());
|
|
186
|
+
const r = t.recommendationProducts, l = r !== e, u = Array.isArray(r) && r.length > 0;
|
|
187
|
+
l && u && (e = r, this._debouncedRegenerateWithProducts());
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
export {
|
|
192
192
|
M as ALGORITHM_CONTROL_ID,
|
|
193
193
|
f as AlgorithmControl,
|
|
194
|
-
|
|
194
|
+
T as CONTROL_BLOCK_ID,
|
|
195
195
|
W as CURRENCY_CONTROL_ID,
|
|
196
196
|
p as CurrencyControl,
|
|
197
197
|
H as FILTERS_CONTROL_ID,
|
|
@@ -200,18 +200,18 @@ export {
|
|
|
200
200
|
R as LocaleControl,
|
|
201
201
|
K as PRODUCT_LAYOUT_CONTROL_ID,
|
|
202
202
|
_ as ProductLayoutControl,
|
|
203
|
-
|
|
203
|
+
B as RecommendationBlockControl,
|
|
204
204
|
J as SHUFFLE_CONTROL_ID,
|
|
205
205
|
N as ShuffleControl,
|
|
206
206
|
X as formatProductPrice,
|
|
207
|
-
|
|
207
|
+
P as getBlockElement,
|
|
208
208
|
Z as getCardComposition,
|
|
209
209
|
tt as getCurrentLayout,
|
|
210
210
|
et as reapplySpacing,
|
|
211
211
|
ot as regenerateProductRows,
|
|
212
|
-
|
|
212
|
+
b as regenerateProductRowsWithStyles,
|
|
213
213
|
rt as setCurrencyAttributes,
|
|
214
|
-
|
|
214
|
+
nt as updatePricesInPlace,
|
|
215
215
|
y as updateProductContentInPlace,
|
|
216
|
-
|
|
216
|
+
it as updateSingleProductContent
|
|
217
217
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { RecommendationFeedSourceMaps as
|
|
2
|
-
import { useRecommendationApi as
|
|
3
|
-
import { useConfigStore as
|
|
4
|
-
import { defineStore as
|
|
5
|
-
import { DEFAULT_CARDS_IN_ROW as
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { RecommendationFeedSourceMaps as d, PriceAttributes as S } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
|
+
import { useRecommendationApi as p } from "../../../../services/recommendationApi.js";
|
|
3
|
+
import { useConfigStore as b } from "../../../../stores/config.js";
|
|
4
|
+
import { defineStore as I } from "pinia";
|
|
5
|
+
import { DEFAULT_CARDS_IN_ROW as R } from "../constants/layout.js";
|
|
6
|
+
import { getDefaultProducts as k } from "../templates/utils.js";
|
|
7
|
+
import { generateCompleteFilterQuery as f } from "../utils/filterUtil.js";
|
|
8
|
+
const m = p();
|
|
9
|
+
function h() {
|
|
9
10
|
return {
|
|
10
|
-
cardsInRow:
|
|
11
|
+
cardsInRow: R,
|
|
11
12
|
currencySettings: {
|
|
12
13
|
name: "USD",
|
|
13
14
|
value: "USD",
|
|
@@ -20,7 +21,7 @@ function f() {
|
|
|
20
21
|
filters: [],
|
|
21
22
|
productIds: [],
|
|
22
23
|
id: 1,
|
|
23
|
-
language: "
|
|
24
|
+
language: "en_US",
|
|
24
25
|
orientation: "grid",
|
|
25
26
|
recommendedProducts: [],
|
|
26
27
|
sendProductRequestFlag: !1,
|
|
@@ -31,16 +32,17 @@ function f() {
|
|
|
31
32
|
size: "6"
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
|
-
function
|
|
35
|
+
function C() {
|
|
35
36
|
return {
|
|
36
|
-
recommendationConfigs:
|
|
37
|
+
recommendationConfigs: h(),
|
|
37
38
|
recommendationProducts: [],
|
|
38
39
|
filterStatus: !1,
|
|
39
40
|
filterSelectionDrawerStatus: !1,
|
|
40
|
-
filterGroup: 1
|
|
41
|
+
filterGroup: 1,
|
|
42
|
+
isInitialized: !1
|
|
41
43
|
};
|
|
42
44
|
}
|
|
43
|
-
const
|
|
45
|
+
const y = () => ({
|
|
44
46
|
recommendationCampaignUrls: {},
|
|
45
47
|
activePredictiveAlgorithms: [],
|
|
46
48
|
languages: {},
|
|
@@ -49,8 +51,8 @@ const k = () => ({
|
|
|
49
51
|
blockStates: {},
|
|
50
52
|
currentRecommendationId: null,
|
|
51
53
|
configVersion: 0
|
|
52
|
-
}),
|
|
53
|
-
state: () =>
|
|
54
|
+
}), A = I("guidoRecommendationExtension", {
|
|
55
|
+
state: () => y(),
|
|
54
56
|
getters: {
|
|
55
57
|
// ====================================================================
|
|
56
58
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -59,32 +61,32 @@ const k = () => ({
|
|
|
59
61
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationConfigs
|
|
60
62
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
61
63
|
*/
|
|
62
|
-
recommendationConfigs(
|
|
63
|
-
return
|
|
64
|
+
recommendationConfigs(t) {
|
|
65
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : h();
|
|
64
66
|
},
|
|
65
67
|
/**
|
|
66
68
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
67
69
|
*/
|
|
68
|
-
recommendationProducts(
|
|
69
|
-
return
|
|
70
|
+
recommendationProducts(t) {
|
|
71
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationProducts : [];
|
|
70
72
|
},
|
|
71
73
|
/**
|
|
72
74
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterSelectionDrawerStatus
|
|
73
75
|
*/
|
|
74
|
-
filterSelectionDrawerStatus(
|
|
75
|
-
return
|
|
76
|
+
filterSelectionDrawerStatus(t) {
|
|
77
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
|
|
76
78
|
},
|
|
77
79
|
/**
|
|
78
80
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
|
|
79
81
|
*/
|
|
80
|
-
filterStatus(
|
|
81
|
-
return
|
|
82
|
+
filterStatus(t) {
|
|
83
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterStatus : !1;
|
|
82
84
|
},
|
|
83
85
|
/**
|
|
84
86
|
* Proxy getter: delegates to blockStates[currentRecommendationId].filterGroup
|
|
85
87
|
*/
|
|
86
|
-
filterGroup(
|
|
87
|
-
return
|
|
88
|
+
filterGroup(t) {
|
|
89
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterGroup : 1;
|
|
88
90
|
},
|
|
89
91
|
// ====================================================================
|
|
90
92
|
// Existing Getters (now reading through proxy)
|
|
@@ -93,39 +95,39 @@ const k = () => ({
|
|
|
93
95
|
return !!this.recommendationConfigs.filters.length;
|
|
94
96
|
},
|
|
95
97
|
getFilterGroupCount() {
|
|
96
|
-
const { filters:
|
|
97
|
-
return
|
|
98
|
+
const { filters: t } = this.recommendationConfigs;
|
|
99
|
+
return t.length && t[t.length - 1].filterGroup || 0;
|
|
98
100
|
},
|
|
99
|
-
getActivePredictiveAlgorithms: (
|
|
101
|
+
getActivePredictiveAlgorithms: (t) => {
|
|
100
102
|
const r = [];
|
|
101
|
-
return
|
|
102
|
-
r.push(...
|
|
103
|
-
}), r.map((
|
|
104
|
-
text:
|
|
105
|
-
value:
|
|
103
|
+
return t.activePredictiveAlgorithms.forEach((e) => {
|
|
104
|
+
r.push(...d.filter((n) => n.id === e));
|
|
105
|
+
}), r.map((e) => ({
|
|
106
|
+
text: e.name,
|
|
107
|
+
value: e.key
|
|
106
108
|
}));
|
|
107
109
|
},
|
|
108
|
-
getLanguages: (
|
|
109
|
-
text:
|
|
110
|
+
getLanguages: (t) => Object.entries(t.languages).map(([r, e]) => ({
|
|
111
|
+
text: e,
|
|
110
112
|
value: r
|
|
111
113
|
})),
|
|
112
|
-
getCurrencySymbolList: (
|
|
114
|
+
getCurrencySymbolList: (t) => t.currencyList.map((r) => ({
|
|
113
115
|
text: r.text,
|
|
114
116
|
value: r.text
|
|
115
117
|
})),
|
|
116
118
|
getFilterList() {
|
|
117
|
-
return Object.values(this.filterList).map((
|
|
118
|
-
const r =
|
|
119
|
-
let n = r ?
|
|
120
|
-
return n =
|
|
121
|
-
text:
|
|
119
|
+
return Object.values(this.filterList).map((t) => {
|
|
120
|
+
const r = t.type === "defaultAttribute", e = S.includes(t.attributeName);
|
|
121
|
+
let n = r ? t.attributeName : `product_attributes.${t.attributeName}`;
|
|
122
|
+
return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
|
|
123
|
+
text: t.displayName,
|
|
122
124
|
value: n,
|
|
123
|
-
type:
|
|
125
|
+
type: t.attributeType
|
|
124
126
|
};
|
|
125
127
|
});
|
|
126
128
|
},
|
|
127
129
|
getSelectedFilterGroup() {
|
|
128
|
-
return (
|
|
130
|
+
return (t) => [...this.recommendationConfigs.filters].filter((r) => r.filterGroup === t);
|
|
129
131
|
}
|
|
130
132
|
},
|
|
131
133
|
actions: {
|
|
@@ -136,37 +138,44 @@ const k = () => ({
|
|
|
136
138
|
* Sets the currently active block ID.
|
|
137
139
|
* Creates a new entry in blockStates if one doesn't exist.
|
|
138
140
|
*/
|
|
139
|
-
setCurrentBlock(
|
|
140
|
-
this.blockStates[
|
|
141
|
+
setCurrentBlock(t) {
|
|
142
|
+
this.blockStates[t] || (this.blockStates = {
|
|
141
143
|
...this.blockStates,
|
|
142
|
-
[
|
|
143
|
-
}), this.currentRecommendationId =
|
|
144
|
+
[t]: C()
|
|
145
|
+
}), this.currentRecommendationId = t;
|
|
144
146
|
},
|
|
145
147
|
/**
|
|
146
148
|
* Removes a block's state from the store.
|
|
147
149
|
* Resets currentRecommendationId if it was the deleted block.
|
|
148
150
|
*/
|
|
149
|
-
removeBlockState(
|
|
151
|
+
removeBlockState(t) {
|
|
150
152
|
const r = { ...this.blockStates };
|
|
151
|
-
if (delete r[
|
|
152
|
-
const
|
|
153
|
-
this.currentRecommendationId =
|
|
153
|
+
if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
|
|
154
|
+
const e = Object.keys(this.blockStates).map(Number);
|
|
155
|
+
this.currentRecommendationId = e.length > 0 ? e[0] : null;
|
|
154
156
|
}
|
|
155
157
|
},
|
|
158
|
+
/**
|
|
159
|
+
* Marks a block as initialized (initial API data has been fetched).
|
|
160
|
+
* Automatically cleaned up when removeBlockState deletes the block entry.
|
|
161
|
+
*/
|
|
162
|
+
markBlockInitialized(t) {
|
|
163
|
+
this.blockStates[t] && (this.blockStates[t].isInitialized = !0);
|
|
164
|
+
},
|
|
156
165
|
/**
|
|
157
166
|
* Patches the current block's recommendationConfigs.
|
|
158
167
|
* Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
|
|
159
168
|
*/
|
|
160
|
-
patchCurrentBlockConfig(
|
|
169
|
+
patchCurrentBlockConfig(t, r = {}) {
|
|
161
170
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
162
171
|
return;
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
...
|
|
166
|
-
...
|
|
172
|
+
const e = this.blockStates[this.currentRecommendationId];
|
|
173
|
+
e.recommendationConfigs = {
|
|
174
|
+
...e.recommendationConfigs,
|
|
175
|
+
...t,
|
|
167
176
|
currencySettings: {
|
|
168
|
-
...
|
|
169
|
-
...
|
|
177
|
+
...e.recommendationConfigs.currencySettings,
|
|
178
|
+
...t.currencySettings || {}
|
|
170
179
|
}
|
|
171
180
|
};
|
|
172
181
|
const { triggerRefetch: n = !0 } = r;
|
|
@@ -180,8 +189,8 @@ const k = () => ({
|
|
|
180
189
|
openFilterDrawer() {
|
|
181
190
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
182
191
|
return;
|
|
183
|
-
const
|
|
184
|
-
|
|
192
|
+
const t = this.blockStates[this.currentRecommendationId];
|
|
193
|
+
t.recommendationConfigs.filters.length || (t.recommendationConfigs.filters = [{
|
|
185
194
|
type: "standardFilter",
|
|
186
195
|
attribute: "",
|
|
187
196
|
operatorReplace: "",
|
|
@@ -192,7 +201,7 @@ const k = () => ({
|
|
|
192
201
|
filterGroup: 1,
|
|
193
202
|
isValid: !1,
|
|
194
203
|
value: ""
|
|
195
|
-
}]),
|
|
204
|
+
}]), t.filterSelectionDrawerStatus = !0;
|
|
196
205
|
},
|
|
197
206
|
/**
|
|
198
207
|
* Closes the filter selection drawer for the current block
|
|
@@ -207,26 +216,26 @@ const k = () => ({
|
|
|
207
216
|
if (this.activePredictiveAlgorithms.length)
|
|
208
217
|
return;
|
|
209
218
|
const {
|
|
210
|
-
activePredictiveAlgorithms:
|
|
219
|
+
activePredictiveAlgorithms: t,
|
|
211
220
|
languages: r,
|
|
212
|
-
currencies:
|
|
213
|
-
} = await
|
|
214
|
-
this.activePredictiveAlgorithms =
|
|
215
|
-
const [n] =
|
|
221
|
+
currencies: e
|
|
222
|
+
} = await m.fetchRecommendationCreateData();
|
|
223
|
+
this.activePredictiveAlgorithms = t, this.languages = r;
|
|
224
|
+
const [n] = e, o = n.value.includes(".") ? n.value.split(".")[1] : n.value;
|
|
216
225
|
if (this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
|
|
217
226
|
const i = this.blockStates[this.currentRecommendationId];
|
|
218
227
|
i.recommendationConfigs.currencySettings.name = n.text, i.recommendationConfigs.currencySettings.value = o, i.filterStatus = !!i.recommendationConfigs.filters.length;
|
|
219
228
|
}
|
|
220
|
-
this.currencyList =
|
|
229
|
+
this.currencyList = e;
|
|
221
230
|
},
|
|
222
231
|
async fetchRecommendationFilters() {
|
|
223
|
-
const
|
|
224
|
-
this.filterList =
|
|
232
|
+
const t = await m.fetchRecommendationFilters();
|
|
233
|
+
this.filterList = t;
|
|
225
234
|
},
|
|
226
235
|
// ====================================================================
|
|
227
236
|
// Per-Block Filter Actions
|
|
228
237
|
// ====================================================================
|
|
229
|
-
addFilterGroup(
|
|
238
|
+
addFilterGroup(t) {
|
|
230
239
|
this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || this.blockStates[this.currentRecommendationId].recommendationConfigs.filters.push({
|
|
231
240
|
type: "standardFilter",
|
|
232
241
|
attribute: "",
|
|
@@ -237,68 +246,71 @@ const k = () => ({
|
|
|
237
246
|
value: "",
|
|
238
247
|
filterNumber: 1,
|
|
239
248
|
isValid: !0,
|
|
240
|
-
filterGroup:
|
|
249
|
+
filterGroup: t
|
|
241
250
|
});
|
|
242
251
|
},
|
|
243
|
-
updateFilter(
|
|
252
|
+
updateFilter(t) {
|
|
244
253
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
245
254
|
return;
|
|
246
|
-
const r = this.blockStates[this.currentRecommendationId],
|
|
247
|
-
if (
|
|
255
|
+
const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
256
|
+
if (e !== -1) {
|
|
248
257
|
const n = [...r.recommendationConfigs.filters];
|
|
249
|
-
n[
|
|
258
|
+
n[e] = t, t.value.length && t.operator && t.attribute && t.innerGroupOperator && t.outerGroupOperator ? n[e].isValid = !0 : n[e].isValid = !1, r.recommendationConfigs.filters = n;
|
|
250
259
|
}
|
|
251
260
|
},
|
|
252
|
-
deleteFilter(
|
|
261
|
+
deleteFilter(t) {
|
|
253
262
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
254
263
|
return;
|
|
255
|
-
const r = this.blockStates[this.currentRecommendationId],
|
|
256
|
-
if (
|
|
264
|
+
const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
|
|
265
|
+
if (e !== -1) {
|
|
257
266
|
const n = [...r.recommendationConfigs.filters];
|
|
258
|
-
n.splice(
|
|
267
|
+
n.splice(e, 1), r.recommendationConfigs.filters = n;
|
|
259
268
|
}
|
|
260
269
|
},
|
|
261
|
-
addFilter(
|
|
270
|
+
addFilter(t) {
|
|
262
271
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
263
272
|
return;
|
|
264
|
-
const r = this.blockStates[this.currentRecommendationId],
|
|
265
|
-
(c) => c.filterGroup ===
|
|
266
|
-
).length + 1, i =
|
|
267
|
-
i !== -1 ?
|
|
268
|
-
...
|
|
273
|
+
const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters], o = e.filter(
|
|
274
|
+
(c) => c.filterGroup === t.filterGroup
|
|
275
|
+
).length + 1, i = e.findLastIndex((c) => c.filterGroup === t.filterGroup);
|
|
276
|
+
i !== -1 ? e.splice(i + 1, 0, {
|
|
277
|
+
...t,
|
|
269
278
|
filterNumber: o
|
|
270
|
-
}) :
|
|
271
|
-
...
|
|
279
|
+
}) : e.push({
|
|
280
|
+
...t,
|
|
272
281
|
filterNumber: o
|
|
273
|
-
}), r.recommendationConfigs.filters =
|
|
282
|
+
}), r.recommendationConfigs.filters = e;
|
|
274
283
|
},
|
|
275
284
|
generateFilterQuery() {
|
|
276
|
-
return
|
|
285
|
+
return f(this.recommendationConfigs.filters);
|
|
277
286
|
},
|
|
278
287
|
// ====================================================================
|
|
279
288
|
// Per-Block Product Fetching
|
|
280
289
|
// ====================================================================
|
|
281
290
|
async fetchRecommendationProducts() {
|
|
282
|
-
var
|
|
291
|
+
var u;
|
|
283
292
|
if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
|
|
284
293
|
return;
|
|
285
|
-
const
|
|
286
|
-
locale:
|
|
287
|
-
currency:
|
|
294
|
+
const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((l) => l.isValid), o = f(n), i = ((u = d.find((l) => l.key === e.strategy)) == null ? void 0 : u.path) || "", c = b(), s = {
|
|
295
|
+
locale: e.language,
|
|
296
|
+
currency: e.currencySettings.value,
|
|
288
297
|
partnerName: c.partnerName,
|
|
289
|
-
size:
|
|
298
|
+
size: e.size,
|
|
290
299
|
details: !0,
|
|
291
300
|
campaignId: c.variationId
|
|
292
301
|
};
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
302
|
+
e.strategy === "manualMerchandising" ? s.productId = e.productIds.join(",") : e.strategy === "similarViewed" && (s.productId = "{itemId}"), o && (s.filter = o), e.shuffleProducts && (s.shuffle = !0);
|
|
303
|
+
const g = parseInt(e.size) || 6;
|
|
304
|
+
let a;
|
|
305
|
+
try {
|
|
306
|
+
a = await m.fetchRecommendationProducts(i, s);
|
|
307
|
+
} catch {
|
|
308
|
+
a = [];
|
|
309
|
+
}
|
|
310
|
+
this.blockStates[t] && (this.blockStates[t].recommendationProducts = a.length > 0 ? a : k(g));
|
|
299
311
|
}
|
|
300
312
|
}
|
|
301
313
|
});
|
|
302
314
|
export {
|
|
303
|
-
|
|
315
|
+
A as useRecommendationExtensionStore
|
|
304
316
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_PRODUCTS_PER_ROW as L } from "../../constants/layout.js";
|
|
2
|
-
import { DEFAULT_CARD_COMPOSITION as R, spacer as I,
|
|
2
|
+
import { DEFAULT_CARD_COMPOSITION as R, spacer as I, getDefaultProducts as E, createBlockTemplate as S, DEFAULTS as _, DEFAULT_CARD_VISIBILITY as b } from "../utils.js";
|
|
3
3
|
import { gridElementRenderer as A, ATTRIBUTE_CELL_CLASS as w, DEFAULT_CELL_PADDING as f } from "./elementRenderer.js";
|
|
4
4
|
const D = `
|
|
5
5
|
<tr class="recommendation-product-row">
|
|
@@ -55,11 +55,11 @@ function U(t, e, r) {
|
|
|
55
55
|
return P(t, e, A, r);
|
|
56
56
|
}
|
|
57
57
|
function B(t) {
|
|
58
|
-
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, r =
|
|
59
|
-
|
|
58
|
+
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, r = S("grid", e), c = U(
|
|
59
|
+
E(),
|
|
60
60
|
L
|
|
61
61
|
);
|
|
62
|
-
return r.replace("{-{-TITLE-}-}",
|
|
62
|
+
return r.replace("{-{-TITLE-}-}", _.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c);
|
|
63
63
|
}
|
|
64
64
|
export {
|
|
65
65
|
B as getDefaultTemplate,
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { ATTR_PRODUCT_IMAGE as a, ATTR_PRODUCT_NAME as o, ATTR_PRODUCT_OLD_PRICE as c, ATTR_PRODUCT_PRICE as
|
|
1
|
+
import { ATTR_PRODUCT_IMAGE as a, ATTR_PRODUCT_NAME as o, ATTR_PRODUCT_OLD_PRICE as c, ATTR_PRODUCT_PRICE as l, ATTR_PRODUCT_OMNIBUS_PRICE as s, ATTR_PRODUCT_OMNIBUS_DISCOUNT as n, ATTR_PRODUCT_BUTTON as i } from "../constants/selectors.js";
|
|
2
2
|
const m = {
|
|
3
3
|
TITLE: "You May Also Like!"
|
|
4
|
-
},
|
|
4
|
+
}, u = [
|
|
5
5
|
a,
|
|
6
6
|
o,
|
|
7
7
|
c,
|
|
8
|
-
s,
|
|
9
8
|
l,
|
|
9
|
+
s,
|
|
10
10
|
n,
|
|
11
11
|
i
|
|
12
12
|
], b = {
|
|
13
13
|
[a]: !0,
|
|
14
14
|
[o]: !0,
|
|
15
|
-
[
|
|
15
|
+
[l]: !0,
|
|
16
16
|
[c]: !0,
|
|
17
|
-
[
|
|
17
|
+
[s]: !1,
|
|
18
18
|
[n]: !1,
|
|
19
19
|
[i]: !0
|
|
20
|
-
},
|
|
20
|
+
}, p = `
|
|
21
21
|
<tr>
|
|
22
22
|
<td class="spacer" style="height: 10px;"></td>
|
|
23
23
|
</tr>
|
|
@@ -25,7 +25,7 @@ const m = {
|
|
|
25
25
|
function R(t) {
|
|
26
26
|
return !t || typeof t != "string" || t.trim() === "" ? d : t.startsWith("http://") ? t.replace("http://", "https://") : t;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function T(t) {
|
|
29
29
|
return {
|
|
30
30
|
name: "Product Name",
|
|
31
31
|
image_url: d,
|
|
@@ -40,23 +40,19 @@ function e(t) {
|
|
|
40
40
|
category: []
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
function D() {
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
e(
|
|
47
|
-
|
|
48
|
-
e("4"),
|
|
49
|
-
e("5"),
|
|
50
|
-
e("6")
|
|
51
|
-
];
|
|
43
|
+
function D(t = 6) {
|
|
44
|
+
return Array.from(
|
|
45
|
+
{ length: t },
|
|
46
|
+
(e, r) => T(String(r + 1))
|
|
47
|
+
);
|
|
52
48
|
}
|
|
53
|
-
function
|
|
54
|
-
const
|
|
49
|
+
function A(t = "grid", e) {
|
|
50
|
+
const r = t === "list" ? `
|
|
55
51
|
data-layout="list"` : "";
|
|
56
52
|
return `
|
|
57
53
|
<td
|
|
58
54
|
align="left"
|
|
59
|
-
class="ins-recommendation-v3-block-v2 esd-block-recommendation-v3-block es-p20${
|
|
55
|
+
class="ins-recommendation-v3-block-v2 esd-block-recommendation-v3-block es-p20${e ? ` ${e}` : ""}"${r}>
|
|
60
56
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
|
61
57
|
<tr>
|
|
62
58
|
<td align="center">
|
|
@@ -88,7 +84,7 @@ function U(t = "grid", r) {
|
|
|
88
84
|
</table>
|
|
89
85
|
</td>
|
|
90
86
|
</tr>
|
|
91
|
-
${
|
|
87
|
+
${p}
|
|
92
88
|
<tr>
|
|
93
89
|
<td>
|
|
94
90
|
<table
|
|
@@ -112,11 +108,11 @@ function U(t = "grid", r) {
|
|
|
112
108
|
}
|
|
113
109
|
export {
|
|
114
110
|
m as DEFAULTS,
|
|
115
|
-
|
|
111
|
+
u as DEFAULT_CARD_COMPOSITION,
|
|
116
112
|
b as DEFAULT_CARD_VISIBILITY,
|
|
117
113
|
d as PLACEHOLDER_IMAGE,
|
|
118
|
-
|
|
114
|
+
A as createBlockTemplate,
|
|
119
115
|
D as getDefaultProducts,
|
|
120
116
|
R as sanitizeImageUrl,
|
|
121
|
-
|
|
117
|
+
p as spacer
|
|
122
118
|
};
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { useHttp as
|
|
1
|
+
import { useHttp as c } from "../composables/useHttp.js";
|
|
2
2
|
import { URLS as m } from "../enums/extensions/recommendationBlock.js";
|
|
3
|
-
const
|
|
4
|
-
const { get:
|
|
3
|
+
const f = () => {
|
|
4
|
+
const { get: o } = c();
|
|
5
5
|
return {
|
|
6
6
|
fetchRecommendationCreateData: async () => {
|
|
7
7
|
try {
|
|
8
|
-
return (await
|
|
8
|
+
return (await o("/newsletter/recommendations/create-data")).data;
|
|
9
9
|
} catch (e) {
|
|
10
10
|
throw console.error("fetchUserModalState error:", e), e;
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
fetchRecommendationFilters: async () => {
|
|
14
14
|
try {
|
|
15
|
-
const { data: e } = await
|
|
15
|
+
const { data: e } = await o("/stripo/email-recommendation-attributes");
|
|
16
16
|
return e;
|
|
17
17
|
} catch (e) {
|
|
18
18
|
throw console.error("fetchRecommendationFilters error:", e), e;
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
fetchRecommendationProducts: async (e,
|
|
21
|
+
fetchRecommendationProducts: async (e, a) => {
|
|
22
22
|
var n;
|
|
23
23
|
try {
|
|
24
|
-
const t = decodeURIComponent(new URLSearchParams(Object.entries(
|
|
24
|
+
const t = decodeURIComponent(new URLSearchParams(Object.entries(a)).toString());
|
|
25
25
|
console.debug("🏁 Recommendation API Query:", t);
|
|
26
|
-
const { get: s } =
|
|
26
|
+
const { get: s } = c({
|
|
27
27
|
headers: {}
|
|
28
|
-
}),
|
|
28
|
+
}), r = await s(
|
|
29
29
|
`${m.RECOMMENDATION_API_URL}/v2/${e}?${t}`
|
|
30
30
|
);
|
|
31
|
-
return
|
|
31
|
+
return ((n = r == null ? void 0 : r.data) == null ? void 0 : n.data) ?? [];
|
|
32
32
|
} catch (t) {
|
|
33
33
|
throw console.error("fetchRecommendationProducts error:", t), t;
|
|
34
34
|
}
|
|
@@ -36,5 +36,5 @@ const l = () => {
|
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
38
|
export {
|
|
39
|
-
|
|
39
|
+
f as useRecommendationApi
|
|
40
40
|
};
|
|
@@ -16,7 +16,6 @@ export * from './utils';
|
|
|
16
16
|
export declare class RecommendationBlockControl extends CommonControl {
|
|
17
17
|
private store;
|
|
18
18
|
private storeUnsubscription;
|
|
19
|
-
private initializedBlocks;
|
|
20
19
|
private algorithmControl;
|
|
21
20
|
private localeControl;
|
|
22
21
|
private currencyControl;
|
|
@@ -29,6 +29,8 @@ interface PerBlockState {
|
|
|
29
29
|
filterStatus: boolean;
|
|
30
30
|
filterSelectionDrawerStatus: boolean;
|
|
31
31
|
filterGroup: number;
|
|
32
|
+
/** Whether initial API data (filters, algorithms, products) has been fetched for this block */
|
|
33
|
+
isInitialized: boolean;
|
|
32
34
|
}
|
|
33
35
|
interface StoreState {
|
|
34
36
|
recommendationCampaignUrls: Record<string, string>;
|
|
@@ -189,6 +191,11 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
189
191
|
* Resets currentRecommendationId if it was the deleted block.
|
|
190
192
|
*/
|
|
191
193
|
removeBlockState(id: number): void;
|
|
194
|
+
/**
|
|
195
|
+
* Marks a block as initialized (initial API data has been fetched).
|
|
196
|
+
* Automatically cleaned up when removeBlockState deletes the block entry.
|
|
197
|
+
*/
|
|
198
|
+
markBlockInitialized(id: number): void;
|
|
192
199
|
/**
|
|
193
200
|
* Patches the current block's recommendationConfigs.
|
|
194
201
|
* Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
|
|
@@ -44,7 +44,7 @@ export declare const PLACEHOLDER_IMAGE = "https://email-static.useinsider.com/st
|
|
|
44
44
|
* @returns Sanitized HTTPS URL or placeholder
|
|
45
45
|
*/
|
|
46
46
|
export declare function sanitizeImageUrl(url: string | undefined | null): string;
|
|
47
|
-
export declare function getDefaultProducts(): RecommendationProduct[];
|
|
47
|
+
export declare function getDefaultProducts(count?: number): RecommendationProduct[];
|
|
48
48
|
/**
|
|
49
49
|
* Creates the block template wrapper HTML for recommendation blocks.
|
|
50
50
|
* The template includes title placeholder and product container.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.29e4650",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|