This is an automated email from the ASF dual-hosted git repository.

gongchao pushed a commit to branch update-ai-with
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit f7428c25c3d3cea7eddef4a3c4ae06ebc5d31ca8
Author: tomsun28 <[email protected]>
AuthorDate: Thu Oct 30 23:42:30 2025 +0800

    [webapp] update ui
    
    Signed-off-by: tomsun28 <[email protected]>
---
 .../shared/components/ai-chat/chat.component.less  | 125 ++++++++++++++++++++-
 .../shared/components/ai-chat/chat.component.ts    |  33 +++++-
 2 files changed, 151 insertions(+), 7 deletions(-)

diff --git a/web-app/src/app/shared/components/ai-chat/chat.component.less 
b/web-app/src/app/shared/components/ai-chat/chat.component.less
index 8edbb3a1c..2af24a670 100644
--- a/web-app/src/app/shared/components/ai-chat/chat.component.less
+++ b/web-app/src/app/shared/components/ai-chat/chat.component.less
@@ -21,7 +21,9 @@
 
 .chat-container {
   display: flex;
-  height: 80vh; // Use viewport height for modal context
+  height: 100%;
+  min-height: 500px;
+  max-height: 80vh;
   background: @layout-body-background;
 
   .chat-sidebar {
@@ -54,6 +56,25 @@
     .conversation-list {
       flex: 1;
       overflow-y: auto;
+      scrollbar-width: thin;
+      scrollbar-color: @border-color-base transparent;
+
+      &::-webkit-scrollbar {
+        width: 6px;
+      }
+
+      &::-webkit-scrollbar-track {
+        background: transparent;
+      }
+
+      &::-webkit-scrollbar-thumb {
+        background: @border-color-base;
+        border-radius: 3px;
+      }
+
+      &::-webkit-scrollbar-thumb:hover {
+        background: @border-color-split;
+      }
 
       .conversation-item {
         padding: 12px 16px;
@@ -134,6 +155,26 @@
       padding: 16px;
       overflow-y: auto;
       background: @layout-body-background;
+      scrollbar-width: thin;
+      scrollbar-color: @border-color-base transparent;
+      scroll-behavior: smooth;
+
+      &::-webkit-scrollbar {
+        width: 6px;
+      }
+
+      &::-webkit-scrollbar-track {
+        background: transparent;
+      }
+
+      &::-webkit-scrollbar-thumb {
+        background: @border-color-base;
+        border-radius: 3px;
+      }
+
+      &::-webkit-scrollbar-thumb:hover {
+        background: @border-color-split;
+      }
 
       .loading-container {
         display: flex;
@@ -395,6 +436,7 @@
       height: 100%;
       z-index: 100;
       box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
+      transition: transform 0.3s ease;
 
       &.collapsed {
         transform: translateX(-100%);
@@ -411,6 +453,46 @@
           }
         }
       }
+
+      .input-area {
+        .input-container {
+          flex-direction: column;
+          gap: 8px;
+
+          .send-button {
+            align-self: flex-end;
+            width: auto;
+            min-width: 80px;
+          }
+        }
+      }
+    }
+  }
+}
+
+// Extra small devices
+@media (max-width: 480px) {
+  .chat-container {
+    min-height: 400px;
+    max-height: 90vh;
+
+    .chat-main {
+      .messages-container {
+        padding: 12px;
+
+        .message {
+          margin-bottom: 16px;
+
+          .message-content {
+            max-width: 90%;
+            padding: 10px 12px;
+          }
+        }
+      }
+
+      .input-area {
+        padding: 12px;
+      }
     }
   }
 }
@@ -593,6 +675,47 @@ body[data-theme='dark'] .chat-container {
       color: fade(@white, 45%) !important;
     }
   }
+
+  // Fix dropdown/select styling in dark theme
+  .ant-select {
+    .ant-select-selector {
+      background: fade(@white, 8%) !important;
+      border-color: @border-color-split !important;
+      color: fade(@white, 85%) !important;
+    }
+
+    .ant-select-selection-placeholder {
+      color: fade(@white, 45%) !important;
+    }
+
+    &:hover .ant-select-selector {
+      border-color: @primary-color !important;
+    }
+
+    &.ant-select-focused .ant-select-selector {
+      border-color: @primary-color !important;
+      box-shadow: 0 0 0 2px fade(@primary-color, 20%) !important;
+    }
+  }
+
+  // Fix dropdown options styling
+  .ant-select-dropdown {
+    background: #141414 !important;
+    border: 1px solid @border-color-split !important;
+
+    .ant-select-item {
+      color: fade(@white, 85%) !important;
+
+      &:hover {
+        background: fade(@white, 8%) !important;
+      }
+
+      &.ant-select-item-option-selected {
+        background: @primary-color !important;
+        color: @white !important;
+      }
+    }
+  }
 }
 
 // Additional high-specificity overrides for dark theme
diff --git a/web-app/src/app/shared/components/ai-chat/chat.component.ts 
b/web-app/src/app/shared/components/ai-chat/chat.component.ts
index cd4fb0f0f..6c0002b1d 100644
--- a/web-app/src/app/shared/components/ai-chat/chat.component.ts
+++ b/web-app/src/app/shared/components/ai-chat/chat.component.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { Component, OnInit, ViewChild, ElementRef, AfterViewChecked, 
ChangeDetectorRef } from '@angular/core';
+import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef, 
OnDestroy } from '@angular/core';
 import { I18NService } from '@core';
 import { NzMessageService } from 'ng-zorro-antd/message';
 import { NzModalService } from 'ng-zorro-antd/modal';
@@ -32,7 +32,7 @@ import { ThemeService } from '../../../service/theme.service';
   templateUrl: './chat.component.html',
   styleUrls: ['./chat.component.less']
 })
-export class ChatComponent implements OnInit, AfterViewChecked {
+export class ChatComponent implements OnInit, OnDestroy {
   @ViewChild('messagesContainer') private messagesContainer!: ElementRef;
 
   conversations: ConversationDto[] = [];
@@ -42,6 +42,7 @@ export class ChatComponent implements OnInit, 
AfterViewChecked {
   isLoading = false;
   sidebarCollapsed = false;
   theme: string = 'default';
+  private scrollTimeout: any;
 
   // OpenAI Configuration
   isOpenAiConfigured = false;
@@ -65,8 +66,22 @@ export class ChatComponent implements OnInit, 
AfterViewChecked {
     this.checkAiConfiguration();
   }
 
-  ngAfterViewChecked(): void {
-    this.scrollToBottom();
+  ngOnDestroy(): void {
+    if (this.scrollTimeout) {
+      clearTimeout(this.scrollTimeout);
+    }
+  }
+
+  /**
+   * Debounced scroll to bottom to improve performance
+   */
+  private scrollToBottomDebounced(): void {
+    if (this.scrollTimeout) {
+      clearTimeout(this.scrollTimeout);
+    }
+    this.scrollTimeout = setTimeout(() => {
+      this.scrollToBottom();
+    }, 100);
   }
 
   /**
@@ -403,13 +418,19 @@ export class ChatComponent implements OnInit, 
AfterViewChecked {
   }
 
   /**
-   * Scroll to bottom of messages
+   * Scroll to bottom of messages with smooth animation
    */
   private scrollToBottom(): void {
     try {
       if (this.messagesContainer) {
         const element = this.messagesContainer.nativeElement;
-        element.scrollTop = element.scrollHeight;
+        // Use requestAnimationFrame for better performance
+        requestAnimationFrame(() => {
+          element.scrollTo({
+            top: element.scrollHeight,
+            behavior: 'smooth'
+          });
+        });
       }
     } catch (err) {
       console.error('Error scrolling to bottom:', err);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to