Spaces:
Running
Running
import { Component, OnInit, OnDestroy, ViewChild, ElementRef, AfterViewChecked } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { FormBuilder, ReactiveFormsModule, Validators, FormsModule } from '@angular/forms'; | |
import { MatButtonModule } from '@angular/material/button'; | |
import { MatIconModule } from '@angular/material/icon'; | |
import { MatFormFieldModule } from '@angular/material/form-field'; | |
import { MatInputModule } from '@angular/material/input'; | |
import { MatCardModule } from '@angular/material/card'; | |
import { MatSelectModule } from '@angular/material/select'; | |
import { MatDividerModule } from '@angular/material/divider'; | |
import { MatTooltipModule } from '@angular/material/tooltip'; | |
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; | |
import { Subscription } from 'rxjs'; | |
import { ApiService } from '../../services/api.service'; | |
interface ChatMessage { | |
author: 'user' | 'assistant'; | |
text: string; | |
timestamp?: Date; | |
} | |
({ | |
selector: 'app-chat', | |
standalone: true, | |
imports: [ | |
CommonModule, | |
FormsModule, | |
ReactiveFormsModule, | |
MatButtonModule, | |
MatIconModule, | |
MatFormFieldModule, | |
MatInputModule, | |
MatCardModule, | |
MatSelectModule, | |
MatDividerModule, | |
MatTooltipModule, | |
MatProgressSpinnerModule | |
], | |
templateUrl: './chat.component.html', | |
styleUrls: ['./chat.component.scss'] | |
}) | |
export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked { | |
'scrollMe') private myScrollContainer!: ElementRef; | (|
projects: string[] = []; | |
selectedProject: string | null = null; // Düzeltildi: ! kaldırıldı, null değer atandı | |
sessionId: string | null = null; | |
messages: ChatMessage[] = []; | |
input = this.fb.control('', Validators.required); | |
loading = false; | |
error = ''; | |
private subs = new Subscription(); | |
private shouldScroll = false; | |
constructor( | |
private fb: FormBuilder, | |
private api: ApiService | |
) {} | |
ngOnInit(): void { | |
this.loadProjects(); | |
} | |
ngAfterViewChecked() { | |
if (this.shouldScroll) { | |
this.scrollToBottom(); | |
this.shouldScroll = false; | |
} | |
} | |
ngOnDestroy(): void { | |
this.subs.unsubscribe(); | |
} | |
loadProjects(): void { | |
this.loading = true; | |
const sub = this.api.getChatProjects().subscribe({ | |
next: projects => { | |
this.projects = projects; | |
this.loading = false; | |
if (projects.length === 0) { | |
this.error = 'No enabled projects found. Please enable a project with published version.'; | |
} | |
}, | |
error: (err) => { | |
this.error = 'Failed to load projects'; | |
this.loading = false; | |
console.error('Load projects error:', err); | |
} | |
}); | |
this.subs.add(sub); | |
} | |
startChat(): void { | |
if (!this.selectedProject) return; | |
this.loading = true; | |
this.error = ''; | |
const sub = this.api.startChat(this.selectedProject).subscribe({ | |
next: res => { | |
this.sessionId = res.session_id; | |
this.messages = [{ | |
author: 'assistant', | |
text: res.answer, | |
timestamp: new Date() | |
}]; | |
this.loading = false; | |
this.shouldScroll = true; | |
}, | |
error: (err) => { | |
this.error = err.error?.detail || 'Failed to start session'; | |
this.loading = false; | |
console.error('Start chat error:', err); | |
} | |
}); | |
this.subs.add(sub); | |
} | |
send(): void { | |
if (!this.sessionId || this.input.invalid) return; | |
const text = this.input.value!.trim(); | |
if (!text) return; | |
// Add user message | |
this.messages.push({ | |
author: 'user', | |
text, | |
timestamp: new Date() | |
}); | |
this.input.reset(); | |
this.loading = true; | |
this.shouldScroll = true; | |
// Send to backend | |
const sub = this.api.chat(this.sessionId, text).subscribe({ | |
next: res => { | |
this.messages.push({ | |
author: 'assistant', | |
text: res.answer, | |
timestamp: new Date() | |
}); | |
this.loading = false; | |
this.shouldScroll = true; | |
}, | |
error: (err) => { | |
this.messages.push({ | |
author: 'assistant', | |
text: '⚠️ ' + (err.error?.detail || 'Failed to send message. Please try again.'), | |
timestamp: new Date() | |
}); | |
this.loading = false; | |
this.shouldScroll = true; | |
console.error('Chat error:', err); | |
} | |
}); | |
this.subs.add(sub); | |
} | |
endSession(): void { | |
this.sessionId = null; | |
this.messages = []; | |
this.selectedProject = null; | |
this.input.reset(); | |
this.error = ''; | |
} | |
private scrollToBottom(): void { | |
try { | |
if (this.myScrollContainer) { | |
this.myScrollContainer.nativeElement.scrollTop = | |
this.myScrollContainer.nativeElement.scrollHeight; | |
} | |
} catch(err) { | |
console.error('Scroll error:', err); | |
} | |
} | |
} |