Skip to content

Commit 314d39a

Browse files
committed
refactor: use signals in the AI Assistant UI
This commit updates the AI Assistant UI to use signals, to fix the problem with not clearing the textarea after the message submission (likely appeared after switching to zoneless).
1 parent 669fd90 commit 314d39a

2 files changed

Lines changed: 31 additions & 20 deletions

File tree

report-app/src/app/shared/ai-assistant/ai-assistant.html

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ <h2>AI Assistant</h2>
1515
<div class="header-actions">
1616
<button class="expand-button" (click)="toggleExpanded()">
1717
<span class="material-symbols-outlined">
18-
@if (isExpanded) {
18+
@if (isExpanded()) {
1919
close_fullscreen
2020
} @else {
2121
open_in_full
@@ -38,7 +38,7 @@ <h2>AI Assistant</h2>
3838
<div [innerHTML]="message.text"></div>
3939
</div>
4040
}
41-
@if (isLoading) {
41+
@if (isLoading()) {
4242
<div class="message model-message">
4343
<message-spinner message="Thinking..." />
4444
</div>
@@ -47,12 +47,13 @@ <h2>AI Assistant</h2>
4747
<div class="input-container">
4848
<textarea
4949
#userInputElement
50-
[(ngModel)]="userInput"
50+
[ngModel]="userInput()"
51+
(ngModelChange)="userInput.set($event)"
5152
placeholder="Ask a question about the report..."
52-
(keydown.enter)="send()"
53-
[readonly]="isLoading"
53+
(keydown.enter)="$event.preventDefault(); send()"
54+
[readonly]="isLoading()"
5455
></textarea>
55-
<button (click)="send()" [disabled]="isLoading">
56+
<button (click)="send()" [disabled]="isLoading()">
5657
<span class="material-symbols-outlined">send</span>
5758
</button>
5859
</div>

report-app/src/app/shared/ai-assistant/ai-assistant.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import {HttpClient} from '@angular/common/http';
2-
import {Component, input, output} from '@angular/core';
2+
import {
3+
Component,
4+
ElementRef,
5+
inject,
6+
Injector,
7+
input,
8+
output,
9+
signal,
10+
viewChild,
11+
} from '@angular/core';
312
import {FormsModule} from '@angular/forms';
413
import {firstValueFrom} from 'rxjs';
514
import {
@@ -20,17 +29,20 @@ interface Model {
2029
styleUrl: './ai-assistant.scss',
2130
imports: [FormsModule, MessageSpinner],
2231
host: {
23-
'[class.expanded]': 'isExpanded',
32+
'[class.expanded]': 'isExpanded()',
2433
},
2534
})
2635
export class AiAssistant {
2736
readonly reportGroupId = input.required<string>();
2837
readonly close = output();
2938

3039
protected messages: AiChatMessage[] = [];
31-
protected userInput = '';
32-
protected isLoading = false;
33-
protected isExpanded = false;
40+
protected userInput = signal('');
41+
protected isLoading = signal(false);
42+
protected isExpanded = signal(false);
43+
protected messagesContainer = viewChild('messagesContainer', {read: ElementRef});
44+
45+
private readonly http = inject(HttpClient);
3446

3547
protected readonly models: Model[] = [
3648
{id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash'},
@@ -39,23 +51,21 @@ export class AiAssistant {
3951
];
4052
protected selectedModel = this.models[0].id;
4153

42-
constructor(private readonly http: HttpClient) {}
43-
4454
protected toggleExpanded(): void {
45-
this.isExpanded = !this.isExpanded;
55+
this.isExpanded.set(!this.isExpanded());
4656
}
4757

4858
async send(): Promise<void> {
49-
if (!this.userInput.trim() || this.isLoading) {
59+
if (!this.userInput().trim() || this.isLoading()) {
5060
return;
5161
}
5262

5363
const pastMessages = this.messages.slice();
5464

55-
this.messages.push({role: 'user', text: this.userInput});
56-
const prompt = this.userInput;
57-
this.userInput = '';
58-
this.isLoading = true;
65+
this.messages.push({role: 'user', text: this.userInput()});
66+
const prompt = this.userInput();
67+
this.userInput.set('');
68+
this.isLoading.set(true);
5969

6070
const payload: AiChatRequest = {
6171
prompt,
@@ -75,7 +85,7 @@ export class AiAssistant {
7585
text: 'Sorry, I failed to get a response. Please try again.',
7686
});
7787
} finally {
78-
this.isLoading = false;
88+
this.isLoading.set(false);
7989
}
8090
}
8191
}

0 commit comments

Comments
 (0)