Skip to content

[feature]:AI Chatbot support #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ea31fc1
Chatbot impl
hritikchaudhary Sep 19, 2024
e954f79
Merge branch 'master' into master
Aias00 Sep 21, 2024
428c322
Merge branch 'master' into master
yuluo-yx Sep 21, 2024
b9f5479
Merge branch 'master' into master
yuluo-yx Sep 22, 2024
180a38a
Merge branch 'master' into master
Aias00 Sep 23, 2024
2096ce5
Merge branch 'master' into master
Aias00 Sep 24, 2024
0744c1a
Merge branch 'master' into master
Aias00 Sep 25, 2024
3178d2d
Merge branch 'master' into master
Aias00 Sep 25, 2024
74dc051
Merge branch 'master' into master
Aias00 Sep 28, 2024
f103709
Merge branch 'master' into master
Aias00 Sep 30, 2024
d883c28
Merge branch 'master' into master
Aias00 Oct 8, 2024
9e9cab1
Merge branch 'master' into master
yuluo-yx Oct 10, 2024
7cfdaf7
Merge branch 'master' into master
Aias00 Oct 13, 2024
e8b1bd9
Merge branch 'master' into master
Aias00 Oct 16, 2024
e833c43
Merge branch 'master' into master
Aias00 Oct 26, 2024
552cf09
Merge branch 'master' into master
Aias00 Oct 26, 2024
6e65b61
Merge branch 'master' into master
Aias00 Oct 27, 2024
37bd6a4
Merge branch 'master' into master
Aias00 Oct 29, 2024
54168e6
Merge branch 'master' into master
Aias00 Oct 29, 2024
0037ed7
Merge branch 'master' into master
Aias00 Oct 31, 2024
f15db0a
Merge branch 'master' into master
Aias00 Nov 1, 2024
cb4c4e8
Merge branch 'master' into master
Aias00 Nov 5, 2024
5cc37d4
Merge branch 'master' into master
Aias00 Nov 8, 2024
161024b
Merge branch 'master' into master
Aias00 Nov 8, 2024
bda848d
Merge branch 'master' into master
zuobiao-zhou Nov 9, 2024
0ea7965
Merge branch 'master' into master
Aias00 Nov 12, 2024
ef3da72
Merge branch 'master' into master
yuluo-yx Nov 16, 2024
550bc2c
Merge branch 'master' into master
Aias00 Nov 19, 2024
05f2e4e
Merge branch 'master' into master
Calvin979 Nov 24, 2024
1c4b2e3
Merge branch 'master' into master
Aias00 Nov 27, 2024
0a3eb83
Merge branch 'master' into master
Aias00 Dec 5, 2024
62a25d8
Merge branch 'master' into master
Aias00 Dec 5, 2024
3eb9c5d
Merge branch 'master' into master
Aias00 Dec 14, 2024
0ceabd6
Merge branch 'master' into master
Aias00 Dec 16, 2024
ce6fb19
Merge branch 'master' into master
Aias00 Dec 28, 2024
338aa17
Merge branch 'master' into master
Aias00 Jan 3, 2025
9cd1cc1
Merge branch 'master' into master
Aias00 Jan 3, 2025
2f61ca9
Merge branch 'master' into master
Aias00 Mar 23, 2025
82593e2
Merge branch 'master' into master
Aias00 Mar 24, 2025
6d446e4
Merge branch 'master' into master
Aias00 Mar 24, 2025
b205591
Merge branch 'master' into master
Aias00 Mar 25, 2025
d721d44
Merge branch 'master' into master
Aias00 Mar 31, 2025
520f123
Merge branch 'master' into master
Aias00 Mar 31, 2025
75a7588
Merge branch 'master' into master
Aias00 Mar 31, 2025
043939b
Merge branch 'master' into master
Aias00 Apr 2, 2025
7a88a4b
Merge branch 'master' into master
Aias00 Apr 2, 2025
54b27a6
Merge branch 'master' into master
Aias00 Apr 3, 2025
1b61f6b
Merge branch 'master' into master
Aias00 Apr 7, 2025
7f6e27a
Merge branch 'master' into master
Aias00 Apr 14, 2025
0924208
Merge branch 'master' into master
Aias00 Apr 14, 2025
3e7c5c7
Merge branch 'master' into master
Aias00 Apr 18, 2025
8412b9e
Merge branch 'master' into master
Aias00 Apr 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion web-app/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpClient } from '@angular/common/http';
import { Component, ElementRef, Inject, OnInit, Renderer2 } from '@angular/core';
import { NavigationEnd, NavigationError, RouteConfigLoadStart, Router } from '@angular/router';
import { I18NService } from '@core';
Expand All @@ -10,7 +11,10 @@ import { ThemeService } from './service/theme.service';

@Component({
selector: 'app-root',
template: ` <router-outlet></router-outlet> `
template: `
<router-outlet></router-outlet>
<app-chatbot></app-chatbot>
`
})
export class AppComponent implements OnInit {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.message {
margin-bottom: 5px;
padding: 5px;
border-radius: 4px;
background-color: #f1f1f1;
max-width: 100%;
word-wrap: break-word;
display: flex;
align-items: center;
}

.message p {
margin: 0;
flex-grow: 1;
}

.copy-btn {
border: none;
background: transparent;
cursor: pointer;
font-size: 1rem;
margin-right: 5px;
color: #3f51b5;
}

.copy-btn:hover {
color: #0056b3;
}

.hint {
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
background-color: #3f51b5;
color: white;
padding: 3px 8px;
border-radius: 4px;
font-size: 0.75rem;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}

.copy-btn .hint {
opacity: 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="message" *ngIf="message.sender === 'AI'">
<p><strong>{{ message.sender }}:</strong> {{ message.text }}</p>
<button class="copy-btn" (click)="copyToClipboard(message.text)">
📋
<span class="hint" *ngIf="copied">Copied!</span>
</button>
</div>
Comment on lines +1 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve accessibility for the copy button

The copy button lacks proper accessibility attributes, which makes it difficult for screen reader users to understand its purpose.

-<button class="copy-btn" (click)="copyToClipboard(message.text)">
+<button class="copy-btn" (click)="copyToClipboard(message.text)" aria-label="Copy message to clipboard" title="Copy to clipboard">
  📋
  <span class="hint" *ngIf="copied">Copied!</span>
</button>

<div class="message" *ngIf="message.sender !== 'AI'">
<p><strong>{{ message.sender }}:</strong> {{ message.text }}</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-chat-message',
templateUrl: './chat-message.component.html',
styleUrls: ['./chat-message.component.css'],
})
export class ChatMessageComponent {
@Input() message!: { sender: string; text: string };
copied: boolean = false;

copyToClipboard(text: string) {
navigator.clipboard.writeText(text).then(
() => {
this.copied = true;
setTimeout(() => this.copied = false, 2000); // Reset hint after 2 seconds
},
(err) => {
console.error('Failed to copy text: ', err);
}
);
}
}
96 changes: 96 additions & 0 deletions web-app/src/app/shared/components/chatbot/chatbot.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.float {
position: fixed;
bottom: 2rem;
right: 2rem;
border: none;
background: transparent;
padding: 0;
cursor: pointer;
}
Comment on lines +1 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add accessibility attributes to the chat button

Improve accessibility by adding appropriate ARIA attributes to the floating chat button.

This will help screen readers identify the purpose of the button. Update the HTML template to include these attributes:

<button class="float" aria-label="Open chat assistant" title="Chat with AI assistant">
  <img src="path-to-chat-icon.png" alt="Chat icon">
</button>


.float img {
width: 3rem;
height: 3rem;
}

.popup {
position: fixed;
bottom: 5rem;
right: 2rem;
width: 310px;
max-height: 400px;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
background-color: white;
z-index: 1000;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.popup-content {
padding: 10px;
display: flex;
flex-direction: column;
align-items: flex-start;
height: 100%;
}

.close-btn {
align-self: flex-end;
border: none;
background: transparent;
cursor: pointer;
font-size: 1rem;
}

.chat-window {
display: flex;
flex-direction: column;
flex-grow: 1;
width: 100%;
}

.chat-messages {
flex-grow: 1;
overflow-y: auto; /* Enables vertical scrolling */
max-height: 200px; /* Set a maximum height for the chat window */
margin-bottom: 10px;
width: 100%;
padding-right: 5px; /* Optional: Adds some padding for better readability */
}

.input-container {
display: flex;
align-items: center;
width: 100%;
}

input[type='text'] {
flex-grow: 1;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 5px;
}

button {
border: none;
background-color: #3f51b5;
color: white;
padding: 6px 10px;
border-radius: 4px;
cursor: pointer;
margin-right: 5px;
height: 34px;
}

.reset-btn {
background-color: #dc3545;
margin-right: 0;
}

.reset-btn:hover {
background-color: #c82333;
}
19 changes: 19 additions & 0 deletions web-app/src/app/shared/components/chatbot/chatbot.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<button class="float" (click)="togglePopup()">
<img src="../assets/img/chatbot-icon.svg" alt="Ai Chat" />
</button>
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the asset path for the chatbot icon

The image path uses a relative path which might be incorrect depending on the project structure. Angular typically uses absolute paths from the assets folder.


🏁 Script executed:

#!/bin/bash
# Check if the chatbot icon exists at the specified path
# Find the assets directory and check for the chatbot-icon.svg
echo "Checking for chatbot icon file..."
fd -t f "chatbot-icon.svg" --full-path

Length of output: 155


Use an absolute asset path for the chatbot icon

The file chatbot-icon.svg does exist at web-app/src/assets/img/chatbot-icon.svg and will be served from /assets/img/chatbot-icon.svg. Relying on a relative path (../assets/...) can break when the app is on a nested route, since URLs resolve against the current browser path. Update the src to an absolute path:

<button class="float" (click)="togglePopup()">
-  <img src="../assets/img/chatbot-icon.svg" alt="Ai Chat" />
+  <img src="/assets/img/chatbot-icon.svg" alt="Ai Chat" />
</button>

— Ensure that all other asset references follow this pattern to avoid similar routing issues.

<div class="popup" *ngIf="isPopupVisible">
<div class="popup-content">
<button class="close-btn" (click)="togglePopup()">✖</button>
<h3>Chatbot</h3>
<div class="chat-window">
<div class="chat-messages">
<app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
</div>
<div class="input-container">
<input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation

Currently, the user can send empty messages as there's no validation on the input. This could result in unnecessary API calls and empty messages in the chat.

-<input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
+<input type="text" [(ngModel)]="userInput" (keydown.enter)="userInput.trim() && sendMessage()" placeholder="Type your message..." />
-<button (click)="sendMessage()">Send</button>
+<button (click)="sendMessage()" [disabled]="!userInput.trim()">Send</button>

<button (click)="sendMessage()">Send</button>
<button class="reset-btn" (click)="resetChat()">Reset</button>
Comment on lines +6 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve accessibility for buttons and inputs

The buttons and inputs in the chatbot lack proper accessibility attributes, making them difficult to use with screen readers.

-<button class="close-btn" (click)="togglePopup()">✖</button>
+<button class="close-btn" (click)="togglePopup()" aria-label="Close chatbot">✖</button>
<h3>Chatbot</h3>
<div class="chat-window">
  <div class="chat-messages">
    <app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
  </div>
  <div class="input-container">
-   <input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
+   <input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." aria-label="Message input" />
-   <button (click)="sendMessage()">Send</button>
+   <button (click)="sendMessage()" aria-label="Send message">Send</button>
-   <button class="reset-btn" (click)="resetChat()">Reset</button>
+   <button class="reset-btn" (click)="resetChat()" aria-label="Reset chat">Reset</button>
  </div>
</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button class="close-btn" (click)="togglePopup()"></button>
<h3>Chatbot</h3>
<div class="chat-window">
<div class="chat-messages">
<app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
</div>
<div class="input-container">
<input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
<button (click)="sendMessage()">Send</button>
<button class="reset-btn" (click)="resetChat()">Reset</button>
<button class="close-btn" (click)="togglePopup()" aria-label="Close chatbot"></button>
<h3>Chatbot</h3>
<div class="chat-window">
<div class="chat-messages">
<app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
</div>
<div class="input-container">
<input
type="text"
[(ngModel)]="userInput"
(keydown.enter)="sendMessage()"
placeholder="Type your message..."
aria-label="Message input"
/>
<button (click)="sendMessage()" aria-label="Send message">Send</button>
<button class="reset-btn" (click)="resetChat()" aria-label="Reset chat">Reset</button>
</div>
</div>

</div>
</div>
</div>
</div>
Comment on lines +1 to +19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add loading state and error handling

The chatbot UI doesn't show any loading indicators or error messages when interacting with the AI backend. This could lead to a poor user experience if the backend is slow or returns an error.

Add loading and error handling states to the template:

<div class="popup" *ngIf="isPopupVisible">
  <div class="popup-content">
    <button class="close-btn" (click)="togglePopup()">✖</button>
    <h3>Chatbot</h3>
    <div class="chat-window">
      <div class="chat-messages">
        <app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
+       <div *ngIf="isLoading" class="loading-indicator">AI is thinking...</div>
+       <div *ngIf="errorMessage" class="error-message">{{errorMessage}}</div>
      </div>
      <div class="input-container">
-       <input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
+       <input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." [disabled]="isLoading" />
-       <button (click)="sendMessage()">Send</button>
+       <button (click)="sendMessage()" [disabled]="isLoading || !userInput.trim()">Send</button>
        <button class="reset-btn" (click)="resetChat()">Reset</button>
      </div>
    </div>
  </div>
</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button class="float" (click)="togglePopup()">
<img src="../assets/img/chatbot-icon.svg" alt="Ai Chat" />
</button>
<div class="popup" *ngIf="isPopupVisible">
<div class="popup-content">
<button class="close-btn" (click)="togglePopup()"></button>
<h3>Chatbot</h3>
<div class="chat-window">
<div class="chat-messages">
<app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
</div>
<div class="input-container">
<input type="text" [(ngModel)]="userInput" (keydown.enter)="sendMessage()" placeholder="Type your message..." />
<button (click)="sendMessage()">Send</button>
<button class="reset-btn" (click)="resetChat()">Reset</button>
</div>
</div>
</div>
</div>
<button class="float" (click)="togglePopup()">
<img src="../assets/img/chatbot-icon.svg" alt="Ai Chat" />
</button>
<div class="popup" *ngIf="isPopupVisible">
<div class="popup-content">
<button class="close-btn" (click)="togglePopup()"></button>
<h3>Chatbot</h3>
<div class="chat-window">
<div class="chat-messages">
<app-chat-message *ngFor="let message of messages" [message]="message"></app-chat-message>
<div *ngIf="isLoading" class="loading-indicator">AI is thinking...</div>
<div *ngIf="errorMessage" class="error-message">{{errorMessage}}</div>
</div>
<div class="input-container">
<input
type="text"
[(ngModel)]="userInput"
(keydown.enter)="sendMessage()"
placeholder="Type your message..."
[disabled]="isLoading"
/>
<button (click)="sendMessage()" [disabled]="isLoading || !userInput.trim()">Send</button>
<button class="reset-btn" (click)="resetChat()">Reset</button>
</div>
</div>
</div>
</div>

46 changes: 46 additions & 0 deletions web-app/src/app/shared/components/chatbot/chatbot.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
selector: 'app-chatbot',
templateUrl: './chatbot.component.html',
styleUrls: ['./chatbot.component.css'],
})
export class ChatbotComponent {
isPopupVisible = false;
userInput = '';
messages: { sender: string; text: string }[] = [];

constructor(private http: HttpClient) { }

togglePopup() {
this.isPopupVisible = !this.isPopupVisible;
}

sendMessage() {
if (this.userInput.trim()) {
// Add user's message to the chat window
this.messages.push({ sender: 'You', text: this.userInput });

// Send the message to the AI backend
this.http.post('/api/ai', { text: this.userInput }).subscribe(
(response: any) => {
// Add AI's response to the chat window
this.messages.push({ sender: 'AI', text: "sample answer" });
},
(error) => {
// Handle error response
this.messages.push({ sender: 'AI', text: 'Error communicating with AI' });
console.error('Error communicating with AI:', error);
}
);
Comment on lines +26 to +36
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix hardcoded AI response and add SSE streaming support

The current implementation doesn't use the actual API response and lacks support for SSE streaming mentioned in the PR description. This is likely causing the frontend display issue mentioned in the PR comments.

       // Send the message to the AI backend
-      this.http.post('/api/ai', { text: this.userInput }).subscribe(
-        (response: any) => {
-          // Add AI's response to the chat window
-          this.messages.push({ sender: 'AI', text: "sample answer" });
-        },
-        (error) => {
-          // Handle error response
-          this.messages.push({ sender: 'AI', text: 'Error communicating with AI' });
-          console.error('Error communicating with AI:', error);
-        }
-      );
+      // Add a placeholder response initially
+      const responseIndex = this.messages.length;
+      this.messages.push({ sender: 'AI', text: 'Thinking...' });
+      
+      // Setup EventSource for SSE streaming
+      const source = new EventSource(`/api/ai/stream?query=${encodeURIComponent(this.userInput)}`);
+      
+      let responseText = '';
+      
+      source.onmessage = (event) => {
+        try {
+          const data = JSON.parse(event.data);
+          if (data.text) {
+            responseText += data.text;
+            // Update the ongoing response
+            this.messages[responseIndex] = { sender: 'AI', text: responseText };
+          }
+        } catch (e) {
+          console.error('Error parsing SSE data:', e);
+        }
+      };
+      
+      source.onerror = (error) => {
+        console.error('SSE Error:', error);
+        // If responseText is empty, show error message, otherwise keep what we received
+        if (!responseText) {
+          this.messages[responseIndex] = { sender: 'AI', text: 'Error communicating with AI' };
+        }
+        source.close();
+      };
+      
+      source.addEventListener('end', () => {
+        source.close();
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.http.post('/api/ai', { text: this.userInput }).subscribe(
(response: any) => {
// Add AI's response to the chat window
this.messages.push({ sender: 'AI', text: "sample answer" });
},
(error) => {
// Handle error response
this.messages.push({ sender: 'AI', text: 'Error communicating with AI' });
console.error('Error communicating with AI:', error);
}
);
// Send the message to the AI backend
// Add a placeholder response initially
const responseIndex = this.messages.length;
this.messages.push({ sender: 'AI', text: 'Thinking...' });
// Setup EventSource for SSE streaming
const source = new EventSource(
`/api/ai/stream?query=${encodeURIComponent(this.userInput)}`
);
let responseText = '';
source.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
if (data.text) {
responseText += data.text;
// Update the ongoing response
this.messages[responseIndex] = { sender: 'AI', text: responseText };
}
} catch (e) {
console.error('Error parsing SSE data:', e);
}
};
source.onerror = (error) => {
console.error('SSE Error:', error);
// If nothing has come through yet, show an error message
if (!responseText) {
this.messages[responseIndex] = {
sender: 'AI',
text: 'Error communicating with AI'
};
}
source.close();
};
// Close the connection when the server signals end-of-stream
source.addEventListener('end', () => {
source.close();
});


// Clear the input field
this.userInput = '';
}
}

resetChat() {
this.messages = [];
}
}
8 changes: 6 additions & 2 deletions web-app/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { I18nElsePipe } from './pipe/i18n-else.pipe';
import { TimezonePipe } from './pipe/timezone.pipe';
import { SHARED_DELON_MODULES } from './shared-delon.module';
import { SHARED_ZORRO_MODULES } from './shared-zorro.module';
import { ChatbotComponent } from './components/chatbot/chatbot.component';
import { ChatMessageComponent } from './components/chat-message/chat-message.component';

const ThirdModules: Array<Type<void>> = [];
const COMPONENTS: Array<Type<void>> = [
Expand All @@ -30,7 +32,9 @@ const COMPONENTS: Array<Type<void>> = [
ToolbarComponent,
ConfigurableFieldComponent,
FormFieldComponent,
MonitorSelectMenuComponent
MonitorSelectMenuComponent,
ChatbotComponent,
ChatMessageComponent
];
const DIRECTIVES: Array<Type<void>> = [TimezonePipe, I18nElsePipe, ElapsedTimePipe];

Expand Down Expand Up @@ -69,4 +73,4 @@ const DIRECTIVES: Array<Type<void>> = [TimezonePipe, I18nElsePipe, ElapsedTimePi
...DIRECTIVES
]
})
export class SharedModule {}
export class SharedModule { }
7 changes: 7 additions & 0 deletions web-app/src/assets/img/chatbot-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.