1 import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
2 import { NzMessageService } from 'ng-zorro-antd';
3 import { SSE } from "sse.js";
4 import { ActivatedRoute } from '@angular/router';
5 import { MaasApi } from '@src/app/api/maas.api';
6 import { TranslateService } from '@ngx-translate/core';
7 import { MaasService } from '../maas-service.service';
8 export type StatusEnum = 'typing' | 'finished';
9 export type Chat = { question: string, answer: string, questionId: string, status: StatusEnum };
11 selector: 'app-use-application',
12 templateUrl: './use-application.component.html',
13 styleUrls: ['./use-application.component.less']
15 export class UseApplicationComponent implements OnInit {
17 communicationMessage: string;
18 chatHistory: Chat[] = [];
19 apiUrl = '/api/usecaseui-llm-adaptation/v1/application/chat';
20 queryParams: { id?: string; name?: string } = {};
21 selectedName: string | null = null;
22 options: Array<{ nzValue: string, nzLabel: string }> = [];
23 send = this.translate.instant('maas.send');
24 private currentSSE: SSE | null = null;
25 isGeneratingAnswer: boolean = false;
26 stopGenerating = this.translate.instant('maas.stopGenerating');
29 private message: NzMessageService,
30 private route: ActivatedRoute,
31 private myhttp: MaasApi,
32 private translate: TranslateService,
33 private maasService: MaasService
37 await this.fetchAllApplication();
38 this.route.queryParams.subscribe(params => {
39 this.queryParams = params;
40 this.selectedName = this.queryParams.id || this.selectedName;
45 if (this.currentSSE) {
46 this.currentSSE.close();
51 if (this.isGeneratingAnswer) {
53 this.chatHistory.forEach(item => {item.status = 'finished'});
54 this.isGeneratingAnswer = false;
56 this.submitQuestion();
64 this.isGeneratingAnswer = true;
66 applicationId: this.selectedName,
67 question: this.question,
68 questionId: this.maasService.generateUniqueId()
70 this.currentSSE = new SSE(this.apiUrl, { headers: { 'Content-Type': 'application/json' }, payload: JSON.stringify(chatParam), method: 'POST' });
71 const questionId = chatParam.questionId;
72 this.chatHistory.push({ question: chatParam.question, questionId: chatParam.questionId, answer: '', status: 'typing' });
73 this.currentSSE.addEventListener('message', (event) => {
74 const chat = this.chatHistory.find(chatItem => chatItem.questionId === questionId);
76 if (['[DONE]', 'Network Error'].includes(event.data)) {
77 chat.status = 'finished';
78 this.isGeneratingAnswer = false;
79 if (event.data === 'Network Error') {
80 this.updateAnswer(event, chat);
84 this.updateAnswer(event, chat);
88 this.currentSSE.addEventListener('error', () => {
89 this.currentSSE = null;
90 this.isGeneratingAnswer = false;
92 this.currentSSE.addEventListener('close', () => {
93 this.currentSSE = null;
94 this.isGeneratingAnswer = false;
99 updateAnswer(event: any, chat: Chat): void {
100 chat.answer += event.data.replace(/__SPACE__/g, ' ');
103 async fetchAllApplication(): Promise<void> {
105 const data = await this.myhttp.getAllApplication().toPromise();
106 this.options = data.result_body.map(item => ({
107 nzValue: item.applicationId,
108 nzLabel: item.applicationName
110 this.selectedName = this.options.length > 0 ? this.options[0].nzValue : '';
112 this.message.error('Failed to obtain intent data');
116 async copy(content: string): Promise<void> {
118 await (navigator as any).clipboard.writeText(content);
119 this.message.success(this.translate.instant('maas.copy_to_clipboard'));
121 console.error(this.translate.instant('maas.copy_failed') + ': ', err);
125 deleteQuestion(questionId: string): void {
126 this.chatHistory = this.chatHistory.filter(item => item.questionId !== questionId);