ttp-agent-sdk 2.34.10 → 2.34.13
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/agent-widget.dev.js +16173 -17322
- package/dist/agent-widget.dev.js.map +1 -1
- package/dist/agent-widget.esm.js +1 -1
- package/dist/agent-widget.esm.js.LICENSE.txt +0 -10
- package/dist/agent-widget.esm.js.map +1 -1
- package/dist/agent-widget.js +1 -1
- package/dist/agent-widget.js.LICENSE.txt +0 -20
- package/dist/agent-widget.js.map +1 -1
- package/dist/demos/index.html +15 -0
- package/dist/demos/test-ecommerce.html +436 -0
- package/dist/demos/test-widget.html +11 -0
- package/dist/examples/test-ecommerce.html +436 -0
- package/dist/examples/test-index.html +15 -0
- package/dist/examples/test-text-chat.html +4 -4
- package/dist/examples/test-widget.html +11 -0
- package/examples/test-ecommerce.html +436 -0
- package/examples/test-index.html +15 -0
- package/examples/test-text-chat.html +4 -4
- package/examples/test-widget.html +11 -0
- package/package.json +1 -1
package/dist/demos/index.html
CHANGED
|
@@ -301,6 +301,21 @@
|
|
|
301
301
|
<span class="badge" style="background: #fef3c7; color: #92400e;">Debug</span>
|
|
302
302
|
</div>
|
|
303
303
|
</a>
|
|
304
|
+
|
|
305
|
+
<a href="../examples/test-ecommerce.html" class="test-card">
|
|
306
|
+
<span class="test-card__icon">🛒</span>
|
|
307
|
+
<h3 class="test-card__title">E-Commerce Widget Test</h3>
|
|
308
|
+
<p class="test-card__description">
|
|
309
|
+
Test the TTPEcommerceWidget — a composition wrapper around TTPChatWidget
|
|
310
|
+
that adds product display, cart management, and partner integration.
|
|
311
|
+
Simulate show_products and cart_updated messages without a live voice call.
|
|
312
|
+
</p>
|
|
313
|
+
<div class="test-card__badges">
|
|
314
|
+
<span class="badge badge--widget">Widget</span>
|
|
315
|
+
<span class="badge badge--voice">Voice</span>
|
|
316
|
+
<span class="badge badge--new">E-Commerce</span>
|
|
317
|
+
</div>
|
|
318
|
+
</a>
|
|
304
319
|
</div>
|
|
305
320
|
</div>
|
|
306
321
|
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
6
|
+
<title>TTP E-Commerce Widget - Test</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
10
|
+
max-width: 1200px;
|
|
11
|
+
margin: 40px auto;
|
|
12
|
+
padding: 20px;
|
|
13
|
+
background: #F9FAFB;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.container {
|
|
17
|
+
background: white;
|
|
18
|
+
padding: 30px;
|
|
19
|
+
border-radius: 12px;
|
|
20
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
h1 { color: #111827; margin-top: 0; }
|
|
24
|
+
h2 { color: #374151; border-bottom: 2px solid #E5E7EB; padding-bottom: 8px; margin-top: 30px; }
|
|
25
|
+
|
|
26
|
+
.info {
|
|
27
|
+
background: #EFF6FF;
|
|
28
|
+
border-left: 4px solid #3B82F6;
|
|
29
|
+
padding: 16px;
|
|
30
|
+
margin: 20px 0;
|
|
31
|
+
border-radius: 4px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.status {
|
|
35
|
+
margin: 20px 0;
|
|
36
|
+
padding: 12px;
|
|
37
|
+
background: #F3F4F6;
|
|
38
|
+
border-radius: 6px;
|
|
39
|
+
font-family: monospace;
|
|
40
|
+
font-size: 14px;
|
|
41
|
+
}
|
|
42
|
+
.status.success { background: #D1FAE5; color: #065F46; }
|
|
43
|
+
.status.error { background: #FEE2E2; color: #991B1B; }
|
|
44
|
+
|
|
45
|
+
button {
|
|
46
|
+
background: #4F46E5;
|
|
47
|
+
color: white;
|
|
48
|
+
border: none;
|
|
49
|
+
padding: 12px 24px;
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
font-size: 16px;
|
|
53
|
+
margin: 10px 10px 10px 0;
|
|
54
|
+
}
|
|
55
|
+
button:hover { background: #4338CA; }
|
|
56
|
+
button.secondary { background: #6B7280; }
|
|
57
|
+
button.secondary:hover { background: #4B5563; }
|
|
58
|
+
button.success { background: #059669; }
|
|
59
|
+
button.success:hover { background: #047857; }
|
|
60
|
+
button.warning { background: #D97706; }
|
|
61
|
+
button.warning:hover { background: #B45309; }
|
|
62
|
+
|
|
63
|
+
label {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
gap: 4px;
|
|
67
|
+
font-size: 14px;
|
|
68
|
+
color: #374151;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
select, input[type="text"], input[type="number"] {
|
|
72
|
+
padding: 8px 12px;
|
|
73
|
+
border: 1px solid #D1D5DB;
|
|
74
|
+
border-radius: 6px;
|
|
75
|
+
font-size: 14px;
|
|
76
|
+
font-family: inherit;
|
|
77
|
+
background: white;
|
|
78
|
+
color: #111827;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.code-block {
|
|
82
|
+
background: #1F2937;
|
|
83
|
+
color: #F9FAFB;
|
|
84
|
+
padding: 16px;
|
|
85
|
+
border-radius: 6px;
|
|
86
|
+
font-family: monospace;
|
|
87
|
+
font-size: 12px;
|
|
88
|
+
overflow-x: auto;
|
|
89
|
+
margin: 20px 0;
|
|
90
|
+
white-space: pre-wrap;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.settings-grid {
|
|
94
|
+
display: grid;
|
|
95
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
96
|
+
gap: 16px;
|
|
97
|
+
margin: 16px 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.test-section {
|
|
101
|
+
border: 1px solid #E5E7EB;
|
|
102
|
+
border-radius: 8px;
|
|
103
|
+
padding: 20px;
|
|
104
|
+
margin: 16px 0;
|
|
105
|
+
background: #F9FAFB;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.test-section h3 {
|
|
109
|
+
margin: 0 0 12px 0;
|
|
110
|
+
color: #111827;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.cart-display {
|
|
114
|
+
background: #F0FDF4;
|
|
115
|
+
border: 1px solid #BBF7D0;
|
|
116
|
+
border-radius: 8px;
|
|
117
|
+
padding: 16px;
|
|
118
|
+
margin: 16px 0;
|
|
119
|
+
font-family: monospace;
|
|
120
|
+
font-size: 13px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.cart-display pre {
|
|
124
|
+
margin: 0;
|
|
125
|
+
white-space: pre-wrap;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@media (max-width: 768px) {
|
|
129
|
+
body { margin: 0; padding: 10px; }
|
|
130
|
+
.container { padding: 16px; border-radius: 8px; }
|
|
131
|
+
h1 { font-size: 24px; }
|
|
132
|
+
button { width: 100%; margin: 8px 0; }
|
|
133
|
+
.settings-grid { grid-template-columns: 1fr; }
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
136
|
+
</head>
|
|
137
|
+
<body>
|
|
138
|
+
<div class="container">
|
|
139
|
+
<h1>🛒 TTP E-Commerce Widget Test</h1>
|
|
140
|
+
|
|
141
|
+
<div class="info">
|
|
142
|
+
<strong>What is TTPEcommerceWidget?</strong>
|
|
143
|
+
<ul>
|
|
144
|
+
<li>Wraps the standard TTPChatWidget with an e-commerce layer</li>
|
|
145
|
+
<li>Displays product cards when the agent sends <code>show_products</code> messages</li>
|
|
146
|
+
<li>Manages a local cart with toast notifications and cart summary</li>
|
|
147
|
+
<li>Supports partner integration via <code>addToCartFn</code> / <code>getCartFn</code> callbacks</li>
|
|
148
|
+
<li>Test API available at <code>window.__TTP_ECOMMERCE__</code></li>
|
|
149
|
+
</ul>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<div id="status" class="status">Loading SDK...</div>
|
|
153
|
+
|
|
154
|
+
<h2>Widget Configuration</h2>
|
|
155
|
+
<div class="settings-grid">
|
|
156
|
+
<label>Agent
|
|
157
|
+
<select id="agentSelect" onchange="handleAgentChange()">
|
|
158
|
+
<option value="agent_87c4a55a1|app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC|en|ltr">e-commerce_english (agent_87c4a55a1)</option>
|
|
159
|
+
<option value="agent_ed18369b3|app_wNGQKiMUfUT5JdVIaxzXOJfdcgBegxGY5hZo|he|rtl">e-commerce_hebrew (agent_ed18369b3)</option>
|
|
160
|
+
<option value="agent_d119003d8|app_wNGQKiMUfUT5JdVIaxzXOJfdcgBegxGY5hZo|es|ltr">ecommerce_spanish (agent_d119003d8)</option>
|
|
161
|
+
<option value="custom">Custom...</option>
|
|
162
|
+
</select>
|
|
163
|
+
</label>
|
|
164
|
+
<label id="customAgentLabel" style="display:none">Agent ID
|
|
165
|
+
<input id="customAgentId" type="text" placeholder="agent_..." />
|
|
166
|
+
</label>
|
|
167
|
+
<label id="customAppLabel" style="display:none">App ID
|
|
168
|
+
<input id="customAppId" type="text" placeholder="app_..." />
|
|
169
|
+
</label>
|
|
170
|
+
<label>Language
|
|
171
|
+
<select id="languageSelect">
|
|
172
|
+
<option value="en" selected>English</option>
|
|
173
|
+
<option value="he">Hebrew</option>
|
|
174
|
+
</select>
|
|
175
|
+
</label>
|
|
176
|
+
<label>Direction
|
|
177
|
+
<select id="dirSelect">
|
|
178
|
+
<option value="ltr" selected>LTR</option>
|
|
179
|
+
<option value="rtl">RTL</option>
|
|
180
|
+
</select>
|
|
181
|
+
</label>
|
|
182
|
+
<label>Widget Mode
|
|
183
|
+
<select id="modeSelect">
|
|
184
|
+
<option value="unified" selected>Unified (Both)</option>
|
|
185
|
+
<option value="voice-only">Voice Only</option>
|
|
186
|
+
<option value="text-only">Text Only</option>
|
|
187
|
+
</select>
|
|
188
|
+
</label>
|
|
189
|
+
<label>Start Open
|
|
190
|
+
<select id="startOpenSelect">
|
|
191
|
+
<option value="true" selected>Yes</option>
|
|
192
|
+
<option value="false">No</option>
|
|
193
|
+
</select>
|
|
194
|
+
</label>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div style="margin-top: 16px;">
|
|
198
|
+
<button id="createBtn">Create Widget</button>
|
|
199
|
+
<button id="destroyBtn" class="secondary">Destroy Widget</button>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<h2>E-Commerce Test Actions</h2>
|
|
203
|
+
|
|
204
|
+
<div class="test-section">
|
|
205
|
+
<h3>Show Products (simulated)</h3>
|
|
206
|
+
<p style="color: #6B7280; font-size: 14px; margin-bottom: 12px;">
|
|
207
|
+
Injects a <code>show_products</code> message into the ecommerce layer — no voice call needed.
|
|
208
|
+
</p>
|
|
209
|
+
<div class="settings-grid">
|
|
210
|
+
<label>Search Query
|
|
211
|
+
<input id="productQuery" type="text" value="milk" />
|
|
212
|
+
</label>
|
|
213
|
+
<label>Layout
|
|
214
|
+
<select id="productLayout">
|
|
215
|
+
<option value="auto">Auto (cards ≤4, list 5+)</option>
|
|
216
|
+
<option value="cards">Cards</option>
|
|
217
|
+
<option value="list">List</option>
|
|
218
|
+
</select>
|
|
219
|
+
</label>
|
|
220
|
+
</div>
|
|
221
|
+
<button id="showProductsBtn" class="success">Show Products</button>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<div class="test-section">
|
|
225
|
+
<h3>Cart Updated (simulated)</h3>
|
|
226
|
+
<p style="color: #6B7280; font-size: 14px; margin-bottom: 12px;">
|
|
227
|
+
Injects a <code>cart_updated</code> message to test toast and summary UI.
|
|
228
|
+
</p>
|
|
229
|
+
<button id="cartAddBtn" class="success">Simulate: Product Added</button>
|
|
230
|
+
<button id="cartClearBtn" class="secondary">Clear Cart</button>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="test-section">
|
|
234
|
+
<h3>Cart State</h3>
|
|
235
|
+
<div id="cartDisplay" class="cart-display">
|
|
236
|
+
<pre>No widget created yet</pre>
|
|
237
|
+
</div>
|
|
238
|
+
<button id="refreshCartBtn" class="secondary">Refresh Cart State</button>
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<h2>Console Commands</h2>
|
|
242
|
+
<div class="code-block">// Show products via test API (fetches from mock API)
|
|
243
|
+
window.__TTP_ECOMMERCE__.showProducts('milk');
|
|
244
|
+
window.__TTP_ECOMMERCE__.showProducts('bread', 3);
|
|
245
|
+
|
|
246
|
+
// Inject raw messages
|
|
247
|
+
window.__TTP_ECOMMERCE__.handleMessage({
|
|
248
|
+
t: 'show_products',
|
|
249
|
+
products: [
|
|
250
|
+
{ id: '1', name: 'Test Product', price: 9.99, image: '' }
|
|
251
|
+
],
|
|
252
|
+
title: 'Test Results'
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Cart operations
|
|
256
|
+
window.__TTP_ECOMMERCE__.getCart();
|
|
257
|
+
window.__TTP_ECOMMERCE__.clearCart();</div>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<script src="/dist/agent-widget.js"></script>
|
|
261
|
+
|
|
262
|
+
<script>
|
|
263
|
+
let ecomWidget = null;
|
|
264
|
+
|
|
265
|
+
function updateStatus(msg, type = '') {
|
|
266
|
+
const el = document.getElementById('status');
|
|
267
|
+
el.textContent = msg;
|
|
268
|
+
el.className = 'status ' + type;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function refreshCartDisplay() {
|
|
272
|
+
const el = document.getElementById('cartDisplay');
|
|
273
|
+
if (!window.__TTP_ECOMMERCE__) {
|
|
274
|
+
el.innerHTML = '<pre>No widget created yet</pre>';
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const cart = window.__TTP_ECOMMERCE__.getCart();
|
|
278
|
+
el.innerHTML = '<pre>' + JSON.stringify(cart, null, 2) + '</pre>';
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function handleAgentChange() {
|
|
282
|
+
const sel = document.getElementById('agentSelect');
|
|
283
|
+
const isCustom = sel.value === 'custom';
|
|
284
|
+
document.getElementById('customAgentLabel').style.display = isCustom ? '' : 'none';
|
|
285
|
+
document.getElementById('customAppLabel').style.display = isCustom ? '' : 'none';
|
|
286
|
+
|
|
287
|
+
if (!isCustom) {
|
|
288
|
+
const [, , lang, dir] = sel.value.split('|');
|
|
289
|
+
document.getElementById('languageSelect').value = lang;
|
|
290
|
+
document.getElementById('dirSelect').value = dir;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function getAgentConfig() {
|
|
295
|
+
const sel = document.getElementById('agentSelect');
|
|
296
|
+
if (sel.value === 'custom') {
|
|
297
|
+
return {
|
|
298
|
+
agentId: document.getElementById('customAgentId').value,
|
|
299
|
+
appId: document.getElementById('customAppId').value
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
const [agentId, appId] = sel.value.split('|');
|
|
303
|
+
return { agentId, appId };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function createWidget() {
|
|
307
|
+
if (ecomWidget) {
|
|
308
|
+
ecomWidget.destroy();
|
|
309
|
+
ecomWidget = null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const TTPAgentSDK = window.TTPAgentSDK;
|
|
313
|
+
if (!TTPAgentSDK || !TTPAgentSDK.TTPEcommerceWidget) {
|
|
314
|
+
updateStatus('TTPEcommerceWidget not available in SDK', 'error');
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const agent = getAgentConfig();
|
|
319
|
+
|
|
320
|
+
ecomWidget = new TTPAgentSDK.TTPEcommerceWidget({
|
|
321
|
+
agentId: agent.agentId,
|
|
322
|
+
appId: agent.appId,
|
|
323
|
+
language: document.getElementById('languageSelect').value,
|
|
324
|
+
direction: document.getElementById('dirSelect').value,
|
|
325
|
+
behavior: {
|
|
326
|
+
mode: document.getElementById('modeSelect').value,
|
|
327
|
+
startOpen: document.getElementById('startOpenSelect').value === 'true'
|
|
328
|
+
},
|
|
329
|
+
icon: {
|
|
330
|
+
type: 'custom',
|
|
331
|
+
customImage: 'https://talktopc.com/logo192.png',
|
|
332
|
+
size: 'medium',
|
|
333
|
+
backgroundColor: '#FFFFFF'
|
|
334
|
+
},
|
|
335
|
+
partner: { name: 'TestStore' },
|
|
336
|
+
cart: {
|
|
337
|
+
addToCartFn: async (productId, qty) => {
|
|
338
|
+
console.log('[TestPage] addToCartFn called:', productId, qty);
|
|
339
|
+
return { ok: true };
|
|
340
|
+
},
|
|
341
|
+
getCartFn: async () => {
|
|
342
|
+
console.log('[TestPage] getCartFn called');
|
|
343
|
+
return window.__TTP_ECOMMERCE__?.getCart() || { items: [], total: 0, count: 0 };
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
window.testWidget = ecomWidget;
|
|
349
|
+
updateStatus('TTPEcommerceWidget created successfully', 'success');
|
|
350
|
+
refreshCartDisplay();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Button handlers
|
|
354
|
+
document.getElementById('createBtn').onclick = createWidget;
|
|
355
|
+
|
|
356
|
+
document.getElementById('destroyBtn').onclick = () => {
|
|
357
|
+
if (ecomWidget) {
|
|
358
|
+
ecomWidget.destroy();
|
|
359
|
+
ecomWidget = null;
|
|
360
|
+
updateStatus('Widget destroyed', '');
|
|
361
|
+
refreshCartDisplay();
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
document.getElementById('showProductsBtn').onclick = async () => {
|
|
366
|
+
if (!window.__TTP_ECOMMERCE__) {
|
|
367
|
+
updateStatus('Create widget first', 'error');
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const query = document.getElementById('productQuery').value || 'milk';
|
|
371
|
+
try {
|
|
372
|
+
await window.__TTP_ECOMMERCE__.showProducts(query);
|
|
373
|
+
updateStatus('showProducts("' + query + '") sent', 'success');
|
|
374
|
+
} catch (e) {
|
|
375
|
+
updateStatus('showProducts failed: ' + e.message, 'error');
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
document.getElementById('cartAddBtn').onclick = async () => {
|
|
380
|
+
if (!window.__TTP_ECOMMERCE__) {
|
|
381
|
+
updateStatus('Create widget first', 'error');
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
const baseUrl = window.__TTP_MOCK_API__ || 'https://backend.talktopc.com';
|
|
386
|
+
const response = await fetch(`${baseUrl}/api/partner/mock-store/products/search?q=milk&limit=1&sessionId=test`);
|
|
387
|
+
const data = await response.json();
|
|
388
|
+
const product = data.products[0];
|
|
389
|
+
window.__TTP_ECOMMERCE__.handleMessage({
|
|
390
|
+
t: 'cart_updated',
|
|
391
|
+
product: product,
|
|
392
|
+
action: 'added',
|
|
393
|
+
cartTotal: product.price,
|
|
394
|
+
cartItemCount: 1
|
|
395
|
+
});
|
|
396
|
+
updateStatus('Simulated cart_updated for "' + product.name + '"', 'success');
|
|
397
|
+
setTimeout(refreshCartDisplay, 200);
|
|
398
|
+
} catch (e) {
|
|
399
|
+
updateStatus('Failed to fetch product: ' + e.message, 'error');
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
document.getElementById('cartClearBtn').onclick = () => {
|
|
404
|
+
if (!window.__TTP_ECOMMERCE__) {
|
|
405
|
+
updateStatus('Create widget first', 'error');
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
window.__TTP_ECOMMERCE__.clearCart();
|
|
409
|
+
updateStatus('Cart cleared', '');
|
|
410
|
+
refreshCartDisplay();
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
document.getElementById('refreshCartBtn').onclick = refreshCartDisplay;
|
|
414
|
+
|
|
415
|
+
// Wait for SDK and auto-create widget
|
|
416
|
+
function waitForSDK() {
|
|
417
|
+
return new Promise((resolve, reject) => {
|
|
418
|
+
if (window.TTPAgentSDK?.TTPEcommerceWidget) { resolve(); return; }
|
|
419
|
+
let attempts = 0;
|
|
420
|
+
const iv = setInterval(() => {
|
|
421
|
+
attempts++;
|
|
422
|
+
if (window.TTPAgentSDK?.TTPEcommerceWidget) { clearInterval(iv); resolve(); }
|
|
423
|
+
else if (attempts >= 50) { clearInterval(iv); reject(new Error('SDK failed to load')); }
|
|
424
|
+
}, 100);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
waitForSDK().then(() => {
|
|
429
|
+
updateStatus('SDK loaded — creating widget...', '');
|
|
430
|
+
createWidget();
|
|
431
|
+
}).catch(e => {
|
|
432
|
+
updateStatus('SDK load failed: ' + e.message, 'error');
|
|
433
|
+
});
|
|
434
|
+
</script>
|
|
435
|
+
</body>
|
|
436
|
+
</html>
|
|
@@ -326,6 +326,13 @@
|
|
|
326
326
|
<label for="primaryColor">Primary Color</label>
|
|
327
327
|
<input type="color" id="primaryColor" value="#7C3AED">
|
|
328
328
|
</div>
|
|
329
|
+
|
|
330
|
+
<div class="config-group">
|
|
331
|
+
<label style="display: flex; align-items: center; gap: 8px;">
|
|
332
|
+
<input type="checkbox" id="useShadowDOM" checked>
|
|
333
|
+
<span>Use Shadow DOM</span>
|
|
334
|
+
</label>
|
|
335
|
+
</div>
|
|
329
336
|
</div>
|
|
330
337
|
|
|
331
338
|
<div class="info-box" style="margin-top: 24px;">
|
|
@@ -452,11 +459,14 @@
|
|
|
452
459
|
}
|
|
453
460
|
|
|
454
461
|
try {
|
|
462
|
+
const useShadowDOM = document.getElementById('useShadowDOM').checked;
|
|
463
|
+
|
|
455
464
|
const config = {
|
|
456
465
|
agentId: agentId,
|
|
457
466
|
appId: appId,
|
|
458
467
|
language: language,
|
|
459
468
|
primaryColor: primaryColor,
|
|
469
|
+
useShadowDOM: useShadowDOM,
|
|
460
470
|
behavior: {
|
|
461
471
|
mode: mode
|
|
462
472
|
}
|
|
@@ -544,6 +554,7 @@
|
|
|
544
554
|
document.getElementById('language').value = 'en';
|
|
545
555
|
document.getElementById('mode').value = 'unified';
|
|
546
556
|
document.getElementById('primaryColor').value = '#7C3AED';
|
|
557
|
+
document.getElementById('useShadowDOM').checked = true;
|
|
547
558
|
// Reset Visual Assistant settings
|
|
548
559
|
document.getElementById('visualAssistantEnabled').checked = true;
|
|
549
560
|
document.getElementById('allowHighlight').checked = true;
|