aptolix_chatbot 1.0.7 → 1.0.9

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 (44) hide show
  1. package/dist/web.mjs +1 -1
  2. package/dist/web.mjs.map +1 -1
  3. package/package.json +23 -3
  4. package/.gitattributes +0 -63
  5. package/.vs/Aptolix-Chatbot/CopilotIndices/17.14.995.13737/CodeChunks.db +0 -0
  6. package/.vs/Aptolix-Chatbot/CopilotIndices/17.14.995.13737/SemanticSymbols.db +0 -0
  7. package/.vs/Aptolix-Chatbot/FileContentIndex/7a6184fc-93ec-4d74-9ae5-f42762df27b5.vsidx +0 -0
  8. package/.vs/Aptolix-Chatbot/FileContentIndex/812b8a98-dfb2-4448-bf14-4ed36d2c34f3.vsidx +0 -0
  9. package/.vs/Aptolix-Chatbot/FileContentIndex/98c498ee-ddc5-46fc-82d9-ed30a218b641.vsidx +0 -0
  10. package/.vs/Aptolix-Chatbot/FileContentIndex/9f4cf152-a82c-4f20-97b4-5c50ab636d6f.vsidx +0 -0
  11. package/.vs/Aptolix-Chatbot/FileContentIndex/c402a8e1-cb87-4b94-8c7f-298a59a5fb1b.vsidx +0 -0
  12. package/.vs/Aptolix-Chatbot/config/applicationhost.config +0 -1011
  13. package/.vs/Aptolix-Chatbot/copilot-chat/c320fb0f/sessions/48c7360b-028f-426c-b850-39c47706c316 +0 -0
  14. package/.vs/Aptolix-Chatbot/v17/.wsuo +0 -0
  15. package/.vs/Aptolix-Chatbot/v17/DocumentLayout.backup.json +0 -62
  16. package/.vs/Aptolix-Chatbot/v17/DocumentLayout.json +0 -62
  17. package/.vs/Aptolix-Chatbot-Widget/CopilotIndices/17.14.995.13737/CodeChunks.db +0 -0
  18. package/.vs/Aptolix-Chatbot-Widget/CopilotIndices/17.14.995.13737/SemanticSymbols.db +0 -0
  19. package/.vs/Aptolix-Chatbot-Widget/FileContentIndex/5d6b4f41-52da-4119-be44-2b20a4cefcd3.vsidx +0 -0
  20. package/.vs/Aptolix-Chatbot-Widget/FileContentIndex/c0c65d68-1df0-4f38-a40a-82ac4f5b0852.vsidx +0 -0
  21. package/.vs/Aptolix-Chatbot-Widget/FileContentIndex/c92407ec-f2a5-4d8d-a76e-b5b00ad5bb95.vsidx +0 -0
  22. package/.vs/Aptolix-Chatbot-Widget/FileContentIndex/cabcefbd-2c41-4e7f-817f-d3eb21b99197.vsidx +0 -0
  23. package/.vs/Aptolix-Chatbot-Widget/FileContentIndex/ebb08769-a636-4f23-aa30-03ee4e0170df.vsidx +0 -0
  24. package/.vs/Aptolix-Chatbot-Widget/config/applicationhost.config +0 -1011
  25. package/.vs/Aptolix-Chatbot-Widget/copilot-chat/c320fb0f/sessions/3189df6f-a527-48b1-8a59-6cbda8035079 +0 -0
  26. package/.vs/Aptolix-Chatbot-Widget/copilot-chat/c320fb0f/sessions/71a58fcf-f873-4b3b-96f4-7c23ed9008ff +0 -0
  27. package/.vs/Aptolix-Chatbot-Widget/v17/.wsuo +0 -0
  28. package/.vs/Aptolix-Chatbot-Widget/v17/DocumentLayout.backup.json +0 -94
  29. package/.vs/Aptolix-Chatbot-Widget/v17/DocumentLayout.json +0 -93
  30. package/.vs/Aptolix_Chatbot/CopilotIndices/17.14.1368.60722/CodeChunks.db +0 -0
  31. package/.vs/Aptolix_Chatbot/CopilotIndices/17.14.1368.60722/SemanticSymbols.db +0 -0
  32. package/.vs/Aptolix_Chatbot/FileContentIndex/6af43a12-1809-4220-acbe-157eada43878.vsidx +0 -0
  33. package/.vs/Aptolix_Chatbot/FileContentIndex/cb041aa7-a0e1-4bca-8679-9fa832fdb7f8.vsidx +0 -0
  34. package/.vs/Aptolix_Chatbot/FileContentIndex/e6968f22-96d6-4c7a-82cb-14a6ddf57328.vsidx +0 -0
  35. package/.vs/Aptolix_Chatbot/config/applicationhost.config +0 -1011
  36. package/.vs/Aptolix_Chatbot/copilot-chat/c320fb0f/sessions/59f54b6a-d7a7-4560-8de1-6ab7fc64e20d +0 -0
  37. package/.vs/Aptolix_Chatbot/v17/.wsuo +0 -0
  38. package/.vs/Aptolix_Chatbot/v17/DocumentLayout.backup.json +0 -115
  39. package/.vs/Aptolix_Chatbot/v17/DocumentLayout.json +0 -115
  40. package/.vs/VSWorkspaceState.json +0 -8
  41. package/.vs/slnx.sqlite +0 -0
  42. package/rollup.config.js +0 -22
  43. package/src/chatbotstyle.css +0 -438
  44. package/src/index.js +0 -405
package/src/index.js DELETED
@@ -1,405 +0,0 @@
1
- import { marked } from "marked";
2
- import './chatbotstyle.css';
3
-
4
- const AptolixChatbot = {
5
- init: ({ apiHost, chatflowid, title, subtitle, greeting, mode = "bubble", target, hintText = "I am here to help", hintDelay = 5000 // default 5 seconds
6
- }) => {
7
-
8
- const modeClass = mode === "section" ? "section-mode" : "bubble-mode";
9
- const chatWindow = document.createElement('div');
10
-
11
- let bubble, hintBubbleTimeout, hintBubble;
12
- if (mode === "bubble") {
13
- bubble = document.createElement('div');
14
- bubble.id = "aptolix-chat-bubble";
15
- bubble.innerText = "💬";
16
- document.body.appendChild(bubble);
17
-
18
- // Remove any existing hint bubble before creating a new one
19
- const existingHintBubble = document.getElementById("aptolix-chat-hint-bubble");
20
- if (existingHintBubble) {
21
- existingHintBubble.remove();
22
- }
23
-
24
- // Create hint bubble but keep it hidden initially
25
- hintBubble = document.createElement('div');
26
- hintBubble.id = "aptolix-chat-hint-bubble";
27
- hintBubble.className = "aptolix-hint-bubble";
28
- hintBubble.style.display = "none";
29
- hintBubble.style.position = "fixed";
30
- hintBubble.style.right = "40px";
31
- hintBubble.style.bottom = "110px";
32
- hintBubble.style.zIndex = "9999"; // <-- Ensure it's on top
33
-
34
- // Create the hint text span
35
- const hintTextSpan = document.createElement('span');
36
- hintTextSpan.textContent = hintText;
37
-
38
- // Create the close button
39
- const hintCloseBtn = document.createElement('button');
40
- hintCloseBtn.id = "aptolix-hint-close";
41
- hintCloseBtn.title = "Close";
42
- hintCloseBtn.setAttribute("aria-label", "Close");
43
- hintCloseBtn.innerHTML = "&#10005;";
44
- hintCloseBtn.style.background = "none";
45
- hintCloseBtn.style.border = "none";
46
- hintCloseBtn.style.color = "#9333ea";
47
- hintCloseBtn.style.fontSize = "1.3em";
48
- hintCloseBtn.style.position = "absolute";
49
- hintCloseBtn.style.top = "8px";
50
- hintCloseBtn.style.right = "12px";
51
- hintCloseBtn.style.cursor = "pointer";
52
- hintCloseBtn.style.padding = "0";
53
-
54
- // Add event listener directly
55
- hintCloseBtn.addEventListener("click", () => {
56
- hintBubble.style.display = "none";
57
- sessionStorage.setItem("aptolixHintClosed", "true");
58
- clearTimeout(hintBubbleTimeout);
59
- });
60
-
61
- // Append children
62
- hintBubble.appendChild(hintTextSpan);
63
- hintBubble.appendChild(hintCloseBtn);
64
-
65
- document.body.appendChild(hintBubble);
66
-
67
- // Show hint bubble after delay, unless closed in session
68
- hintBubbleTimeout = setTimeout(() => {
69
- if (
70
- chatWindow.style.display === "none" &&
71
- !sessionStorage.getItem("aptolixHintClosed")
72
- ) {
73
- hintBubble.style.display = "block";
74
- }
75
- }, hintDelay);
76
-
77
- // Hide hint bubble when main bubble is clicked
78
- bubble.addEventListener("click", () => {
79
- hintBubble.style.display = "none";
80
- clearTimeout(hintBubbleTimeout);
81
- });
82
-
83
- // Hide hint bubble if chat is opened by other means
84
- chatWindow.addEventListener("transitionstart", () => {
85
- hintBubble.style.display = "none";
86
- clearTimeout(hintBubbleTimeout);
87
- });
88
- }
89
-
90
-
91
- chatWindow.id = "aptolix-chat-window";
92
- chatWindow.classList.add(modeClass);
93
- chatWindow.style.display = mode === "section" ? "flex" : "none";
94
-
95
- if (mode === "section" && target) {
96
- const targetEl = typeof target === "string" ? document.querySelector(target) : target;
97
- if (targetEl) targetEl.appendChild(chatWindow);
98
- else document.body.appendChild(chatWindow);
99
- } else {
100
- document.body.appendChild(chatWindow);
101
- }
102
-
103
- chatWindow.innerHTML = `
104
- <div id="aptolix-chat-header">
105
- <div class="aptolix-header-flex">
106
- <div class="aptolix-header-title">
107
- <strong>${title || "AI Chatbot"}</strong>
108
- ${subtitle ? `<div class="aptolix-header-subtitle">${subtitle}</div>` : ""}
109
- </div>
110
- <div class="aptolix-header-actions">
111
- <button id="aptolix-chat-reset" title="Clear chat" aria-label="Clear chat">⟲</button>
112
- <button id="aptolix-chat-expand" title="Expand/Collapse" aria-label="Expand/Collapse">
113
- <span id="aptolix-chat-expand-icon">⤢</span>
114
- </button>
115
- <button id="aptolix-chat-download" title="Download chat" aria-label="Download chat">⤓</button>
116
- <button id="aptolix-chat-close" title="Close chat" aria-label="Close chat">×</button>
117
- </div>
118
- </div>
119
- </div>
120
- <div id="aptolix-chat-messages"></div>
121
- <div id="aptolix-chat-input">
122
- <textarea id="aptolix-chat-inputbox" rows="1" placeholder="Type your message..." style="resize:none"></textarea>
123
- <button>Send</button>
124
- </div>
125
- <div class="aptolix-powered-by">
126
- Powered by <a href="https://aptolix.com" target="_blank" rel="noopener" class="aptolix-link">Aptolix</a>
127
- </div>
128
- `;
129
-
130
- const closeBtn = chatWindow.querySelector("#aptolix-chat-close");
131
- const resetBtn = chatWindow.querySelector("#aptolix-chat-reset");
132
- const expandBtn = chatWindow.querySelector("#aptolix-chat-expand");
133
- const expandIcon = chatWindow.querySelector("#aptolix-chat-expand-icon");
134
- const input = chatWindow.querySelector("#aptolix-chat-inputbox");
135
- const sendButton = chatWindow.querySelector("button");
136
- const messagesDiv = chatWindow.querySelector("#aptolix-chat-messages");
137
- const downloadBtn = chatWindow.querySelector("#aptolix-chat-download");
138
-
139
- if (mode === "bubble") {
140
- closeBtn.addEventListener("click", () => {
141
- chatWindow.style.display = "none";
142
- });
143
- }
144
-
145
- resetBtn.addEventListener("click", () => {
146
- messagesDiv.innerHTML = "";
147
- input.value = "";
148
- showGreeting(); // Show greeting after reset
149
- });
150
-
151
- if (mode === "bubble" && bubble) {
152
- bubble.addEventListener("click", () => {
153
- const wasClosed = chatWindow.style.display === "none";
154
- chatWindow.style.display = wasClosed ? "flex" : "none";
155
- bubble.removeAttribute("data-unread");
156
- if (wasClosed) showGreeting();
157
- });
158
- }
159
-
160
- if (mode === "bubble") {
161
- document.addEventListener("mousedown", function onOutsideClick(event) {
162
- if (chatWindow.style.display !== "none") {
163
- if (
164
- !chatWindow.contains(event.target) &&
165
- !bubble.contains(event.target)
166
- ) {
167
- chatWindow.style.display = "none";
168
- }
169
- }
170
- });
171
- }
172
-
173
- async function sendMessage(isRetry = false, previousText = null) {
174
- const userText = previousText || input.value.trim();
175
- if (!userText) return;
176
- if (!isRetry) {
177
- input.value = "";
178
- input.rows = 1;
179
- input.style.height = "32px"; // or your default line height
180
- input.style.overflowY = "hidden";
181
- }
182
- if (!isRetry) {
183
- const userMsg = document.createElement("div");
184
- userMsg.className = "message user";
185
- userMsg.innerText = userText;
186
- messagesDiv.appendChild(userMsg);
187
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
188
- }
189
-
190
- const typingMsg = document.createElement("div");
191
- typingMsg.className = "message bot typing";
192
- typingMsg.innerHTML = `<span class="typing-dots"><span>.</span><span>.</span><span>.</span></span>`;
193
- messagesDiv.appendChild(typingMsg);
194
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
195
-
196
- function showError() {
197
- typingMsg.remove();
198
- const errorMsg = document.createElement("div");
199
- errorMsg.className = "message bot error";
200
- errorMsg.innerHTML = `
201
- <div>
202
- <strong>⚠️ Unable to connect to the assistant.</strong><br>
203
- Please check your internet connection or try again later.
204
- </div>
205
- <button class="aptolix-retry-btn">Retry</button>
206
- `;
207
- messagesDiv.appendChild(errorMsg);
208
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
209
-
210
- const retryBtn = errorMsg.querySelector('.aptolix-retry-btn');
211
- if (retryBtn) {
212
- retryBtn.addEventListener('click', () => {
213
- errorMsg.remove();
214
- sendMessage(true, userText);
215
- });
216
- }
217
- }
218
-
219
- try {
220
- const res = await fetch(`${apiHost}${chatflowid}`, {
221
- method: "POST",
222
- headers: { "Content-Type": "application/json" },
223
- body: JSON.stringify({ question: userText }),
224
- });
225
- const data = await res.json();
226
-
227
- typingMsg.remove();
228
-
229
- const botMsg = document.createElement("div");
230
- botMsg.className = "message bot";
231
- botMsg.innerHTML = marked.parse(data.text || "[No response]");
232
- messagesDiv.appendChild(botMsg);
233
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
234
-
235
- if (mode === "bubble" && chatWindow.style.display === "none") {
236
- bubble.setAttribute("data-unread", "true");
237
- }
238
- } catch (err) {
239
- showError();
240
- if (mode === "bubble" && chatWindow.style.display === "none") {
241
- bubble.setAttribute("data-unread", "true");
242
- }
243
- }
244
- }
245
-
246
- // Send on Enter key or button click
247
- sendButton.addEventListener("click", () => sendMessage());
248
- input.addEventListener("keydown", (e) => {
249
- if (e.key === "Enter") {
250
- e.preventDefault();
251
- sendMessage();
252
- }
253
- });
254
-
255
- let expanded = false;
256
- if (mode === "bubble") {
257
- expandBtn.addEventListener("click", () => {
258
- expanded = !expanded;
259
- if (expanded) {
260
- chatWindow.style.width = "600px";
261
- chatWindow.style.height = "80vh";
262
- expandIcon.textContent = "⤡";
263
- } else {
264
- chatWindow.style.width = "400px";
265
- chatWindow.style.height = "595px";
266
- expandIcon.textContent = "⤢";
267
- }
268
- });
269
- }
270
-
271
- function showGreeting() {
272
- // Remove any previous greeting messages
273
- messagesDiv.querySelectorAll('.message.greeting').forEach(el => el.remove());
274
- const greetMsg = greeting || "<strong>👋 Howdy, </strong>How can I help you today?";
275
- const greetingDiv = document.createElement("div");
276
- greetingDiv.className = "message bot greeting";
277
- greetingDiv.innerHTML = greetMsg;
278
- messagesDiv.appendChild(greetingDiv);
279
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
280
- }
281
- setTimeout(showGreeting, 100);
282
-
283
- input.addEventListener('input', function() {
284
- // Restrict to max 350 characters
285
- if (this.value.length > 350) {
286
- this.value = this.value.slice(0, 350);
287
- return;
288
- }
289
- // If textarea is empty, reset to default size
290
- if (this.value === "") {
291
- this.rows = 1;
292
- this.style.height = "32px";
293
- this.style.overflowY = "hidden";
294
- return;
295
- }
296
- // Count the number of lines in the textarea
297
- const lines = this.value.split('\n');
298
- // Set the number of rows, max 4
299
- this.rows = Math.min(lines.length, 4);
300
- // Calculate the max height for 4 rows (approximate line height: 32px)
301
- const maxHeight = 3 * 36; // 128px
302
- this.style.height = 'auto';
303
- this.style.height = Math.min(this.scrollHeight, maxHeight) + 'px';
304
- // Show scrollbar only if content exceeds maxHeight
305
- if (this.scrollHeight > maxHeight) {
306
- this.style.overflowY = 'auto';
307
- } else {
308
- this.style.overflowY = 'hidden';
309
- }
310
- });
311
-
312
- downloadBtn.addEventListener("click", () => {
313
- // Collect all messages
314
- const messages = Array.from(messagesDiv.querySelectorAll('.message')).map(msg => {
315
- const sender = msg.classList.contains('user') ? "You" : "Bot";
316
- // Remove HTML tags for plain text
317
- const text = msg.innerText || msg.textContent;
318
- return `${sender}: ${text}`;
319
- }).join('\n\n');
320
-
321
- // Create a blob and trigger download
322
- const blob = new Blob([messages], { type: "text/plain" });
323
- const url = URL.createObjectURL(blob);
324
- const a = document.createElement("a");
325
- a.href = url;
326
- a.download = "chat_history.txt";
327
- document.body.appendChild(a);
328
- a.click();
329
- setTimeout(() => {
330
- document.body.removeChild(a);
331
- URL.revokeObjectURL(url);
332
- }, 100);
333
- });
334
-
335
-
336
- },
337
- initFull: function(options) {
338
- let el = document.querySelector('aptolix-chatbot');
339
- if (!el) {
340
- console.warn('No <aptolix-chatbot> element found in the DOM.');
341
- return;
342
- }
343
- Object.entries(options).forEach(([key, value]) => {
344
- el.setAttribute(key, value);
345
- });
346
- }
347
- };
348
-
349
- // Custom element for section embedding
350
- class AptolixChatbotElement extends HTMLElement {
351
- static get observedAttributes() {
352
- return ['apiHost', 'chatflowid', 'title', 'greeting', 'subtitle', 'target'];
353
- }
354
-
355
- connectedCallback() {
356
- this.tryInit();
357
- }
358
-
359
- attributeChangedCallback() {
360
- // Remove previous chat window if present
361
- const existingChatWindow = this.querySelector('#aptolix-chat-window');
362
- if (existingChatWindow) existingChatWindow.remove();
363
- // Re-initialize to update greeting and other attributes
364
- this._initialized = false;
365
- this.tryInit();
366
- }
367
-
368
- tryInit() {
369
- const apiHost = this.getAttribute('apiHost');
370
- const chatflowid = this.getAttribute('chatflowid');
371
- if (!apiHost || !chatflowid) return;
372
-
373
- const title = this.getAttribute('title') || "Aptolix AI Chatbot";
374
- const greeting = this.getAttribute('greeting');
375
- const subtitle = this.getAttribute('subtitle');
376
- const targetAttr = this.getAttribute('target');
377
- let target = this;
378
- if (targetAttr) {
379
- const found = document.querySelector(targetAttr);
380
- if (found) target = found;
381
- }
382
-
383
- if (this._initialized) return;
384
- this._initialized = true;
385
-
386
- AptolixChatbot.init({
387
- apiHost,
388
- chatflowid,
389
- title,
390
- subtitle,
391
- greeting,
392
- mode: "section",
393
- target
394
- });
395
- }
396
- }
397
- customElements.define('aptolix-chatbot', AptolixChatbotElement);
398
-
399
- // Export as default so consumers use Chatbot.init and Chatbot.initFull
400
- export default AptolixChatbot;
401
-
402
-
403
-
404
-
405
-