@wabbit-dashboard/embed 1.1.1 → 1.1.3

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.
@@ -444,6 +444,7 @@ declare class ChatPanel {
444
444
  private messages;
445
445
  private isWaitingForResponse;
446
446
  private closeButton;
447
+ private statusIndicator;
447
448
  private eventCleanup;
448
449
  private streamingMessages;
449
450
  private streamingCleanupInterval;
@@ -470,9 +471,11 @@ declare class ChatPanel {
470
471
  */
471
472
  setMessages(messages: Message[]): void;
472
473
  /**
473
- * Add system message
474
+ * Add system message (e.g. welcome or server/guardrail error).
475
+ * @param content - Message text
476
+ * @param isError - If true, message is styled as an error (e.g. guardrail/rate limit)
474
477
  */
475
- addSystemMessage(content: string): void;
478
+ addSystemMessage(content: string, isError?: boolean): void;
476
479
  /**
477
480
  * Set waiting for response state
478
481
  */
@@ -481,8 +484,14 @@ declare class ChatPanel {
481
484
  * Set disabled state
482
485
  */
483
486
  setDisabled(disabled: boolean): void;
487
+ /**
488
+ * Update the connection status indicator
489
+ */
490
+ setConnectionStatus(status: ConnectionStatus): void;
484
491
  /**
485
492
  * Render a single message
493
+ * @param message - Message to render
494
+ * @param isSystemError - If true, add error styling (for system role only)
486
495
  */
487
496
  private renderMessage;
488
497
  /**
@@ -1047,6 +1047,7 @@ class ChatPanel {
1047
1047
  this.messages = [];
1048
1048
  this.isWaitingForResponse = false;
1049
1049
  this.closeButton = null;
1050
+ this.statusIndicator = null;
1050
1051
  this.eventCleanup = [];
1051
1052
  this.streamingMessages = new Map();
1052
1053
  this.streamingCleanupInterval = null;
@@ -1182,6 +1183,14 @@ class ChatPanel {
1182
1183
  this.sendButton?.removeEventListener('click', sendClickHandler);
1183
1184
  });
1184
1185
  this.updateSendButtonState();
1186
+ this.statusIndicator = createElement('div', {
1187
+ class: 'wabbit-chat-status-indicator',
1188
+ 'data-status': 'connecting',
1189
+ title: 'Connecting...',
1190
+ 'aria-label': 'Connection status: connecting',
1191
+ role: 'status'
1192
+ });
1193
+ inputWrapper.appendChild(this.statusIndicator);
1185
1194
  inputWrapper.appendChild(this.inputElement);
1186
1195
  inputWrapper.appendChild(this.sendButton);
1187
1196
  inputArea.appendChild(inputWrapper);
@@ -1207,16 +1216,20 @@ class ChatPanel {
1207
1216
  }
1208
1217
  }
1209
1218
  /**
1210
- * Add system message
1219
+ * Add system message (e.g. welcome or server/guardrail error).
1220
+ * @param content - Message text
1221
+ * @param isError - If true, message is styled as an error (e.g. guardrail/rate limit)
1211
1222
  */
1212
- addSystemMessage(content) {
1223
+ addSystemMessage(content, isError) {
1213
1224
  const message = {
1214
1225
  id: `system-${Date.now()}`,
1215
1226
  role: 'system',
1216
1227
  content,
1217
1228
  timestamp: new Date()
1218
1229
  };
1219
- this.addMessage(message);
1230
+ this.messages.push(message);
1231
+ this.renderMessage(message, isError);
1232
+ this.scrollToBottom();
1220
1233
  }
1221
1234
  /**
1222
1235
  * Set waiting for response state
@@ -1253,14 +1266,34 @@ class ChatPanel {
1253
1266
  this.updateSendButtonState();
1254
1267
  }
1255
1268
  }
1269
+ /**
1270
+ * Update the connection status indicator
1271
+ */
1272
+ setConnectionStatus(status) {
1273
+ if (!this.statusIndicator)
1274
+ return;
1275
+ this.statusIndicator.setAttribute('data-status', status);
1276
+ const labels = {
1277
+ connected: 'Connected',
1278
+ disconnected: 'Disconnected',
1279
+ connecting: 'Connecting...',
1280
+ reconnecting: 'Reconnecting...',
1281
+ };
1282
+ this.statusIndicator.setAttribute('title', labels[status]);
1283
+ this.statusIndicator.setAttribute('aria-label', `Connection status: ${labels[status].toLowerCase()}`);
1284
+ }
1256
1285
  /**
1257
1286
  * Render a single message
1287
+ * @param message - Message to render
1288
+ * @param isSystemError - If true, add error styling (for system role only)
1258
1289
  */
1259
- renderMessage(message) {
1290
+ renderMessage(message, isSystemError) {
1260
1291
  if (!this.messagesContainer)
1261
1292
  return;
1293
+ const baseClass = `wabbit-chat-message wabbit-chat-message-${message.role}`;
1294
+ const errorClass = message.role === 'system' && isSystemError ? ' wabbit-chat-message-system-error' : '';
1262
1295
  const messageDiv = createElement('div', {
1263
- class: `wabbit-chat-message wabbit-chat-message-${message.role}`
1296
+ class: baseClass + errorClass
1264
1297
  });
1265
1298
  const bubble = createElement('div', { class: 'wabbit-chat-message-bubble' });
1266
1299
  const content = createElement('div', { class: 'wabbit-chat-message-content' });
@@ -1535,6 +1568,7 @@ class ChatPanel {
1535
1568
  this.inputElement = null;
1536
1569
  this.sendButton = null;
1537
1570
  this.closeButton = null;
1571
+ this.statusIndicator = null;
1538
1572
  }
1539
1573
  }
1540
1574
  }
@@ -1844,6 +1878,15 @@ function injectChatStyles(primaryColor = '#6366f1', theme) {
1844
1878
  padding: 8px 12px;
1845
1879
  }
1846
1880
 
1881
+ .wabbit-chat-message-system-error .wabbit-chat-message-bubble {
1882
+ background: rgba(220, 38, 38, 0.1);
1883
+ border: 1px solid rgba(220, 38, 38, 0.4);
1884
+ color: #b91c1c;
1885
+ text-align: left;
1886
+ font-size: 13px;
1887
+ padding: 10px 14px;
1888
+ }
1889
+
1847
1890
  .wabbit-chat-message-content {
1848
1891
  font-size: 14px;
1849
1892
  line-height: 1.5;
@@ -1975,6 +2018,35 @@ function injectChatStyles(primaryColor = '#6366f1', theme) {
1975
2018
  height: 20px;
1976
2019
  }
1977
2020
 
2021
+ /* Connection Status Indicator */
2022
+ .wabbit-chat-status-indicator {
2023
+ width: 8px;
2024
+ height: 8px;
2025
+ border-radius: 50%;
2026
+ flex-shrink: 0;
2027
+ align-self: center;
2028
+ transition: background-color 0.3s ease;
2029
+ }
2030
+
2031
+ .wabbit-chat-status-indicator[data-status="connected"] {
2032
+ background-color: #22c55e;
2033
+ }
2034
+
2035
+ .wabbit-chat-status-indicator[data-status="disconnected"] {
2036
+ background-color: #ef4444;
2037
+ }
2038
+
2039
+ .wabbit-chat-status-indicator[data-status="connecting"],
2040
+ .wabbit-chat-status-indicator[data-status="reconnecting"] {
2041
+ background-color: #f59e0b;
2042
+ animation: wabbit-status-pulse 1.5s ease-in-out infinite;
2043
+ }
2044
+
2045
+ @keyframes wabbit-status-pulse {
2046
+ 0%, 100% { opacity: 1; }
2047
+ 50% { opacity: 0.3; }
2048
+ }
2049
+
1978
2050
  /* Scrollbar */
1979
2051
  .wabbit-chat-messages::-webkit-scrollbar {
1980
2052
  width: 6px;
@@ -2258,38 +2330,27 @@ class ChatWidget {
2258
2330
  }
2259
2331
  };
2260
2332
  this.wsClient.onError = (error) => {
2261
- console.error('[Wabbit] Chat error:', error);
2333
+ const message = typeof error === 'string' ? error : (error?.message ?? 'An error occurred');
2334
+ console.error('[Wabbit] Chat error:', message);
2262
2335
  if (this.panel) {
2263
- // Clean up any active streaming messages on error
2264
2336
  this.panel.cancelAllStreamingMessages();
2265
- this.panel.addSystemMessage(`Error: ${error}`);
2266
2337
  this.panel.setWaitingForResponse(false);
2267
2338
  }
2268
2339
  };
2269
2340
  this.wsClient.onStatusChange = (status) => {
2270
2341
  if (this.panel) {
2271
2342
  this.panel.setDisabled(status !== 'connected');
2343
+ this.panel.setConnectionStatus(status);
2272
2344
  }
2273
2345
  };
2274
2346
  this.wsClient.onDisconnect = () => {
2275
2347
  if (this.panel) {
2276
- // Clean up any active streaming messages on disconnect
2277
2348
  this.panel.cancelAllStreamingMessages();
2278
- // Check if there are queued messages
2279
- const queueSize = this.wsClient.getQueueSize();
2280
- if (queueSize > 0) {
2281
- this.panel.addSystemMessage(`Disconnected from chat service. ${queueSize} message(s) will be sent when reconnected.`);
2282
- }
2283
- else {
2284
- this.panel.addSystemMessage('Disconnected from chat service');
2285
- }
2286
2349
  this.panel.setDisabled(true);
2287
2350
  }
2288
2351
  };
2289
2352
  this.wsClient.onQueueOverflow = (message) => {
2290
- if (this.panel) {
2291
- this.panel.addSystemMessage(message);
2292
- }
2353
+ console.warn('[Wabbit] Queue overflow:', message);
2293
2354
  };
2294
2355
  }
2295
2356
  /**