aptolix_chatbot 1.0.6 → 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/b14bec07-2499-48bc-a8f5-a3bf197e9f3c.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/17cf5d2a-65af-4522-8aad-84dfff696a04 +0 -0
  37. package/.vs/Aptolix_Chatbot/v17/.wsuo +0 -0
  38. package/.vs/Aptolix_Chatbot/v17/DocumentLayout.backup.json +0 -117
  39. package/.vs/Aptolix_Chatbot/v17/DocumentLayout.json +0 -117
  40. package/.vs/VSWorkspaceState.json +0 -9
  41. package/.vs/slnx.sqlite +0 -0
  42. package/rollup.config.js +0 -22
  43. package/src/chatbotstyle.css +0 -439
  44. package/src/index.js +0 -359
package/src/index.js DELETED
@@ -1,359 +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
- // Create hint bubble but keep it hidden initially
19
- hintBubble = document.createElement('div');
20
- hintBubble.id = "aptolix-chat-hint-bubble";
21
- hintBubble.className = "aptolix-hint-bubble";
22
- hintBubble.innerText = hintText;
23
- hintBubble.style.display = "none";
24
- document.body.appendChild(hintBubble);
25
-
26
- // Show hint bubble after delay
27
- hintBubbleTimeout = setTimeout(() => {
28
- if (chatWindow.style.display === "none") {
29
- hintBubble.style.display = "block";
30
- }
31
- }, hintDelay);
32
-
33
- // Hide hint bubble when main bubble is clicked
34
- bubble.addEventListener("click", () => {
35
- hintBubble.style.display = "none";
36
- clearTimeout(hintBubbleTimeout);
37
- });
38
-
39
- // Hide hint bubble if chat is opened by other means
40
- chatWindow.addEventListener("transitionstart", () => {
41
- hintBubble.style.display = "none";
42
- clearTimeout(hintBubbleTimeout);
43
- });
44
- }
45
-
46
-
47
- chatWindow.id = "aptolix-chat-window";
48
- chatWindow.classList.add(modeClass);
49
- chatWindow.style.display = mode === "section" ? "flex" : "none";
50
-
51
- if (mode === "section" && target) {
52
- const targetEl = typeof target === "string" ? document.querySelector(target) : target;
53
- if (targetEl) targetEl.appendChild(chatWindow);
54
- else document.body.appendChild(chatWindow);
55
- } else {
56
- document.body.appendChild(chatWindow);
57
- }
58
-
59
- chatWindow.innerHTML = `
60
- <div id="aptolix-chat-header">
61
- <div class="aptolix-header-flex">
62
- <div class="aptolix-header-title">
63
- <strong>${title || "AI Chatbot"}</strong>
64
- ${subtitle ? `<div class="aptolix-header-subtitle">${subtitle}</div>` : ""}
65
- </div>
66
- <div class="aptolix-header-actions">
67
- <button id="aptolix-chat-reset" title="Clear chat" aria-label="Clear chat">⟲</button>
68
- <button id="aptolix-chat-expand" title="Expand/Collapse" aria-label="Expand/Collapse">
69
- <span id="aptolix-chat-expand-icon">⤢</span>
70
- </button>
71
- <button id="aptolix-chat-download" title="Download chat" aria-label="Download chat">⤓</button>
72
- <button id="aptolix-chat-close" title="Close chat" aria-label="Close chat">×</button>
73
- </div>
74
- </div>
75
- </div>
76
- <div id="aptolix-chat-messages"></div>
77
- <div id="aptolix-chat-input">
78
- <textarea id="aptolix-chat-inputbox" rows="1" placeholder="Type your message..." style="resize:none"></textarea>
79
- <button>Send</button>
80
- </div>
81
- <div class="aptolix-powered-by">
82
- Powered by <a href="https://aptolix.com" target="_blank" rel="noopener" class="aptolix-link">Aptolix</a>
83
- </div>
84
- `;
85
-
86
- const closeBtn = chatWindow.querySelector("#aptolix-chat-close");
87
- const resetBtn = chatWindow.querySelector("#aptolix-chat-reset");
88
- const expandBtn = chatWindow.querySelector("#aptolix-chat-expand");
89
- const expandIcon = chatWindow.querySelector("#aptolix-chat-expand-icon");
90
- const input = chatWindow.querySelector("#aptolix-chat-inputbox");
91
- const sendButton = chatWindow.querySelector("button");
92
- const messagesDiv = chatWindow.querySelector("#aptolix-chat-messages");
93
- const downloadBtn = chatWindow.querySelector("#aptolix-chat-download");
94
-
95
- if (mode === "bubble") {
96
- closeBtn.addEventListener("click", () => {
97
- chatWindow.style.display = "none";
98
- });
99
- }
100
-
101
- resetBtn.addEventListener("click", () => {
102
- messagesDiv.innerHTML = "";
103
- input.value = "";
104
- showGreeting(); // Show greeting after reset
105
- });
106
-
107
- if (mode === "bubble" && bubble) {
108
- bubble.addEventListener("click", () => {
109
- const wasClosed = chatWindow.style.display === "none";
110
- chatWindow.style.display = wasClosed ? "flex" : "none";
111
- bubble.removeAttribute("data-unread");
112
- if (wasClosed) showGreeting();
113
- });
114
- }
115
-
116
- if (mode === "bubble") {
117
- document.addEventListener("mousedown", function onOutsideClick(event) {
118
- if (chatWindow.style.display !== "none") {
119
- if (
120
- !chatWindow.contains(event.target) &&
121
- !bubble.contains(event.target)
122
- ) {
123
- chatWindow.style.display = "none";
124
- }
125
- }
126
- });
127
- }
128
-
129
- async function sendMessage(isRetry = false, previousText = null) {
130
- const userText = previousText || input.value.trim();
131
- if (!userText) return;
132
- if (!isRetry) {
133
- input.value = "";
134
- input.rows = 1;
135
- input.style.height = "32px"; // or your default line height
136
- input.style.overflowY = "hidden";
137
- }
138
- if (!isRetry) {
139
- const userMsg = document.createElement("div");
140
- userMsg.className = "message user";
141
- userMsg.innerText = userText;
142
- messagesDiv.appendChild(userMsg);
143
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
144
- }
145
-
146
- const typingMsg = document.createElement("div");
147
- typingMsg.className = "message bot typing";
148
- typingMsg.innerHTML = `<span class="typing-dots"><span>.</span><span>.</span><span>.</span></span>`;
149
- messagesDiv.appendChild(typingMsg);
150
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
151
-
152
- function showError() {
153
- typingMsg.remove();
154
- const errorMsg = document.createElement("div");
155
- errorMsg.className = "message bot error";
156
- errorMsg.innerHTML = `
157
- <div>
158
- <strong>⚠️ Unable to connect to the assistant.</strong><br>
159
- Please check your internet connection or try again later.
160
- </div>
161
- <button class="aptolix-retry-btn">Retry</button>
162
- `;
163
- messagesDiv.appendChild(errorMsg);
164
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
165
-
166
- const retryBtn = errorMsg.querySelector('.aptolix-retry-btn');
167
- if (retryBtn) {
168
- retryBtn.addEventListener('click', () => {
169
- errorMsg.remove();
170
- sendMessage(true, userText);
171
- });
172
- }
173
- }
174
-
175
- try {
176
- const res = await fetch(`${apiHost}${chatflowid}`, {
177
- method: "POST",
178
- headers: { "Content-Type": "application/json" },
179
- body: JSON.stringify({ question: userText }),
180
- });
181
- const data = await res.json();
182
-
183
- typingMsg.remove();
184
-
185
- const botMsg = document.createElement("div");
186
- botMsg.className = "message bot";
187
- botMsg.innerHTML = marked.parse(data.text || "[No response]");
188
- messagesDiv.appendChild(botMsg);
189
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
190
-
191
- if (mode === "bubble" && chatWindow.style.display === "none") {
192
- bubble.setAttribute("data-unread", "true");
193
- }
194
- } catch (err) {
195
- showError();
196
- if (mode === "bubble" && chatWindow.style.display === "none") {
197
- bubble.setAttribute("data-unread", "true");
198
- }
199
- }
200
- }
201
-
202
- // Send on Enter key or button click
203
- sendButton.addEventListener("click", () => sendMessage());
204
- input.addEventListener("keydown", (e) => {
205
- if (e.key === "Enter") {
206
- e.preventDefault();
207
- sendMessage();
208
- }
209
- });
210
-
211
- let expanded = false;
212
- if (mode === "bubble") {
213
- expandBtn.addEventListener("click", () => {
214
- expanded = !expanded;
215
- if (expanded) {
216
- chatWindow.style.width = "600px";
217
- chatWindow.style.height = "80vh";
218
- expandIcon.textContent = "⤡";
219
- } else {
220
- chatWindow.style.width = "400px";
221
- chatWindow.style.height = "595px";
222
- expandIcon.textContent = "⤢";
223
- }
224
- });
225
- }
226
-
227
- function showGreeting() {
228
- // Remove any previous greeting messages
229
- messagesDiv.querySelectorAll('.message.greeting').forEach(el => el.remove());
230
- const greetMsg = greeting || "<strong>👋 Howdy, </strong>How can I help you today?";
231
- const greetingDiv = document.createElement("div");
232
- greetingDiv.className = "message bot greeting";
233
- greetingDiv.innerHTML = greetMsg;
234
- messagesDiv.appendChild(greetingDiv);
235
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
236
- }
237
- setTimeout(showGreeting, 100);
238
-
239
- input.addEventListener('input', function() {
240
- // Restrict to max 350 characters
241
- if (this.value.length > 350) {
242
- this.value = this.value.slice(0, 350);
243
- return;
244
- }
245
- // If textarea is empty, reset to default size
246
- if (this.value === "") {
247
- this.rows = 1;
248
- this.style.height = "32px";
249
- this.style.overflowY = "hidden";
250
- return;
251
- }
252
- // Count the number of lines in the textarea
253
- const lines = this.value.split('\n');
254
- // Set the number of rows, max 4
255
- this.rows = Math.min(lines.length, 4);
256
- // Calculate the max height for 4 rows (approximate line height: 32px)
257
- const maxHeight = 3 * 36; // 128px
258
- this.style.height = 'auto';
259
- this.style.height = Math.min(this.scrollHeight, maxHeight) + 'px';
260
- // Show scrollbar only if content exceeds maxHeight
261
- if (this.scrollHeight > maxHeight) {
262
- this.style.overflowY = 'auto';
263
- } else {
264
- this.style.overflowY = 'hidden';
265
- }
266
- });
267
-
268
- downloadBtn.addEventListener("click", () => {
269
- // Collect all messages
270
- const messages = Array.from(messagesDiv.querySelectorAll('.message')).map(msg => {
271
- const sender = msg.classList.contains('user') ? "You" : "Bot";
272
- // Remove HTML tags for plain text
273
- const text = msg.innerText || msg.textContent;
274
- return `${sender}: ${text}`;
275
- }).join('\n\n');
276
-
277
- // Create a blob and trigger download
278
- const blob = new Blob([messages], { type: "text/plain" });
279
- const url = URL.createObjectURL(blob);
280
- const a = document.createElement("a");
281
- a.href = url;
282
- a.download = "chat_history.txt";
283
- document.body.appendChild(a);
284
- a.click();
285
- setTimeout(() => {
286
- document.body.removeChild(a);
287
- URL.revokeObjectURL(url);
288
- }, 100);
289
- });
290
- },
291
- initFull: function(options) {
292
- let el = document.querySelector('aptolix-chatbot');
293
- if (!el) {
294
- console.warn('No <aptolix-chatbot> element found in the DOM.');
295
- return;
296
- }
297
- Object.entries(options).forEach(([key, value]) => {
298
- el.setAttribute(key, value);
299
- });
300
- }
301
- };
302
-
303
- // Custom element for section embedding
304
- class AptolixChatbotElement extends HTMLElement {
305
- static get observedAttributes() {
306
- return ['apiHost', 'chatflowid', 'title', 'greeting', 'subtitle', 'target'];
307
- }
308
-
309
- connectedCallback() {
310
- this.tryInit();
311
- }
312
-
313
- attributeChangedCallback() {
314
- // Remove previous chat window if present
315
- const existingChatWindow = this.querySelector('#aptolix-chat-window');
316
- if (existingChatWindow) existingChatWindow.remove();
317
- // Re-initialize to update greeting and other attributes
318
- this._initialized = false;
319
- this.tryInit();
320
- }
321
-
322
- tryInit() {
323
- const apiHost = this.getAttribute('apiHost');
324
- const chatflowid = this.getAttribute('chatflowid');
325
- if (!apiHost || !chatflowid) return;
326
-
327
- const title = this.getAttribute('title') || "Aptolix AI Chatbot";
328
- const greeting = this.getAttribute('greeting');
329
- const subtitle = this.getAttribute('subtitle');
330
- const targetAttr = this.getAttribute('target');
331
- let target = this;
332
- if (targetAttr) {
333
- const found = document.querySelector(targetAttr);
334
- if (found) target = found;
335
- }
336
-
337
- if (this._initialized) return;
338
- this._initialized = true;
339
-
340
- AptolixChatbot.init({
341
- apiHost,
342
- chatflowid,
343
- title,
344
- subtitle,
345
- greeting,
346
- mode: "section",
347
- target
348
- });
349
- }
350
- }
351
- customElements.define('aptolix-chatbot', AptolixChatbotElement);
352
-
353
- // Export as default so consumers use Chatbot.init and Chatbot.initFull
354
- export default AptolixChatbot;
355
-
356
-
357
-
358
-
359
-