@gengage/assistant-fe 0.2.0 → 0.2.2
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/chat/components/Launcher.d.ts +2 -0
- package/dist/chat/components/Launcher.d.ts.map +1 -1
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/chat/panel-manager.d.ts +16 -0
- package/dist/chat/panel-manager.d.ts.map +1 -1
- package/dist/chat/types.d.ts +6 -0
- package/dist/chat/types.d.ts.map +1 -1
- package/dist/chat.cjs +1 -1
- package/dist/chat.iife.js +8 -8
- package/dist/chat.iife.js.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/common/overlay.d.ts +11 -0
- package/dist/common/overlay.d.ts.map +1 -1
- package/dist/common/protocol-adapter.d.ts +2 -0
- package/dist/common/protocol-adapter.d.ts.map +1 -1
- package/dist/common.cjs +1 -1
- package/dist/common.js +5 -5
- package/dist/index-CB8DgwIv.cjs +13 -0
- package/dist/index-CB8DgwIv.cjs.map +1 -0
- package/dist/index-CUukV8wH.cjs +2 -0
- package/dist/index-CUukV8wH.cjs.map +1 -0
- package/dist/{index-C6KDzSjm.js → index-CpLM7vPC.js} +65 -65
- package/dist/index-CpLM7vPC.js.map +1 -0
- package/dist/{index-RmQRBt6w.js → index-EEUjXgSt.js} +245 -226
- package/dist/index-EEUjXgSt.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/native.cjs +1 -1
- package/dist/native.iife.js +17 -17
- package/dist/native.iife.js.map +1 -1
- package/dist/native.js +1 -1
- package/dist/qna/index.d.ts.map +1 -1
- package/dist/qna/types.d.ts +3 -0
- package/dist/qna/types.d.ts.map +1 -1
- package/dist/qna.cjs +1 -1
- package/dist/qna.cjs.map +1 -1
- package/dist/qna.iife.js +15 -15
- package/dist/qna.iife.js.map +1 -1
- package/dist/qna.js +11 -12
- package/dist/qna.js.map +1 -1
- package/dist/{schemas-BAEbjFPE.js → schemas-D1Kd4wn8.js} +524 -499
- package/dist/schemas-D1Kd4wn8.js.map +1 -0
- package/dist/{schemas-DIyHm5pa.cjs → schemas-DOxyUYVA.cjs} +7 -7
- package/dist/schemas-DOxyUYVA.cjs.map +1 -0
- package/dist/simrel/components/GroupTabs.d.ts +1 -0
- package/dist/simrel/components/GroupTabs.d.ts.map +1 -1
- package/dist/simrel/components/ProductCard.d.ts +1 -0
- package/dist/simrel/components/ProductCard.d.ts.map +1 -1
- package/dist/simrel/components/ProductGrid.d.ts +1 -0
- package/dist/simrel/components/ProductGrid.d.ts.map +1 -1
- package/dist/simrel/components/renderUISpec.d.ts.map +1 -1
- package/dist/simrel/index.d.ts.map +1 -1
- package/dist/simrel/types.d.ts +10 -0
- package/dist/simrel/types.d.ts.map +1 -1
- package/dist/simrel.cjs +1 -1
- package/dist/simrel.cjs.map +1 -1
- package/dist/simrel.iife.js +5 -5
- package/dist/simrel.iife.js.map +1 -1
- package/dist/simrel.js +171 -165
- package/dist/simrel.js.map +1 -1
- package/package.json +1 -1
- package/dist/index-BA7N_XOO.cjs +0 -2
- package/dist/index-BA7N_XOO.cjs.map +0 -1
- package/dist/index-C6KDzSjm.js.map +0 -1
- package/dist/index-RmQRBt6w.js.map +0 -1
- package/dist/index-VgLdYuZV.cjs +0 -13
- package/dist/index-VgLdYuZV.cjs.map +0 -1
- package/dist/schemas-BAEbjFPE.js.map +0 -1
- package/dist/schemas-DIyHm5pa.cjs.map +0 -1
package/dist/simrel.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as P, p as j, q as M, c as N, a as
|
|
1
|
+
import { b as P, p as j, q as M, c as N, a as I, v as B, x as q, r as z, o as b, s as h, f as H, e as $, _ as x, y as E, B as F, t as J, z as W, j as v, A as Q, C as V, g as Y, i as k, h as _, w as S, k as K, l as X, m as Z } from "./schemas-D1Kd4wn8.js";
|
|
2
2
|
import { a as ee, c as te, b as ne, f as T, d as re } from "./quantity-stepper-BKtPQUR1.js";
|
|
3
3
|
function R(n) {
|
|
4
4
|
const e = [];
|
|
@@ -16,8 +16,8 @@ function L(n) {
|
|
|
16
16
|
async function ie(n, e) {
|
|
17
17
|
const t = [], r = {
|
|
18
18
|
onEvent: (i) => {
|
|
19
|
-
const
|
|
20
|
-
!
|
|
19
|
+
const a = I(i);
|
|
20
|
+
!a || a.type !== "ui_spec" || t.push(...R(a.spec.elements));
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
return e !== void 0 && (r.signal = e), await N(n, r), t;
|
|
@@ -29,66 +29,70 @@ async function oe(n, e, t) {
|
|
|
29
29
|
body: JSON.stringify(n)
|
|
30
30
|
};
|
|
31
31
|
t !== void 0 && (i.signal = t);
|
|
32
|
-
const
|
|
33
|
-
if (!
|
|
34
|
-
throw new Error(`HTTP ${
|
|
35
|
-
if (L(
|
|
36
|
-
return ie(
|
|
37
|
-
const
|
|
38
|
-
if (!
|
|
32
|
+
const a = await fetch(r, i);
|
|
33
|
+
if (!a.ok)
|
|
34
|
+
throw new Error(`HTTP ${a.status}: ${a.statusText}`);
|
|
35
|
+
if (L(a))
|
|
36
|
+
return ie(a, t);
|
|
37
|
+
const s = await a.text();
|
|
38
|
+
if (!s) return [];
|
|
39
39
|
try {
|
|
40
|
-
return j(JSON.parse(
|
|
40
|
+
return j(JSON.parse(s));
|
|
41
41
|
} catch {
|
|
42
42
|
throw new Error("Invalid JSON from similar_products endpoint");
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
async function
|
|
45
|
+
async function ae(n, e) {
|
|
46
46
|
const t = [];
|
|
47
47
|
let r = null;
|
|
48
48
|
const i = {
|
|
49
|
-
onEvent: (
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
52
|
-
if (
|
|
53
|
-
const p =
|
|
49
|
+
onEvent: (a) => {
|
|
50
|
+
const s = I(a);
|
|
51
|
+
if (s) {
|
|
52
|
+
if (s.type === "metadata" && s.meta) {
|
|
53
|
+
const p = s.meta.group_name;
|
|
54
54
|
if (typeof p == "string") {
|
|
55
55
|
r = { name: p, products: [] };
|
|
56
|
-
const
|
|
57
|
-
typeof
|
|
56
|
+
const d = s.meta.highlight;
|
|
57
|
+
typeof d == "string" && (r.highlight = d), t.push(r);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
s.type === "ui_spec" && r && r.products.push(...R(s.spec.elements));
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
return e !== void 0 && (i.signal = e), await N(n, i), t;
|
|
65
65
|
}
|
|
66
|
-
async function
|
|
66
|
+
async function se(n, e, t) {
|
|
67
67
|
const r = P("product_groupings", e), i = {
|
|
68
68
|
method: "POST",
|
|
69
69
|
headers: { "Content-Type": "application/json" },
|
|
70
70
|
body: JSON.stringify(n)
|
|
71
71
|
};
|
|
72
72
|
t !== void 0 && (i.signal = t);
|
|
73
|
-
const
|
|
74
|
-
if (!
|
|
75
|
-
throw new Error(`HTTP ${
|
|
76
|
-
if (L(
|
|
77
|
-
return
|
|
78
|
-
const
|
|
79
|
-
if (!
|
|
73
|
+
const a = await fetch(r, i);
|
|
74
|
+
if (!a.ok)
|
|
75
|
+
throw new Error(`HTTP ${a.status}: ${a.statusText}`);
|
|
76
|
+
if (L(a))
|
|
77
|
+
return ae(a, t);
|
|
78
|
+
const s = await a.text();
|
|
79
|
+
if (!s) return [];
|
|
80
80
|
try {
|
|
81
|
-
return M(JSON.parse(
|
|
81
|
+
return M(JSON.parse(s));
|
|
82
82
|
} catch {
|
|
83
83
|
throw new Error("Invalid JSON from product_groupings endpoint");
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
function U(n) {
|
|
87
|
-
const { product: e, index: t, discountType: r, onClick: i, onAddToCart:
|
|
88
|
-
if (
|
|
87
|
+
const { product: e, index: t, discountType: r, onClick: i, onAddToCart: a, renderCard: s } = n, p = n.i18n, d = n.pricing;
|
|
88
|
+
if (n.renderCardElement) {
|
|
89
|
+
const o = n.renderCardElement(e, t);
|
|
90
|
+
if (o) return o;
|
|
91
|
+
}
|
|
92
|
+
if (s) {
|
|
89
93
|
const o = document.createElement("div");
|
|
90
|
-
return o.className = "gengage-simrel-card gengage-simrel-card--custom", o.innerHTML = B(
|
|
91
|
-
|
|
94
|
+
return o.className = "gengage-simrel-card gengage-simrel-card--custom", o.innerHTML = B(s(e, t)), o.addEventListener("click", (f) => {
|
|
95
|
+
f.target.closest(".gengage-simrel-atc") || f.target.closest(".gengage-chat-product-card-atc") || i(e);
|
|
92
96
|
}), o;
|
|
93
97
|
}
|
|
94
98
|
const u = document.createElement("article");
|
|
@@ -108,40 +112,40 @@ function U(n) {
|
|
|
108
112
|
const o = document.createElement("div");
|
|
109
113
|
o.className = "gengage-simrel-card-brand gengage-chat-product-card-brand", o.textContent = e.brand, g.appendChild(o);
|
|
110
114
|
}
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
115
|
+
const m = document.createElement("div");
|
|
116
|
+
if (m.className = "gengage-simrel-card-name gengage-chat-product-card-name", m.textContent = e.name, g.appendChild(m), e.rating != null && e.rating > 0) {
|
|
113
117
|
const o = document.createElement("div");
|
|
114
118
|
if (o.className = "gengage-simrel-card-rating gengage-chat-product-card-rating", o.appendChild(ne(e.rating)), e.reviewCount != null) {
|
|
115
|
-
const
|
|
116
|
-
|
|
119
|
+
const f = document.createElement("span");
|
|
120
|
+
f.className = "gengage-simrel-card-review-count gengage-chat-product-card-review-count", f.textContent = ` (${e.reviewCount})`, o.appendChild(f);
|
|
117
121
|
}
|
|
118
122
|
g.appendChild(o);
|
|
119
123
|
}
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
124
|
+
const C = document.createElement("div");
|
|
125
|
+
if (C.className = "gengage-simrel-card-price gengage-chat-product-card-price", e.originalPrice && e.originalPrice !== e.price && (r === "strike-through" || !r)) {
|
|
122
126
|
const o = document.createElement("span");
|
|
123
|
-
o.className = "gengage-simrel-card-price-original gengage-chat-product-card-original-price", o.textContent = T(e.originalPrice,
|
|
127
|
+
o.className = "gengage-simrel-card-price-original gengage-chat-product-card-original-price", o.textContent = T(e.originalPrice, d), C.appendChild(o);
|
|
124
128
|
}
|
|
125
129
|
if (e.price) {
|
|
126
130
|
const o = document.createElement("span");
|
|
127
|
-
o.className = "gengage-simrel-card-price-current gengage-chat-product-card-price-current", o.textContent = T(e.price,
|
|
131
|
+
o.className = "gengage-simrel-card-price-current gengage-chat-product-card-price-current", o.textContent = T(e.price, d), C.appendChild(o);
|
|
128
132
|
}
|
|
129
|
-
g.appendChild(
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
133
|
+
g.appendChild(C), u.appendChild(g);
|
|
134
|
+
const l = document.createElement("button");
|
|
135
|
+
if (l.className = "gengage-simrel-card-cta gengage-chat-product-card-cta", l.type = "button", l.textContent = p?.ctaLabel ?? "View", l.addEventListener("click", (o) => {
|
|
132
136
|
o.preventDefault(), o.stopPropagation(), i(e);
|
|
133
|
-
}), u.appendChild(
|
|
137
|
+
}), u.appendChild(l), e.inStock === !1) {
|
|
134
138
|
const o = document.createElement("div");
|
|
135
139
|
o.className = "gengage-simrel-card-oos", o.textContent = p?.outOfStockLabel ?? "Out of Stock", u.appendChild(o);
|
|
136
140
|
} else if (e.cartCode) {
|
|
137
|
-
const o = e.cartCode,
|
|
141
|
+
const o = e.cartCode, f = re({
|
|
138
142
|
compact: !0,
|
|
139
143
|
label: p?.addToCartButton ?? "Add to Cart",
|
|
140
|
-
onSubmit: (
|
|
141
|
-
|
|
144
|
+
onSubmit: (y) => {
|
|
145
|
+
a({ sku: e.sku, quantity: y, cartCode: o });
|
|
142
146
|
}
|
|
143
147
|
});
|
|
144
|
-
|
|
148
|
+
f.classList.add("gengage-simrel-atc"), u.appendChild(f);
|
|
145
149
|
}
|
|
146
150
|
return u.addEventListener("click", (o) => {
|
|
147
151
|
o.target.closest(".gengage-simrel-atc") || o.target.closest(".gengage-chat-product-card-atc") || o.target.closest(".gengage-chat-product-card-cta") || i(e);
|
|
@@ -157,9 +161,9 @@ function w(n) {
|
|
|
157
161
|
onClick: n.onClick,
|
|
158
162
|
onAddToCart: n.onAddToCart
|
|
159
163
|
};
|
|
160
|
-
n.i18n !== void 0 && (i.i18n = n.i18n), n.discountType !== void 0 && (i.discountType = n.discountType), n.renderCard !== void 0 && (i.renderCard = n.renderCard);
|
|
161
|
-
const
|
|
162
|
-
e.appendChild(
|
|
164
|
+
n.i18n !== void 0 && (i.i18n = n.i18n), n.discountType !== void 0 && (i.discountType = n.discountType), n.renderCard !== void 0 && (i.renderCard = n.renderCard), n.renderCardElement !== void 0 && (i.renderCardElement = n.renderCardElement);
|
|
165
|
+
const a = U(i);
|
|
166
|
+
e.appendChild(a);
|
|
163
167
|
}
|
|
164
168
|
if (n.products.length === 0) {
|
|
165
169
|
const t = document.createElement("div");
|
|
@@ -176,40 +180,40 @@ function de(n) {
|
|
|
176
180
|
}
|
|
177
181
|
const r = document.createElement("div");
|
|
178
182
|
r.className = "gengage-simrel-tabs", r.setAttribute("role", "tablist");
|
|
179
|
-
const i = [],
|
|
183
|
+
const i = [], a = [], s = (c) => {
|
|
180
184
|
const g = {
|
|
181
185
|
products: c.products,
|
|
182
186
|
onClick: n.onClick,
|
|
183
187
|
onAddToCart: n.onAddToCart
|
|
184
188
|
};
|
|
185
|
-
return n.i18n !== void 0 && (g.i18n = n.i18n), n.discountType !== void 0 && (g.discountType = n.discountType), n.renderCard !== void 0 && (g.renderCard = n.renderCard), g;
|
|
189
|
+
return n.i18n !== void 0 && (g.i18n = n.i18n), n.discountType !== void 0 && (g.discountType = n.discountType), n.renderCard !== void 0 && (g.renderCard = n.renderCard), n.renderCardElement !== void 0 && (g.renderCardElement = n.renderCardElement), g;
|
|
186
190
|
}, p = (c) => {
|
|
187
|
-
for (let
|
|
188
|
-
const o =
|
|
189
|
-
i[
|
|
191
|
+
for (let l = 0; l < i.length; l++) {
|
|
192
|
+
const o = l === c;
|
|
193
|
+
i[l].classList.toggle("gengage-simrel-tab--active", o), i[l].setAttribute("aria-selected", String(o)), i[l].tabIndex = o ? 0 : -1;
|
|
190
194
|
}
|
|
191
|
-
const g = n.groups[c],
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
for (let
|
|
196
|
-
const o =
|
|
197
|
-
|
|
195
|
+
const g = n.groups[c], m = a[c];
|
|
196
|
+
m.innerHTML = "";
|
|
197
|
+
const C = w(s(g));
|
|
198
|
+
m.appendChild(C);
|
|
199
|
+
for (let l = 0; l < a.length; l++) {
|
|
200
|
+
const o = l === c;
|
|
201
|
+
a[l].style.display = o ? "" : "none", a[l].tabIndex = o ? 0 : -1;
|
|
198
202
|
}
|
|
199
203
|
};
|
|
200
204
|
for (let c = 0; c < n.groups.length; c++) {
|
|
201
|
-
const g = n.groups[c],
|
|
202
|
-
|
|
203
|
-
let
|
|
204
|
-
|
|
205
|
-
}), i.push(
|
|
205
|
+
const g = n.groups[c], m = `gengage-simrel-tab-${e}-${c}`, C = `gengage-simrel-panel-${e}-${c}`, l = document.createElement("button");
|
|
206
|
+
l.className = "gengage-simrel-tab", l.type = "button", l.id = m, l.textContent = g.name, l.setAttribute("role", "tab"), l.setAttribute("aria-controls", C), l.setAttribute("aria-selected", String(c === 0)), l.tabIndex = c === 0 ? 0 : -1, c === 0 && l.classList.add("gengage-simrel-tab--active"), l.addEventListener("click", () => p(c)), l.addEventListener("keydown", (f) => {
|
|
207
|
+
let y = -1;
|
|
208
|
+
f.key === "ArrowRight" || f.key === "ArrowDown" ? y = (c + 1) % n.groups.length : f.key === "ArrowLeft" || f.key === "ArrowUp" ? y = (c - 1 + n.groups.length) % n.groups.length : f.key === "Home" ? y = 0 : f.key === "End" && (y = n.groups.length - 1), y >= 0 && (f.preventDefault(), p(y), i[y].focus());
|
|
209
|
+
}), i.push(l), r.appendChild(l);
|
|
206
210
|
const o = document.createElement("div");
|
|
207
|
-
o.className = "gengage-simrel-tab-panel", o.id =
|
|
211
|
+
o.className = "gengage-simrel-tab-panel", o.id = C, o.setAttribute("role", "tabpanel"), o.setAttribute("aria-labelledby", m), o.tabIndex = c === 0 ? 0 : -1, c !== 0 && (o.style.display = "none"), a.push(o);
|
|
208
212
|
}
|
|
209
213
|
t.appendChild(r);
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
for (const c of
|
|
214
|
+
const d = a[0], u = w(s(n.groups[0]));
|
|
215
|
+
d.appendChild(u);
|
|
216
|
+
for (const c of a) t.appendChild(c);
|
|
213
217
|
return t;
|
|
214
218
|
}
|
|
215
219
|
function A(n) {
|
|
@@ -225,20 +229,22 @@ function A(n) {
|
|
|
225
229
|
typeof r == "string" && (t.imageUrl = r);
|
|
226
230
|
const i = e.price;
|
|
227
231
|
typeof i == "string" && (t.price = i);
|
|
228
|
-
const
|
|
229
|
-
typeof
|
|
230
|
-
const
|
|
231
|
-
typeof
|
|
232
|
+
const a = e.originalPrice;
|
|
233
|
+
typeof a == "string" && (t.originalPrice = a);
|
|
234
|
+
const s = e.discountPercent;
|
|
235
|
+
typeof s == "number" && (t.discountPercent = s);
|
|
232
236
|
const p = e.brand;
|
|
233
237
|
typeof p == "string" && (t.brand = p);
|
|
234
|
-
const
|
|
235
|
-
typeof
|
|
238
|
+
const d = e.rating;
|
|
239
|
+
typeof d == "number" && (t.rating = d);
|
|
236
240
|
const u = e.reviewCount;
|
|
237
241
|
typeof u == "number" && (t.reviewCount = u);
|
|
238
242
|
const c = e.cartCode;
|
|
239
243
|
typeof c == "string" && (t.cartCode = c);
|
|
240
244
|
const g = e.inStock;
|
|
241
|
-
|
|
245
|
+
typeof g == "boolean" && (t.inStock = g);
|
|
246
|
+
const m = e.extras;
|
|
247
|
+
return m != null && typeof m == "object" && (t.extras = m), t;
|
|
242
248
|
}
|
|
243
249
|
function le(n) {
|
|
244
250
|
if (!n || typeof n != "object") return null;
|
|
@@ -253,47 +259,47 @@ const O = {
|
|
|
253
259
|
r.className = "gengage-simrel-grid", r.setAttribute("role", "list");
|
|
254
260
|
const i = n.props?.columns;
|
|
255
261
|
typeof i == "number" && Number.isFinite(i) && i > 0 && r.style.setProperty("--gengage-simrel-columns", String(i));
|
|
256
|
-
for (const
|
|
257
|
-
const
|
|
258
|
-
|
|
262
|
+
for (const a of n.children ?? []) {
|
|
263
|
+
const s = e(a);
|
|
264
|
+
s && r.appendChild(s);
|
|
259
265
|
}
|
|
260
266
|
if (r.children.length === 0) {
|
|
261
|
-
const
|
|
262
|
-
|
|
267
|
+
const a = document.createElement("div");
|
|
268
|
+
a.className = "gengage-simrel-empty", a.textContent = t.i18n.emptyStateMessage, r.appendChild(a);
|
|
263
269
|
}
|
|
264
270
|
return r;
|
|
265
271
|
},
|
|
266
272
|
ProductCard: ({ element: n, context: e }) => {
|
|
267
273
|
const t = n.props?.product ?? n.props, r = A(t);
|
|
268
274
|
if (!r) return null;
|
|
269
|
-
const i = n.props?.index,
|
|
275
|
+
const i = n.props?.index, a = typeof i == "number" && Number.isFinite(i) ? i : 0, s = n.props?.discountType, p = s === "strike-through" || s === "badge" ? s : e.discountType, d = {
|
|
270
276
|
product: r,
|
|
271
|
-
index:
|
|
277
|
+
index: a,
|
|
272
278
|
onClick: e.onClick,
|
|
273
279
|
onAddToCart: e.onAddToCart,
|
|
274
280
|
i18n: e.i18n
|
|
275
281
|
};
|
|
276
|
-
return p !== void 0 && (
|
|
282
|
+
return p !== void 0 && (d.discountType = p), e.renderCard !== void 0 && (d.renderCard = e.renderCard), e.renderCardElement !== void 0 && (d.renderCardElement = e.renderCardElement), e.pricing !== void 0 && (d.pricing = e.pricing), U(d);
|
|
277
283
|
},
|
|
278
284
|
GroupTabs: ({ element: n, context: e }) => {
|
|
279
285
|
const t = n.props?.groups;
|
|
280
286
|
if (!Array.isArray(t)) return null;
|
|
281
287
|
const r = [];
|
|
282
|
-
for (const
|
|
283
|
-
if (!
|
|
284
|
-
const
|
|
285
|
-
if (typeof
|
|
288
|
+
for (const a of t) {
|
|
289
|
+
if (!a || typeof a != "object") continue;
|
|
290
|
+
const s = a;
|
|
291
|
+
if (typeof s.name != "string") continue;
|
|
286
292
|
const p = [];
|
|
287
|
-
if (Array.isArray(
|
|
288
|
-
for (const u of
|
|
293
|
+
if (Array.isArray(s.products))
|
|
294
|
+
for (const u of s.products) {
|
|
289
295
|
const c = A(u);
|
|
290
296
|
c && p.push(c);
|
|
291
297
|
}
|
|
292
|
-
const
|
|
293
|
-
name:
|
|
298
|
+
const d = {
|
|
299
|
+
name: s.name,
|
|
294
300
|
products: p
|
|
295
301
|
};
|
|
296
|
-
typeof
|
|
302
|
+
typeof s.highlight == "string" && (d.highlight = s.highlight), r.push(d);
|
|
297
303
|
}
|
|
298
304
|
const i = {
|
|
299
305
|
groups: r,
|
|
@@ -301,7 +307,7 @@ const O = {
|
|
|
301
307
|
onAddToCart: e.onAddToCart,
|
|
302
308
|
i18n: e.i18n
|
|
303
309
|
};
|
|
304
|
-
return e.discountType !== void 0 && (i.discountType = e.discountType), e.renderCard !== void 0 && (i.renderCard = e.renderCard), de(i);
|
|
310
|
+
return e.discountType !== void 0 && (i.discountType = e.discountType), e.renderCard !== void 0 && (i.renderCard = e.renderCard), e.renderCardElement !== void 0 && (i.renderCardElement = e.renderCardElement), de(i);
|
|
305
311
|
},
|
|
306
312
|
EmptyState: ({ element: n, context: e }) => {
|
|
307
313
|
const t = document.createElement("div");
|
|
@@ -314,9 +320,9 @@ const O = {
|
|
|
314
320
|
if (typeof t != "string" || typeof r != "string") return null;
|
|
315
321
|
const i = document.createElement("button");
|
|
316
322
|
i.className = "gengage-simrel-atc gengage-chat-product-card-cta", i.type = "button";
|
|
317
|
-
const
|
|
318
|
-
return i.textContent = typeof
|
|
319
|
-
|
|
323
|
+
const a = n.props?.label;
|
|
324
|
+
return i.textContent = typeof a == "string" ? a : e.i18n.addToCartButton, i.addEventListener("click", (s) => {
|
|
325
|
+
s.preventDefault(), s.stopPropagation(), e.onAddToCart({ sku: t, quantity: 1, cartCode: r });
|
|
320
326
|
}), i;
|
|
321
327
|
},
|
|
322
328
|
QuickActions: ({ element: n, context: e }) => {
|
|
@@ -326,12 +332,12 @@ const O = {
|
|
|
326
332
|
if (!Array.isArray(r) || !e.onAction) return t;
|
|
327
333
|
for (const i of r) {
|
|
328
334
|
if (!i || typeof i != "object") continue;
|
|
329
|
-
const
|
|
330
|
-
if (typeof
|
|
331
|
-
const
|
|
332
|
-
|
|
335
|
+
const a = i, s = a.label, p = le(a.action);
|
|
336
|
+
if (typeof s != "string" || !p) continue;
|
|
337
|
+
const d = document.createElement("button");
|
|
338
|
+
d.className = "gengage-simrel-quick-action", d.type = "button", d.textContent = s, d.addEventListener("click", (u) => {
|
|
333
339
|
u.preventDefault(), u.stopPropagation(), e.onAction?.(p);
|
|
334
|
-
}), t.appendChild(
|
|
340
|
+
}), t.appendChild(d);
|
|
335
341
|
}
|
|
336
342
|
return t;
|
|
337
343
|
}
|
|
@@ -382,48 +388,48 @@ function fe(n) {
|
|
|
382
388
|
return me(n) === "en" ? pe : D;
|
|
383
389
|
}
|
|
384
390
|
const he = b({
|
|
385
|
-
sku:
|
|
386
|
-
name:
|
|
387
|
-
imageUrl:
|
|
388
|
-
price:
|
|
389
|
-
originalPrice:
|
|
390
|
-
discountPercent:
|
|
391
|
-
url:
|
|
392
|
-
brand:
|
|
393
|
-
rating:
|
|
394
|
-
reviewCount:
|
|
395
|
-
}), ye = b({
|
|
396
|
-
layout: I(["grid", "carousel"]).optional(),
|
|
397
|
-
columns: v().int().positive().optional()
|
|
391
|
+
sku: h(),
|
|
392
|
+
name: h(),
|
|
393
|
+
imageUrl: h().url().optional(),
|
|
394
|
+
price: h().optional(),
|
|
395
|
+
originalPrice: h().optional(),
|
|
396
|
+
discountPercent: E().optional(),
|
|
397
|
+
url: h().url(),
|
|
398
|
+
brand: h().optional(),
|
|
399
|
+
rating: E().min(0).max(5).optional(),
|
|
400
|
+
reviewCount: E().int().nonnegative().optional()
|
|
398
401
|
}), Ce = b({
|
|
402
|
+
layout: x(["grid", "carousel"]).optional(),
|
|
403
|
+
columns: E().int().positive().optional()
|
|
404
|
+
}), ye = b({
|
|
399
405
|
product: he,
|
|
400
|
-
index:
|
|
401
|
-
discountType:
|
|
406
|
+
index: E().int().nonnegative(),
|
|
407
|
+
discountType: x(["strike-through", "badge"]).optional()
|
|
402
408
|
}), be = b({
|
|
403
|
-
sku:
|
|
404
|
-
label:
|
|
405
|
-
cartCode:
|
|
406
|
-
}),
|
|
409
|
+
sku: h(),
|
|
410
|
+
label: h().optional(),
|
|
411
|
+
cartCode: h()
|
|
412
|
+
}), Ee = b({
|
|
407
413
|
actions: H(
|
|
408
414
|
b({
|
|
409
|
-
label:
|
|
415
|
+
label: h(),
|
|
410
416
|
action: b({
|
|
411
|
-
title:
|
|
412
|
-
type:
|
|
417
|
+
title: h(),
|
|
418
|
+
type: h(),
|
|
413
419
|
payload: $().optional()
|
|
414
420
|
})
|
|
415
421
|
})
|
|
416
422
|
)
|
|
417
|
-
}),
|
|
418
|
-
message:
|
|
423
|
+
}), ve = b({
|
|
424
|
+
message: h().optional()
|
|
419
425
|
}), Te = {
|
|
420
426
|
components: {
|
|
421
427
|
ProductGrid: {
|
|
422
|
-
schema:
|
|
428
|
+
schema: Ce,
|
|
423
429
|
description: "Outer grid or carousel container for similar products."
|
|
424
430
|
},
|
|
425
431
|
ProductCard: {
|
|
426
|
-
schema:
|
|
432
|
+
schema: ye,
|
|
427
433
|
description: "A single product card with image, title, price, and actions."
|
|
428
434
|
},
|
|
429
435
|
AddToCartButton: {
|
|
@@ -431,11 +437,11 @@ const he = b({
|
|
|
431
437
|
description: "Add-to-cart CTA rendered inside or below a product card."
|
|
432
438
|
},
|
|
433
439
|
QuickActions: {
|
|
434
|
-
schema:
|
|
440
|
+
schema: Ee,
|
|
435
441
|
description: "A row of quick-action buttons below product info."
|
|
436
442
|
},
|
|
437
443
|
EmptyState: {
|
|
438
|
-
schema:
|
|
444
|
+
schema: ve,
|
|
439
445
|
description: "Empty state shown when no similar products are available."
|
|
440
446
|
}
|
|
441
447
|
}
|
|
@@ -473,14 +479,14 @@ class ke extends F {
|
|
|
473
479
|
if (e.imageUrl !== void 0 && (t.imageUrl = e.imageUrl), e.price !== void 0 && (t.price = e.price), e.originalPrice !== void 0 && (t.originalPrice = e.originalPrice), e.discountPercent !== void 0 && (t.discountPercent = e.discountPercent), e.brand !== void 0 && (t.brand = e.brand), e.rating !== void 0 && (t.rating = e.rating), e.reviewCount !== void 0 && (t.reviewCount = e.reviewCount), e.cartCode !== void 0 && (t.cartCode = e.cartCode), e.inStock !== void 0 && (t.inStock = e.inStock), this.config.onProductClick?.(t) === !1) return;
|
|
474
480
|
W(e.sku, e.name);
|
|
475
481
|
const r = this.config.session?.sessionId ?? null;
|
|
476
|
-
|
|
482
|
+
v("gengage:similar:product-click", {
|
|
477
483
|
sku: e.sku,
|
|
478
484
|
url: e.url,
|
|
479
485
|
sessionId: r
|
|
480
486
|
}), this.config.onProductNavigate?.(e.url, e.sku, r);
|
|
481
487
|
}
|
|
482
488
|
_handleAddToCart(e) {
|
|
483
|
-
Q(e.sku, e.quantity), this.config.onAddToCart?.(e),
|
|
489
|
+
Q(e.sku, e.quantity), this.config.onAddToCart?.(e), v("gengage:similar:add-to-cart", e), this.track(
|
|
484
490
|
V(this.analyticsContext(), {
|
|
485
491
|
attribution_source: "simrel",
|
|
486
492
|
attribution_action_id: crypto.randomUUID(),
|
|
@@ -507,51 +513,51 @@ class ke extends F {
|
|
|
507
513
|
r.className = "gengage-simrel-loading";
|
|
508
514
|
const i = document.createElement("div");
|
|
509
515
|
i.className = "gengage-simrel-spinner", r.appendChild(i), this._contentEl.appendChild(r);
|
|
510
|
-
const
|
|
516
|
+
const a = {
|
|
511
517
|
middlewareUrl: this.config.middlewareUrl
|
|
512
|
-
},
|
|
518
|
+
}, s = crypto.randomUUID(), p = Date.now();
|
|
513
519
|
this.track(
|
|
514
520
|
Y(this.analyticsContext(), {
|
|
515
521
|
endpoint: "similar_products",
|
|
516
|
-
request_id:
|
|
522
|
+
request_id: s,
|
|
517
523
|
widget: "simrel"
|
|
518
524
|
})
|
|
519
525
|
);
|
|
520
526
|
try {
|
|
521
|
-
const
|
|
527
|
+
const d = {
|
|
522
528
|
account_id: this.config.accountId,
|
|
523
529
|
session_id: this.config.session?.sessionId ?? "",
|
|
524
530
|
correlation_id: this.config.session?.sessionId ?? "",
|
|
525
531
|
sku: e
|
|
526
532
|
};
|
|
527
|
-
this.config.domain !== void 0 && (
|
|
528
|
-
const u = await oe(
|
|
533
|
+
this.config.domain !== void 0 && (d.domain = this.config.domain);
|
|
534
|
+
const u = await oe(d, a, t);
|
|
529
535
|
if (!this._contentEl) return;
|
|
530
536
|
if (this._contentEl.innerHTML = "", u.length > 0)
|
|
531
537
|
try {
|
|
532
|
-
const c = u.map((
|
|
538
|
+
const c = u.map((m) => m.sku), g = await se(
|
|
533
539
|
{
|
|
534
540
|
account_id: this.config.accountId,
|
|
535
541
|
session_id: this.config.session?.sessionId ?? "",
|
|
536
542
|
correlation_id: this.config.session?.sessionId ?? "",
|
|
537
543
|
skus: c
|
|
538
544
|
},
|
|
539
|
-
|
|
545
|
+
a,
|
|
540
546
|
t
|
|
541
547
|
);
|
|
542
548
|
if (g.length > 0 && this._contentEl) {
|
|
543
|
-
const
|
|
544
|
-
this._contentEl.appendChild(
|
|
549
|
+
const m = this._buildGroupsSpec(g), C = this._renderUISpec(m);
|
|
550
|
+
this._contentEl.appendChild(C), k("simrel"), this.track(
|
|
545
551
|
_(this.analyticsContext(), {
|
|
546
|
-
request_id:
|
|
552
|
+
request_id: s,
|
|
547
553
|
latency_ms: Date.now() - p,
|
|
548
|
-
chunk_count: g.reduce((
|
|
554
|
+
chunk_count: g.reduce((l, o) => l + o.products.length, 0),
|
|
549
555
|
widget: "simrel"
|
|
550
556
|
})
|
|
551
557
|
), this.track(
|
|
552
558
|
S(this.analyticsContext(), {
|
|
553
|
-
message_count: g.reduce((
|
|
554
|
-
history_ref:
|
|
559
|
+
message_count: g.reduce((l, o) => l + o.products.length, 0),
|
|
560
|
+
history_ref: s,
|
|
555
561
|
redaction_level: "none",
|
|
556
562
|
widget: "simrel"
|
|
557
563
|
})
|
|
@@ -566,7 +572,7 @@ class ke extends F {
|
|
|
566
572
|
}
|
|
567
573
|
u.length > 0 && k("simrel"), this.track(
|
|
568
574
|
_(this.analyticsContext(), {
|
|
569
|
-
request_id:
|
|
575
|
+
request_id: s,
|
|
570
576
|
latency_ms: Date.now() - p,
|
|
571
577
|
chunk_count: u.length,
|
|
572
578
|
widget: "simrel"
|
|
@@ -574,22 +580,22 @@ class ke extends F {
|
|
|
574
580
|
), this.track(
|
|
575
581
|
S(this.analyticsContext(), {
|
|
576
582
|
message_count: u.length,
|
|
577
|
-
history_ref:
|
|
583
|
+
history_ref: s,
|
|
578
584
|
redaction_level: "none",
|
|
579
585
|
widget: "simrel"
|
|
580
586
|
})
|
|
581
587
|
);
|
|
582
|
-
} catch (
|
|
583
|
-
if (
|
|
584
|
-
if (
|
|
588
|
+
} catch (d) {
|
|
589
|
+
if (d instanceof DOMException && d.name === "AbortError") return;
|
|
590
|
+
if (v("gengage:global:error", {
|
|
585
591
|
source: "simrel",
|
|
586
592
|
code: "FETCH_ERROR",
|
|
587
593
|
message: K(this.config.locale)
|
|
588
594
|
}), this.track(
|
|
589
595
|
X(this.analyticsContext(), {
|
|
590
|
-
request_id:
|
|
596
|
+
request_id: s,
|
|
591
597
|
error_code: "FETCH_ERROR",
|
|
592
|
-
error_message:
|
|
598
|
+
error_message: d instanceof Error ? d.message : String(d),
|
|
593
599
|
widget: "simrel"
|
|
594
600
|
})
|
|
595
601
|
), this._contentEl) {
|
|
@@ -618,24 +624,24 @@ class ke extends F {
|
|
|
618
624
|
onAddToCart: (r) => this._handleAddToCart(r),
|
|
619
625
|
i18n: this._i18n
|
|
620
626
|
};
|
|
621
|
-
return this.config.discountType !== void 0 && (t.discountType = this.config.discountType), e !== void 0 && (t.renderCard = e), this.config.pricing !== void 0 && (t.pricing = this.config.pricing), t;
|
|
627
|
+
return this.config.discountType !== void 0 && (t.discountType = this.config.discountType), e !== void 0 && (t.renderCard = e), this.config.renderCardElement !== void 0 && (t.renderCardElement = this.config.renderCardElement), this.config.pricing !== void 0 && (t.pricing = this.config.pricing), t;
|
|
622
628
|
}
|
|
623
629
|
_renderUISpec(e) {
|
|
624
|
-
const t = this._resolveUISpecRegistry(), r = this._buildRenderContext(), i = this.config.renderer?.unknownRenderer ?? G,
|
|
625
|
-
return
|
|
630
|
+
const t = this._resolveUISpecRegistry(), r = this._buildRenderContext(), i = this.config.renderer?.unknownRenderer ?? G, a = (d, u) => ge(d, u, t, i), s = this.config.renderer?.renderUISpec;
|
|
631
|
+
return s ? s(e, r, {
|
|
626
632
|
registry: t,
|
|
627
633
|
unknownRenderer: i,
|
|
628
|
-
defaultRender:
|
|
629
|
-
}) :
|
|
634
|
+
defaultRender: a
|
|
635
|
+
}) : a(e, r);
|
|
630
636
|
}
|
|
631
637
|
_buildProductsSpec(e) {
|
|
632
638
|
const t = {}, r = [];
|
|
633
639
|
for (let i = 0; i < e.length; i++) {
|
|
634
|
-
const
|
|
635
|
-
r.push(
|
|
640
|
+
const a = e[i], s = `product-${i}`;
|
|
641
|
+
r.push(s), t[s] = {
|
|
636
642
|
type: "ProductCard",
|
|
637
643
|
props: {
|
|
638
|
-
product:
|
|
644
|
+
product: a,
|
|
639
645
|
index: i,
|
|
640
646
|
discountType: this.config.discountType
|
|
641
647
|
}
|