Skip to content

Commit 7a8aa31

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 7a8aa31

2 files changed

Lines changed: 22 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: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {HttpClient} from '@angular/common/http';
2-
import {Component, input, output} from '@angular/core';
2+
import {Component, ElementRef, inject, Injector, input, output, signal, viewChild} from '@angular/core';
33
import {FormsModule} from '@angular/forms';
44
import {firstValueFrom} from 'rxjs';
55
import {
@@ -20,17 +20,20 @@ interface Model {
2020
styleUrl: './ai-assistant.scss',
2121
imports: [FormsModule, MessageSpinner],
2222
host: {
23-
'[class.expanded]': 'isExpanded',
23+
'[class.expanded]': 'isExpanded()',
2424
},
2525
})
2626
export class AiAssistant {
2727
readonly reportGroupId = input.required<string>();
2828
readonly close = output();
2929

3030
protected messages: AiChatMessage[] = [];
31-
protected userInput = '';
32-
protected isLoading = false;
33-
protected isExpanded = false;
31+
protected userInput = signal('');
32+
protected isLoading = signal(false);
33+
protected isExpanded = signal(false);
34+
protected messagesContainer = viewChild('messagesContainer', {read: ElementRef});
35+
36+
private readonly http = inject(HttpClient);
3437

3538
protected readonly models: Model[] = [
3639
{id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash'},
@@ -39,23 +42,21 @@ export class AiAssistant {
3942
];
4043
protected selectedModel = this.models[0].id;
4144

42-
constructor(private readonly http: HttpClient) {}
43-
4445
protected toggleExpanded(): void {
45-
this.isExpanded = !this.isExpanded;
46+
this.isExpanded.set(!this.isExpanded());
4647
}
4748

4849
async send(): Promise<void> {
49-
if (!this.userInput.trim() || this.isLoading) {
50+
if (!this.userInput().trim() || this.isLoading()) {
5051
return;
5152
}
5253

5354
const pastMessages = this.messages.slice();
5455

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

6061
const payload: AiChatRequest = {
6162
prompt,
@@ -75,7 +76,7 @@ export class AiAssistant {
7576
text: 'Sorry, I failed to get a response. Please try again.',
7677
});
7778
} finally {
78-
this.isLoading = false;
79+
this.isLoading.set(false);
7980
}
8081
}
8182
}

0 commit comments

Comments
 (0)