summaryrefslogtreecommitdiffstats
path: root/usecaseui-portal/src/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'usecaseui-portal/src/app/views')
-rw-r--r--usecaseui-portal/src/app/views/maas/build/application-detail/application-detail.component.html2
-rw-r--r--usecaseui-portal/src/app/views/maas/build/application-management.component.html8
-rw-r--r--usecaseui-portal/src/app/views/maas/build/application-management.component.ts50
-rw-r--r--usecaseui-portal/src/app/views/maas/build/application.type.ts9
-rw-r--r--usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.html20
-rw-r--r--usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.less11
-rw-r--r--usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.ts58
-rw-r--r--usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.html18
-rw-r--r--usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.less0
-rw-r--r--usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.spec.ts25
-rw-r--r--usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.ts109
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/create-knowledge-base/create-knowledge-base.component.ts25
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.html18
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.less21
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.ts106
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component.ts4
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.html10
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.ts36
-rw-r--r--usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base.type.ts39
-rw-r--r--usecaseui-portal/src/app/views/maas/maas-service.service.spec.ts15
-rw-r--r--usecaseui-portal/src/app/views/maas/maas-service.service.ts14
-rw-r--r--usecaseui-portal/src/app/views/maas/maas.module.ts30
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.html43
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.less190
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.ts99
25 files changed, 821 insertions, 139 deletions
diff --git a/usecaseui-portal/src/app/views/maas/build/application-detail/application-detail.component.html b/usecaseui-portal/src/app/views/maas/build/application-detail/application-detail.component.html
index 0827f477..e01cea5d 100644
--- a/usecaseui-portal/src/app/views/maas/build/application-detail/application-detail.component.html
+++ b/usecaseui-portal/src/app/views/maas/build/application-detail/application-detail.component.html
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<nz-modal [(nzVisible)]="showModal" nzTitle="Knowledge Base Detail" (nzOnCancel)="handleCancel()"
+<nz-modal [(nzVisible)]="showModal" nzTitle="Application Detail" (nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()" nzWidth="56%" nzHeight="800px" >
<app-descriptions>
<app-descriptions-item nzTitle="Application Name">{{applicationDetail.applicationName}}
diff --git a/usecaseui-portal/src/app/views/maas/build/application-management.component.html b/usecaseui-portal/src/app/views/maas/build/application-management.component.html
index 6496270a..53e112be 100644
--- a/usecaseui-portal/src/app/views/maas/build/application-management.component.html
+++ b/usecaseui-portal/src/app/views/maas/build/application-management.component.html
@@ -50,12 +50,14 @@
<td>{{data.largeModelName}}</td>
<td>
<i class="anticon anticon-menu-fold" (click)="displayApplicationDetails(data)"></i>
- <i class="anticon anticon-delete" (click)="delete(data)"></i>
+ <i class="anticon anticon-edit" (click)="edit(data)"></i>
+ <i class="anticon anticon-delete" (click)="showDeleteConfirm(data)"></i>
<i class="anticon anticon-link" (click)="navigateToDetail(data)"></i>
</td>
</tr>
</tbody>
</nz-table>
</div>
-<app-create-application-management *ngIf="createModalShow" [showModal]="createModalShow" (modalOpreation)="createModalClose($event)"></app-create-application-management>
-<app-application-detail *ngIf="applicationShow" [showModal]="applicationShow" (modalOpreation)="applicationDetailClose()" [applicationDetail]="applicationDetail"></app-application-detail> \ No newline at end of file
+<app-create-application-management *ngIf="createModalShow" [showModal]="createModalShow" (modalOpreation)="createModalClose($event)" [existedNames]="existedNames"></app-create-application-management>
+<app-application-detail *ngIf="applicationShow" [showModal]="applicationShow" (modalOpreation)="applicationDetailClose()" [applicationDetail]="applicationDetail"></app-application-detail>
+<app-edit-application *ngIf="editModalShow" [showModal]="editModalShow" (modalOpreation)="editModalClose($event)" [applicationId]="applicationId"></app-edit-application> \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/build/application-management.component.ts b/usecaseui-portal/src/app/views/maas/build/application-management.component.ts
index 61471de4..00c0c405 100644
--- a/usecaseui-portal/src/app/views/maas/build/application-management.component.ts
+++ b/usecaseui-portal/src/app/views/maas/build/application-management.component.ts
@@ -1,8 +1,10 @@
import { Component, OnInit } from '@angular/core';
-import { NzMessageService } from "ng-zorro-antd";
+import { NzMessageService, NzModalService } from "ng-zorro-antd";
import { Router } from '@angular/router';
-import { MaasService } from '@src/app/core/services/maas.service';
+import { MaasApi } from '@src/app/api/maas.api';
import { Application } from './application.type';
+import { modalClose } from '../knowledge-base-management/knowledge-base.type';
+import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-application-management',
@@ -14,11 +16,16 @@ export class ApplicationManagementComponent implements OnInit {
createModalShow = false;
applicationShow = false;
applicationDetail: Object = {};
+ editModalShow = false;
+ applicationId = '';
+ existedNames = [];
constructor(
- private myhttp: MaasService,
+ private myhttp: MaasApi,
private message: NzMessageService,
- private router: Router
+ private router: Router,
+ private modalService: NzModalService,
+ private translate: TranslateService
) { }
ngOnInit() {
@@ -30,6 +37,7 @@ export class ApplicationManagementComponent implements OnInit {
.subscribe(
(data) => {
this.data = data.result_body
+ this.existedNames = this.data.map(item => item.applicationName);
},
() => {
this.message.error('Failed to obtain application data');
@@ -41,7 +49,7 @@ export class ApplicationManagementComponent implements OnInit {
this.createModalShow = true;
}
- createModalClose($event: any): void {
+ createModalClose($event: modalClose): void {
this.createModalShow = false;
if ($event.cancel) {
return;
@@ -49,7 +57,7 @@ export class ApplicationManagementComponent implements OnInit {
this.getAllApplicationData()
}
- delete(data): void {
+ delete(data: Application): void {
this.myhttp.deleteApplicationById(data.applicationId).subscribe((data) => {
this.getAllApplicationData()
if (data.result_header.result_code === 200) {
@@ -62,7 +70,7 @@ export class ApplicationManagementComponent implements OnInit {
});
}
- navigateToDetail(data): void {
+ navigateToDetail(data: Application): void {
this.router.navigate(['maas/use'], { queryParams: { id: data.applicationId, name: data.applicationName } });
}
@@ -70,7 +78,7 @@ export class ApplicationManagementComponent implements OnInit {
this.applicationShow = false;
}
- displayApplicationDetails(data): void {
+ displayApplicationDetails(data: Application): void {
this.applicationShow = true;
this.myhttp.getApplicationById(data.applicationId)
.subscribe(
@@ -82,4 +90,30 @@ export class ApplicationManagementComponent implements OnInit {
}
)
}
+
+ edit(data: Application) {
+ this.applicationId = data.applicationId;
+ this.editModalShow = true;
+ }
+
+ showDeleteConfirm(data: Application): void {
+ this.modalService.error({
+ nzTitle: this.translate.instant('maas.deleteTitle'),
+ nzContent: this.translate.instant('maas.application.deleteApplicationContent'),
+ nzOkText: 'Yes',
+ nzOkType: 'danger',
+ nzOnOk: () => this.delete(data),
+ nzCancelText: 'No',
+ nzIconType: 'warning',
+ });
+ }
+
+ editModalClose($event: modalClose): void {
+ this.editModalShow = false;
+ if ($event.cancel) {
+ return;
+ }
+ this.getAllApplicationData()
+ }
+
} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/build/application.type.ts b/usecaseui-portal/src/app/views/maas/build/application.type.ts
index e3224e7c..a0348d7b 100644
--- a/usecaseui-portal/src/app/views/maas/build/application.type.ts
+++ b/usecaseui-portal/src/app/views/maas/build/application.type.ts
@@ -1,3 +1,4 @@
+import { Response } from '../knowledge-base-management/knowledge-base.type';
export type Application = {
"applicationId"?: string,
"applicationName": string,
@@ -14,6 +15,12 @@ export type Application = {
"prompt": string,
"temperature": number,
"top_p": number,
- "openingRemarks": string
+ "openingRemarks": string,
}
+export type ApplicationsResponse = Response<Application[]>;
+
+export type ApplicationResponse = Response<Application>;
+
+
+
diff --git a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.html b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.html
index c7c9b216..5a5bb445 100644
--- a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.html
+++ b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.html
@@ -22,7 +22,12 @@
<nz-form-control [nzSpan]="12">
<input type="text" nz-input formControlName="name">
<nz-form-explain *ngIf="validateForm.get('name').dirty && validateForm.get('name').errors">
- Please input application name!
+ <ng-container *ngIf="validateForm.get('name').hasError('required')">
+ Please input application name
+ </ng-container>
+ <ng-container *ngIf="validateForm.get('name').hasError('duplicated')">
+ {{ 'maas.nameDuplicateTip' | translate}}
+ </ng-container>
</nz-form-explain>
</nz-form-control>
</nz-form-item>
@@ -98,15 +103,22 @@
</nz-form-control>
</nz-form-item>
<nz-form-item>
- <nz-form-label [nzSpan]="8" nzFor="prompt">Prompt</nz-form-label>
+ <nz-form-label [nzSpan]="8" nzFor="prompt" nzRequired>Prompt</nz-form-label>
<nz-form-control [nzSpan]="12">
- <textarea rows="2" nz-input formControlName="prompt"></textarea>
+ <textarea #myTextarea id="myTextarea" rows="2" nz-input formControlName="prompt" [placeholder]="'maas.application.promptTip' | translate" maxlength="1000" minlength="20" (input)="updateCharCount()"></textarea>
+ <div #charCount id="charCount">0/1000</div>
+ <nz-form-explain *ngIf="validateForm.get('prompt').dirty && validateForm.get('prompt').errors">
+ {{ 'maas.application.promptTip' | translate}}
+ </nz-form-explain>
</nz-form-control>
</nz-form-item>
<nz-form-item>
- <nz-form-label [nzSpan]="8" nzFor="openingRemarks">Opening Remarks</nz-form-label>
+ <nz-form-label [nzSpan]="8" nzFor="openingRemarks" nzRequired>Opening Remarks</nz-form-label>
<nz-form-control [nzSpan]="12">
<textarea rows="2" nz-input formControlName="openingRemarks"></textarea>
+ <nz-form-explain *ngIf="validateForm.get('openingRemarks').dirty && validateForm.get('openingRemarks').errors">
+ Please input opening remarks!
+ </nz-form-explain>
</nz-form-control>
</nz-form-item>
diff --git a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.less b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.less
index e8e3fca4..9156f1f9 100644
--- a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.less
+++ b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.less
@@ -41,4 +41,15 @@
.nz-select-container {
width: 300px;
+}
+
+:host ::ng-deep #myTextarea {
+ position: relative;
+}
+
+#charCount {
+ position: absolute;
+ top: 9px;
+ right: 15px;
+ line-height: 20px;
} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.ts b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.ts
index 1bbef527..a4dba970 100644
--- a/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.ts
+++ b/usecaseui-portal/src/app/views/maas/build/create-application-management/create-application-management.component.ts
@@ -1,7 +1,10 @@
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { NzMessageService } from "ng-zorro-antd";
-import { FormBuilder, FormGroup, Validators } from '@angular/forms';
-import { MaasService } from '@src/app/core/services/maas.service';
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
+import { MaasApi } from '@src/app/api/maas.api';
+import { KnowledgeBase, MaaSPlatform, ModelInformation, Operators } from '../../knowledge-base-management/knowledge-base.type';
+import { Subject } from 'rxjs';
+import { debounceTime } from 'rxjs/operators';
@Component({
selector: 'app-create-application-management',
@@ -13,15 +16,19 @@ export class CreateApplicationManagementComponent implements OnInit {
validateForm: FormGroup;
@Input() showModal: boolean;
@Output() modalOpreation = new EventEmitter();
- operators: any[] = [];
- filteredPlatforms: any[] = [];
- filteredModels: any[] = [];
- knowledgeBases: any[] = [];
+ operators: Operators[] = [];
+ filteredPlatforms: MaaSPlatform[] = [];
+ filteredModels: ModelInformation[] = [];
+ knowledgeBases: KnowledgeBase[] = [];
temperature = 3;
top_p = 3;
+ private submitSubject = new Subject<void>();
+ @ViewChild('myTextarea') myTextarea: ElementRef;
+ @ViewChild('charCount') charCount: ElementRef;
+ @Input() existedNames: string[] = [];
constructor(
- private myhttp: MaasService,
+ private myhttp: MaasApi,
private message: NzMessageService,
private fb: FormBuilder
) { }
@@ -29,19 +36,28 @@ export class CreateApplicationManagementComponent implements OnInit {
ngOnInit() {
this.fetchOperators();
this.initFormData();
+ this.submitSubject.pipe(debounceTime(6000)).subscribe(() => this.executeSubmit());
+ }
+
+ nameDuplicateValidator = (control: FormControl): { [s: string]: boolean } => {
+ if (!control.value) {
+ return { required: true };
+ } else if (this.existedNames.includes(control.value)) {
+ return { duplicated: true, error: true };
+ }
}
initFormData() {
this.validateForm = this.fb.group({
- name: [null, [Validators.required]],
+ name: [null, [Validators.required, this.nameDuplicateValidator]],
description: [null],
applicationType: [null, [Validators.required]],
selectedOperator: [null, [Validators.required]],
selectedPlatform: [null, [Validators.required]],
selectedModel: [null, [Validators.required]],
selectKnowledgeBase: [null, [Validators.required]],
- prompt: [null],
- openingRemarks: [null],
+ prompt: [null, [Validators.required, Validators.minLength(20), Validators.maxLength(1000)]],
+ openingRemarks: [null, [Validators.required]],
temperature: [3, [Validators.required]],
temperatureSlider: [3],
top_p: [3, [Validators.required]],
@@ -60,7 +76,7 @@ export class CreateApplicationManagementComponent implements OnInit {
);
}
- handleOperatorChange(value: any): void {
+ handleOperatorChange(value: Operators): void {
if (value) {
this.filteredPlatforms = value.maaSPlatformList;
} else {
@@ -71,7 +87,7 @@ export class CreateApplicationManagementComponent implements OnInit {
this.validateForm.get('selectKnowledgeBase').setValue(null);
}
- handleMaasChange(value: any): void {
+ handleMaasChange(value: MaaSPlatform): void {
if (value) {
this.filteredModels = value.modelList;
this.fetchKnowledgeBase(value);
@@ -99,11 +115,16 @@ export class CreateApplicationManagementComponent implements OnInit {
}
handleOk() {
+ this.submitSubject.next();
+ }
+
+ private executeSubmit() {
this.submitForm();
if (this.validateForm.invalid) {
this.showModal = true;
return;
}
+
this.myhttp.createApplication(this.constructBody()).subscribe(
(response) => {
this.showModal = false;
@@ -120,6 +141,7 @@ export class CreateApplicationManagementComponent implements OnInit {
}
)
}
+
constructBody() {
const requestBody = {
applicationName: this.validateForm.value.name,
@@ -167,4 +189,12 @@ export class CreateApplicationManagementComponent implements OnInit {
toppInputChange(event: number): void {
this.validateForm.controls.top_pSlider.setValue(event);
}
-} \ No newline at end of file
+
+ updateCharCount() {
+ const textarea = this.myTextarea.nativeElement as HTMLTextAreaElement;
+ const charCount = textarea.value.length;
+ const maxLength = textarea.getAttribute('maxlength');
+ this.charCount.nativeElement.innerText = charCount + '/' + maxLength;
+ }
+}
+
diff --git a/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.html b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.html
new file mode 100644
index 00000000..d2fb553b
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.html
@@ -0,0 +1,18 @@
+<nz-modal [(nzVisible)]="showModal" [nzTitle]="title" (nzOnCancel)="handleCancel()"
+ (nzOnOk)="submitForm()" nzWidth="648px" nzHeight="800px">
+ <form nz-form [formGroup]="validateForm" (ngSubmit)="checkForm()">
+ <nz-form-item>
+ <nz-form-label [nzSpan]="8" nzFor="name" nzRequired>Application Name</nz-form-label>
+ <nz-form-control [nzSpan]="12">
+ <input nz-input formControlName="name" placeholder="Please input application name" />
+ <nz-form-explain *ngIf="validateForm.get('name').dirty && validateForm.get('name').errors">Please input application name</nz-form-explain>
+ </nz-form-control>
+ </nz-form-item>
+ <nz-form-item>
+ <nz-form-label [nzSpan]="8" nzFor="description">Application Description</nz-form-label>
+ <nz-form-control [nzSpan]="12">
+ <textarea rows="2" formControlName="description" nz-input></textarea>
+ </nz-form-control>
+ </nz-form-item>
+ </form>
+</nz-modal> \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.less b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.less
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.less
diff --git a/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.spec.ts b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.spec.ts
new file mode 100644
index 00000000..40fc6bd5
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditApplicationComponent } from './edit-application.component';
+
+describe('EditApplicationComponent', () => {
+ let component: EditApplicationComponent;
+ let fixture: ComponentFixture<EditApplicationComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ EditApplicationComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EditApplicationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.ts b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.ts
new file mode 100644
index 00000000..380cd5ff
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/build/edit-application/edit-application.component.ts
@@ -0,0 +1,109 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { MaasApi } from '@src/app/api/maas.api';
+import { NzMessageService } from 'ng-zorro-antd';
+import { Application } from '../application.type';
+
+@Component({
+ selector: 'app-edit-application',
+ templateUrl: './edit-application.component.html',
+ styleUrls: ['./edit-application.component.less']
+})
+export class EditApplicationComponent implements OnInit {
+ title = 'Edit Application';
+ @Input() showModal: boolean;
+ @Input() applicationId: string;
+ @Output() modalOpreation = new EventEmitter();
+ validateForm: FormGroup;
+ defalutApplication: Application = {
+ 'applicationId': '',
+ 'applicationName': '',
+ 'applicationDescription': '',
+ 'applicationType': '',
+ 'operatorId': '',
+ 'operatorName': '',
+ 'maaSPlatformId': '',
+ 'maaSPlatformName': '',
+ 'knowledgeBaseName': '',
+ 'knowledgeBaseId': '',
+ 'largeModelName': '',
+ 'largeModelId': '',
+ 'prompt': '',
+ 'temperature': 3,
+ 'top_p': 3,
+ 'openingRemarks': '',
+ }
+ application: Application = this.defalutApplication;
+ constructor(
+ private myhttp: MaasApi,
+ private message: NzMessageService,
+ private fb: FormBuilder,
+ ) { }
+
+ ngOnInit() {
+ this.validateForm = this.fb.group({
+ name: [this.application.applicationName, [Validators.required]],
+ description: [this.application.applicationDescription],
+ });
+ this.fetchApplication();
+ }
+
+ checkForm(): void {
+ for (const i in this.validateForm.controls) {
+ this.validateForm.controls[i].markAsDirty();
+ this.validateForm.controls[i].updateValueAndValidity();
+ }
+ }
+
+ submitForm(): void {
+ this.checkForm();
+ this.create();
+ }
+
+ fetchApplication(): void {
+ this.myhttp.getApplicationById(this.applicationId)
+ .subscribe(
+ (response) => {
+ if (response.result_header.result_code !== 200) {
+ this.message.error('get application error');
+ return;
+ }
+ this.application = response.result_body;
+ this.validateForm.patchValue({
+ name: this.application.applicationName,
+ description: this.application.applicationDescription
+ });
+ },
+ () => {
+ this.message.error('Failed to obtain knowledge base data');
+ }
+ )
+ }
+
+ handleCancel(): void {
+ this.showModal = false;
+ this.modalOpreation.emit({ 'cancel': true });
+ }
+
+ create() {
+ const metaData = {
+ ...this.application,
+ applicationName: this.validateForm.get('name').value,
+ applicationDescription: this.validateForm.get('description').value,
+ };
+ this.myhttp.updateApplication(metaData).subscribe(
+ (response) => {
+ if (response.result_header.result_code === 200) {
+ this.message.success('update knowledge base successfully');
+ } else {
+ this.message.error(response.result_header.result_message);
+ }
+ this.modalOpreation.emit({ 'cancel': false });
+ },
+ (error) => {
+ console.log('Upload failed', error);
+ }
+ );
+ }
+
+}
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/create-knowledge-base/create-knowledge-base.component.ts b/usecaseui-portal/src/app/views/maas/knowledge-base-management/create-knowledge-base/create-knowledge-base.component.ts
index 891fb9bd..2757137b 100644
--- a/usecaseui-portal/src/app/views/maas/knowledge-base-management/create-knowledge-base/create-knowledge-base.component.ts
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/create-knowledge-base/create-knowledge-base.component.ts
@@ -3,7 +3,9 @@ import { Util } from '../../../../shared/utils/utils';
import { NzMessageService, UploadFile } from 'ng-zorro-antd';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
-import { MaasService } from '@src/app/core/services/maas.service';
+import { MaasApi } from '@src/app/api/maas.api';
+import { Operator } from 'rxjs';
+import { MaaSPlatform, Operators } from '../knowledge-base.type';
@Component({
selector: 'app-create-knowledge-base',
@@ -14,16 +16,13 @@ export class CreateKnowledgeBaseComponent implements OnInit {
title = 'Add Knowledge Base';
@Input() showModal: boolean;
@Output() modalOpreation = new EventEmitter();
-
- apiUrl = '/api/usecaseui-llm-adaptation/v1/knowledgeBase/create';
- maasUrl = '/api/usecaseui-llm-adaptation/v1/operator/maas/getAll'
- fileList: UploadFile[] = [];
- operators: any[] = [];
- filteredPlatforms: any[] = [];
+ fileList: File[] = [];
+ operators: Operators[] = [];
+ filteredPlatforms: MaaSPlatform[] = [];
validateForm: FormGroup;
constructor(
- private myhttp: MaasService,
+ private myhttp: MaasApi,
private Util: Util,
private message: NzMessageService,
private http: HttpClient,
@@ -40,7 +39,7 @@ export class CreateKnowledgeBaseComponent implements OnInit {
});
}
fetchOperators(): void {
- this.http.get<any>(this.maasUrl).subscribe(
+ this.myhttp.getOperators().subscribe(
(response) => {
this.operators = response.result_body;
},
@@ -55,7 +54,7 @@ export class CreateKnowledgeBaseComponent implements OnInit {
this.validateForm.controls[i].updateValueAndValidity();
}
}
- handleOperatorChange(value: any): void {
+ handleOperatorChange(value: Operators): void {
if (value) {
this.filteredPlatforms = value.maaSPlatformList;
} else {
@@ -63,7 +62,7 @@ export class CreateKnowledgeBaseComponent implements OnInit {
}
this.validateForm.get('selectedPlatform').setValue(null);
}
- beforeUpload = (file: UploadFile): boolean => {
+ beforeUpload = (file: File): boolean => {
this.fileList.push(file);
return false;
}
@@ -84,7 +83,7 @@ export class CreateKnowledgeBaseComponent implements OnInit {
};
const metaDataJson = JSON.stringify(metaData);
formData.append('metaData', metaDataJson);
- this.fileList.forEach((file: any) => {
+ this.fileList.forEach((file: File) => {
formData.append('files', file);
});
return formData
@@ -96,7 +95,7 @@ export class CreateKnowledgeBaseComponent implements OnInit {
this.showModal = true;
return;
}
- this.http.post<any>(this.apiUrl, this.constructBody()).subscribe(
+ this.myhttp.createKnowledgeBase(this.constructBody()).subscribe(
(response) => {
if (response.result_header.result_code === 200) {
this.message.success('Created successfully');
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.html b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.html
new file mode 100644
index 00000000..feee9b8f
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.html
@@ -0,0 +1,18 @@
+<nz-modal [(nzVisible)]="showModal" [nzTitle]="title" (nzOnCancel)="handleCancel()"
+ (nzOnOk)="submitForm()" nzWidth="648px" nzHeight="800px">
+ <form nz-form [formGroup]="validateForm" (ngSubmit)="checkForm()">
+ <nz-form-item>
+ <nz-form-label [nzSpan]="8" nzFor="name" nzRequired>Knowledge Base Name</nz-form-label>
+ <nz-form-control [nzSpan]="12">
+ <input nz-input formControlName="name" placeholder="Please input knowledge base name" />
+ <nz-form-explain *ngIf="validateForm.get('name').dirty && validateForm.get('name').errors">Please input knowledge base name</nz-form-explain>
+ </nz-form-control>
+ </nz-form-item>
+ <nz-form-item>
+ <nz-form-label [nzSpan]="8" nzFor="description">Knowledge Base Description</nz-form-label>
+ <nz-form-control [nzSpan]="12">
+ <textarea rows="2" formControlName="description" nz-input></textarea>
+ </nz-form-control>
+ </nz-form-item>
+ </form>
+</nz-modal> \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.less b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.less
new file mode 100644
index 00000000..a5e73a17
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.less
@@ -0,0 +1,21 @@
+.intent-management-modal {
+ .ant-input {
+ width: 300px;
+ }
+}
+
+
+.resizable-textarea {
+ min-width: 200px;
+ min-height: 80px;
+ resize: vertical;
+}
+
+.disabled-input {
+ color: #00000040;
+ background-color: #f5f5f5;
+ border-color: #d9d9d9;
+ box-shadow: none;
+ cursor: not-allowed;
+ opacity: 1;
+} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.ts b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.ts
new file mode 100644
index 00000000..3a71d800
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component.ts
@@ -0,0 +1,106 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { KnowledgeBase } from '../knowledge-base.type';
+import { MaasApi } from '@src/app/api/maas.api';
+
+@Component({
+ selector: 'app-edit-knowledge-base',
+ templateUrl: './edit-knowledge-base.component.html',
+ styleUrls: ['./edit-knowledge-base.component.less']
+})
+export class EditKnowledgeBaseComponent implements OnInit {
+ title = 'Edit Knowledge Base';
+ @Input() showModal: boolean;
+ @Input() knowledgeBaseId: string;
+ @Output() modalOpreation = new EventEmitter();
+ validateForm: FormGroup;
+ defalutKnowledgeBase: KnowledgeBase = {
+ knowledgeBaseName: '',
+ knowledgeBaseDescription: '',
+ knowledgeBaseId: '',
+ operatorName: '',
+ maaSPlatformName: '',
+ maaSPlatformId: '',
+ updateTime: '',
+ filesName: [],
+ operatorId: ''
+ }
+ knowledgeBase: KnowledgeBase = this.defalutKnowledgeBase;
+
+ constructor(
+ private myhttp: MaasApi,
+ private message: NzMessageService,
+ private fb: FormBuilder,
+ ) { }
+
+ ngOnInit() {
+ this.validateForm = this.fb.group({
+ name: [this.knowledgeBase.knowledgeBaseName, [Validators.required]],
+ description: [this.knowledgeBase.knowledgeBaseDescription],
+ });
+ this.fetchKnowledgeBase();
+ }
+
+ checkForm(): void {
+ for (const i in this.validateForm.controls) {
+ this.validateForm.controls[i].markAsDirty();
+ this.validateForm.controls[i].updateValueAndValidity();
+ }
+ }
+
+ submitForm(): void {
+ this.checkForm();
+ this.create();
+ }
+
+ fetchKnowledgeBase(): void {
+ this.myhttp.getKnowledgeBaseById(this.knowledgeBaseId)
+ .subscribe(
+ (response) => {
+ if (response.result_header.result_code !== 200) {
+ this.message.error('get Knowledge Base error');
+ return;
+ }
+ this.knowledgeBase = response.result_body;
+ this.validateForm.patchValue({
+ name: this.knowledgeBase.knowledgeBaseName,
+ description: this.knowledgeBase.knowledgeBaseDescription
+ });
+ },
+ () => {
+ this.message.error('Failed to obtain knowledge base data');
+ }
+ )
+ }
+
+ handleCancel(): void {
+ this.showModal = false;
+ this.modalOpreation.emit({ "cancel": true });
+ }
+
+ create() {
+ const body = {
+ knowledgeBaseId: this.knowledgeBase.knowledgeBaseId,
+ knowledgeBaseName: this.validateForm.get('name').value,
+ knowledgeBaseDescription: this.validateForm.get('description').value,
+ operatorId: this.knowledgeBase.operatorId,
+ operatorName: this.knowledgeBase.operatorName,
+ maaSPlatformId: this.knowledgeBase.maaSPlatformId,
+ maaSPlatformName: this.knowledgeBase.maaSPlatformName
+ };
+ this.myhttp.updateKnowledgeBase(body).subscribe(
+ (response) => {
+ if (response.result_header.result_code === 200) {
+ this.message.success('update knowledge base successfully');
+ } else {
+ this.message.error(response.result_header.result_message);
+ }
+ this.modalOpreation.emit({ "cancel": false });
+ },
+ (error) => {
+ console.log('Upload failed', error);
+ }
+ );
+ }
+} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component.ts b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component.ts
index 3bcc1455..49b9de4a 100644
--- a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component.ts
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component.ts
@@ -20,11 +20,11 @@ export class KnowledgeBaseDetailComponent implements OnInit {
handleCancel(): void {
this.showModal = false;
- this.modalOpreation.emit({ "cancel": true });
+ this.modalOpreation.emit();
}
handleOk(): void {
this.showModal = false;
- this.modalOpreation.emit({ "cancel": true });
+ this.modalOpreation.emit();
}
} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.html b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.html
index 6186ef2f..eb7c232a 100644
--- a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.html
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.html
@@ -35,8 +35,8 @@
<td>{{ data.knowledgeBaseDescription }}</td>
<td>
<i class="anticon anticon-menu-fold" (click)="displayKnowledgeDetails(data)"></i>
- <!-- <i class="anticon anticon-edit" (click)="editKnowedgeBase(data)"></i> -->
- <i class="anticon anticon-delete" (click)="deleteKnowledgeBase(data)"></i>
+ <i class="anticon anticon-edit" (click)="editKnowedgeBase(data)"></i>
+ <i class="anticon anticon-delete" (click)="showDeleteConfirm(data)"></i>
</td>
</tr>
</tbody>
@@ -45,8 +45,8 @@
<app-create-knowledge-base *ngIf="createModalShow" [showModal]="createModalShow"
(modalOpreation)="createModalClose($event)"></app-create-knowledge-base>
<app-knowledge-base-detail *ngIf="knowledgeBaseShow" [showModal]="knowledgeBaseShow"
- (modalOpreation)="knowledgeBaseDetailClose($event)"
+ (modalOpreation)="knowledgeBaseDetailClose()"
[knowledgeBaseDetail]="knowledgeBaseDetail"></app-knowledge-base-detail>
-<!-- <app-edit-knowledge-base *ngIf="editKnowledgeBaseShow" [showModal]="editKnowledgeBaseShow" [knowledgeBaseId]="knowledgeBaseId"
-(modalOpreation)="editKnowledgeBaseModuleClose($event)"></app-edit-knowledge-base> --> \ No newline at end of file
+<app-edit-knowledge-base *ngIf="editKnowledgeBaseShow" [showModal]="editKnowledgeBaseShow" [knowledgeBaseId]="knowledgeBaseId"
+(modalOpreation)="editKnowledgeBaseModuleClose($event)"></app-edit-knowledge-base> \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.ts b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.ts
index bad5808c..26b672cc 100644
--- a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.ts
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base-management.component.ts
@@ -1,7 +1,8 @@
-import { Component, OnInit } from '@angular/core';
-import { NzMessageService } from "ng-zorro-antd";
-import { MaasService } from '@src/app/core/services/maas.service';
-import { KnowledgeBase } from './knowledge-base.type';
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { NzMessageService, NzModalService } from "ng-zorro-antd";
+import { MaasApi } from '@src/app/api/maas.api';
+import { KnowledgeBase, modalClose } from './knowledge-base.type';
+import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-knowledge-base-management',
@@ -17,8 +18,10 @@ export class KnowledgeBaseManagementComponent implements OnInit {
knowledgeBaseDetail: Object = {};
constructor(
- private myhttp: MaasService,
- private message: NzMessageService
+ private myhttp: MaasApi,
+ private message: NzMessageService,
+ private modalService: NzModalService,
+ private translate: TranslateService
) { }
ngOnInit() {
@@ -40,7 +43,7 @@ export class KnowledgeBaseManagementComponent implements OnInit {
create(): void {
this.createModalShow = true;
}
- createModalClose($event: any): void {
+ createModalClose($event: modalClose): void {
this.createModalShow = false;
if ($event.cancel) {
return;
@@ -48,7 +51,7 @@ export class KnowledgeBaseManagementComponent implements OnInit {
this.getKnowledgeBaseData()
}
- editKnowledgeBaseModuleClose($event: any): void {
+ editKnowledgeBaseModuleClose($event: modalClose): void {
this.editKnowledgeBaseShow = false;
if ($event.cancel) {
return;
@@ -56,11 +59,11 @@ export class KnowledgeBaseManagementComponent implements OnInit {
this.getKnowledgeBaseData()
}
- knowledgeBaseDetailClose($event: any): void {
+ knowledgeBaseDetailClose(): void {
this.knowledgeBaseShow = false;
}
- deleteKnowledgeBase(data): void {
+ deleteKnowledgeBase(data: KnowledgeBase): void {
this.myhttp.deleteKnowledgeBaseData(data.knowledgeBaseId).subscribe((data) => {
this.getKnowledgeBaseData()
if (data.result_header.result_code === 200) {
@@ -86,9 +89,20 @@ export class KnowledgeBaseManagementComponent implements OnInit {
)
}
- editKnowedgeBase(data) {
+ editKnowedgeBase(data: KnowledgeBase) {
this.knowledgeBaseId = data.knowledgeBaseId;
this.editKnowledgeBaseShow = true;
}
+ showDeleteConfirm(data: KnowledgeBase): void {
+ this.modalService.confirm({
+ nzTitle: this.translate.instant('maas.deleteTitle'),
+ nzContent: this.translate.instant('maas.knowledgeBase.deleteKnowledgeBaseContent'),
+ nzOkText: 'Yes',
+ nzOkType: 'danger',
+ nzOnOk: () => this.deleteKnowledgeBase(data),
+ nzCancelText: 'No'
+ });
+ }
+
} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base.type.ts b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base.type.ts
index e6004ff1..b9ec432d 100644
--- a/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base.type.ts
+++ b/usecaseui-portal/src/app/views/maas/knowledge-base-management/knowledge-base.type.ts
@@ -10,11 +10,42 @@ export type KnowledgeBase = {
knowledgeBaseId: string
}
-export type KnowledgeBaseResponse = {
- result_body: KnowledgeBase,
- result_header: {
- result_code :number,
+export type KnowledgeBaseResponse = Response<KnowledgeBase>
+
+export type KnowledgeBasesResponse = Response<Array<KnowledgeBase>>
+
+export type Operators = {
+ operatorId: string,
+ operatorName: string,
+ maaSPlatformList: Array<MaaSPlatform>,
+}
+
+export type MaaSPlatform = {
+ maaSPlatformId: string,
+ maaSPlatformName: string,
+ operatorId: string,
+ operatorName: string,
+ modelList: Array<ModelInformation>;
+}
+
+export type ModelInformation = {
+ modelId: string,
+ modelName: string,
+}
+
+export type ResponseHeader = {
+ result_header:{
+ result_code: number,
result_message: string
}
}
+export type OperatorsResponse = Response<Array<Operators>>
+
+export type Response<T> = {
+ result_body: T
+} & ResponseHeader
+
+export type modalClose = {
+ cancel: boolean
+} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/maas-service.service.spec.ts b/usecaseui-portal/src/app/views/maas/maas-service.service.spec.ts
new file mode 100644
index 00000000..69f472e2
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/maas-service.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { MaasServiceService } from './maas-service.service';
+
+describe('MaasServiceService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [MaasServiceService]
+ });
+ });
+
+ it('should be created', inject([MaasServiceService], (service: MaasServiceService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/usecaseui-portal/src/app/views/maas/maas-service.service.ts b/usecaseui-portal/src/app/views/maas/maas-service.service.ts
new file mode 100644
index 00000000..257f7a1c
--- /dev/null
+++ b/usecaseui-portal/src/app/views/maas/maas-service.service.ts
@@ -0,0 +1,14 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MaasService {
+
+ constructor() { }
+
+ generateUniqueId(): string {
+ const timestamp = new Date().getTime();
+ const randomNum = Math.floor(Math.random() * 1000000);
+ return `${timestamp}${randomNum}`;
+ }
+
+}
diff --git a/usecaseui-portal/src/app/views/maas/maas.module.ts b/usecaseui-portal/src/app/views/maas/maas.module.ts
index 814cd635..8c666903 100644
--- a/usecaseui-portal/src/app/views/maas/maas.module.ts
+++ b/usecaseui-portal/src/app/views/maas/maas.module.ts
@@ -10,28 +10,34 @@ import { KnowledgeBaseManagementComponent } from './knowledge-base-management/kn
import { CreateKnowledgeBaseComponent } from './knowledge-base-management/create-knowledge-base/create-knowledge-base.component';
import { KnowledgeBaseDetailComponent } from './knowledge-base-management/knowledge-base-detail/knowledge-base-detail.component';
import { SharedModule } from '@src/app/shared/module/sharded.module';
-import { MaasService } from '@src/app/core/services/maas.service';
-// import { EditKnowledgeBaseComponent } from './knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component';
+import { MaasApi } from '@src/app/api/maas.api';
+import { EditKnowledgeBaseComponent } from './knowledge-base-management/edit-knowledge-base/edit-knowledge-base.component';
+import { EditApplicationComponent } from './build/edit-application/edit-application.component';
+import { MaasService } from './maas-service.service';
+import { KnowledgeBaseService } from './knowledge-base-management/knowledge-base.service';
@NgModule({
providers: [
- MaasService
+ MaasApi,
+ MaasService,
+ KnowledgeBaseService
],
imports: [
SharedModule,
- MaasRoutingModule,
+ MaasRoutingModule
],
declarations: [
ApplicationManagementComponent,
- CreateApplicationManagementComponent,
- UseApplicationComponent,
- ApplicationDetailComponent,
- DescriptionComponent,
- DescriptionItemComponent,
+ CreateApplicationManagementComponent,
+ UseApplicationComponent,
+ ApplicationDetailComponent,
+ DescriptionComponent,
+ DescriptionItemComponent,
KnowledgeBaseManagementComponent,
- CreateKnowledgeBaseComponent,
- KnowledgeBaseDetailComponent,
- // EditKnowledgeBaseComponent
+ CreateKnowledgeBaseComponent,
+ KnowledgeBaseDetailComponent,
+ EditKnowledgeBaseComponent,
+ EditApplicationComponent
]
})
export class MaasModule { }
diff --git a/usecaseui-portal/src/app/views/maas/use/use-application.component.html b/usecaseui-portal/src/app/views/maas/use/use-application.component.html
index 52322960..f8c65794 100644
--- a/usecaseui-portal/src/app/views/maas/use/use-application.component.html
+++ b/usecaseui-portal/src/app/views/maas/use/use-application.component.html
@@ -22,23 +22,46 @@
<div class="chat-container">
<div *ngFor="let chat of chatHistory">
<div class="question">
- <img src="assets/images/user.png">
- <span>{{ chat.question }}</span>
+ <div class="question-icon">
+ <div class="question-icon-actions">
+ <span class="anticon anticon-copy question-action" (click)="copy(chat.question)"
+ [nz-tooltip]="'maas.copy' | translate"></span>
+ <span *ngIf="chat.status==='finished'" class="anticon anticon-delete question-action" (click)="deleteQuestion(chat.questionId)"
+ [nz-tooltip]="'maas.delete' | translate"></span>
+ </div>
+ <div>
+ <img src="assets/images/user.png">
+ </div>
+ </div>
+ <div class="question-container">
+ <span class="question-text">{{ chat.question }}</span>
+ </div>
</div>
<br>
- <div class="answer">
- <img src="assets/images/answer.png">
- <span>{{ chat.answer }}</span>
+ <div>
+ <div class="answer-icon">
+ <img src="assets/images/answer.png">
+ <span class="anticon anticon-copy answer-action" (click)="copy(chat.answer)"
+ [nz-tooltip]="'maas.copy' | translate"></span>
+ </div>
+ <span class="answer-text">
+ <span class="answer" [ngClass]="{'hidden-cursor': chat.status==='finished'}" #answerText
+ id="answerText">{{chat.answer}}</span>
+ </span>
</div>
<br>
</div>
</div>
<div class="input-wrapper">
- <textarea nz-tooltip nz-input [nzAutosize]="{ minRows: 2, maxRows: 2 }" [(ngModel)]="question"
- class="text-input"></textarea>
- <i class="icon" (click)="submitQuestion()">
- <img src="assets/images/send.png">
- </i>
+ <textarea nzAutosize nz-input [(ngModel)]="question" class="text-input question-input"></textarea>
+ <div class="send-wrapper" [ngClass]="{'stop-wrapper': isGeneratingAnswer}">
+ <div class="icon" (click)="doAction()"
+ [ngClass]="{'send-disabled': !isGeneratingAnswer &&!question, 'send-enabled': question && !isGeneratingAnswer, 'stop-generating': isGeneratingAnswer}"
+ [nz-tooltip]="isGeneratingAnswer ? stopGenerating : send">
+ <img [src]="isGeneratingAnswer ? 'assets/images/stop-generating.svg' : 'assets/images/send.svg'"
+ [alt]="isGeneratingAnswer ? stopGenerating : send">
+ </div>
+ </div>
</div>
</div> \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/use/use-application.component.less b/usecaseui-portal/src/app/views/maas/use/use-application.component.less
index e4570d4f..c2f926fb 100644
--- a/usecaseui-portal/src/app/views/maas/use/use-application.component.less
+++ b/usecaseui-portal/src/app/views/maas/use/use-application.component.less
@@ -7,76 +7,147 @@
display: flex;
flex-direction: column;
}
+
.fixed-select-wrapper {
- position: fixed;
- top: 20px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 1000;
- }
+ position: fixed;
+ top: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 1000;
+}
+
.chat-container {
margin: 60px 0;
padding: 0 100px;
}
+
.question {
display: flex;
+ flex-direction: column;
+ gap: 8px;
+ display: flex;
+ align-items: flex-end;
}
-.record-input{
+
+.record-input {
margin-left: 10px;
resize: none;
}
-.question span {
- background-color: white;
- font-size: 16px;
- margin-left: 10px;
- padding: 10px;
+
+.question-icon {
+ display: flex;
+}
+
+.question-icon-actions {
+ color: #8A95A7;
+ display: flex;
border-radius: 8px;
+ overflow: hidden;
+ border: 1px solid #fff;
+ margin-right: 8px;
+ height: 24px;
+ margin-top:3px;
}
-.question img {
- width: 28px;
- height: 28px;
+
+.question-icon-actions span:not(:first-child) {
+ border-left: 1px solid #fff;
}
-.answer {
- display: flex;
+.question-action {
+ width: 24px;
+ padding-top: 4px;
}
-.answer span{
+
+.question-container {
+ margin: 8px 0;
+}
+
+.question-text {
background-color: white;
font-size: 16px;
- margin-left: 10px;
padding: 10px;
border-radius: 8px;
+}
+
+.answer-action {
+ height: 24px;
+ width: 24px;
+ border: 1px solid #fff;
+ border-radius: 8px;
+ padding-top: 3px;
+}
+
+#answerText {
+ font-size: 16px;
+ padding: 10px;
white-space: pre-line;
+ width: auto;
+ display: inline-block;
+ position: relative;
+ min-height: 40px;
+}
+
+.answer::after {
+ content: '';
+ display: inline-block;
+ width: 1px;
+ height: 16px;
+ background-color: black;
+ position: absolute;
+ animation: blink 1s step-end infinite;
+ margin-top: 5px;
}
-.answer img {
+
+.hidden-cursor::after {
+ display: none;
+}
+
+.answer-text {
+ margin: 8px 0;
+ background-color: white;
+ display: inline-block;
+ border-radius: 8px;
+}
+
+.answer-container img, .answer-icon img, .question img{
width: 28px;
height: 28px;
}
+.showing-answer {
+ display: inline-block;
+}
+
+.answer-done {
+ display: none;
+}
+
.chat-input {
- margin-top: 30px;
- padding-left: 1100px;
+ margin-top: 30px;
+ padding-left: 1100px;
}
.input-wrapper {
display: flex;
justify-content: space-around;
- width: e("calc(100% - 240px)");
margin: 0 100px;
- margin-left: 138px;
padding: 10px;
background: #fff;
border-radius: 8px;
border: 2px solid #8a2be2;
}
+.question-input {
+ width: 100%;
+}
+
.text-input {
- width: e("calc(100% - 50px)");
background-color: white;
color: black;
text-align: left;
border: 0;
resize: none;
+ padding-right: 40px;
&:focus {
border: 0 !important;
@@ -84,15 +155,68 @@
}
}
-.icon {
- width: 50px;
- height: 50px;
+.send-wrapper {
+ position: relative;
+ right: 16px;
+
+ .icon {
+ width: 32px;
+ height: 32px;
+ position: absolute;
+ // top: 50%;
+ left: 50%;
+ border-radius: 8px;
+ transform: translateX(-50%) translateY(-50%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ >img {
+ width: 20px;
+ height: 20px;
+ }
+ }
+}
+
+.stop-wrapper {
+ margin-right: 16px;
+}
+
+.send-disabled {
+ cursor: not-allowed;
+ background: rgb(229, 229, 229);
+ top: 50%;
+}
+
+.send-enabled {
+ // background: rgb(72, 127, 255);
+ background: #8a2be2;
cursor: pointer;
+ top: 50%;
+}
- >img {
- width: 35px;
- height: 31px;
- margin-top: 15px;
- margin-left: 15px;
+@keyframes zoomStopIcon {
+ 0% {
+ transform: scale(0.8);
}
+
+ 100% {
+ transform: scale(1.2);
+ }
+}
+
+.stop-generating {
+ background: rgb(229, 229, 229);
+ animation: 0.4s ease 0s infinite alternate none running zoomStopIcon;
+ cursor: pointer;
}
+
+
+@keyframes blink {
+ from, to {
+ background-color: transparent;
+ }
+ 50% {
+ background-color: black;
+ }
+} \ No newline at end of file
diff --git a/usecaseui-portal/src/app/views/maas/use/use-application.component.ts b/usecaseui-portal/src/app/views/maas/use/use-application.component.ts
index 96b17fd0..e73463d6 100644
--- a/usecaseui-portal/src/app/views/maas/use/use-application.component.ts
+++ b/usecaseui-portal/src/app/views/maas/use/use-application.component.ts
@@ -1,10 +1,12 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
-import { HttpClient } from '@angular/common/http';
import { SSE } from "sse.js";
import { ActivatedRoute } from '@angular/router';
-import { MaasService } from '@src/app/core/services/maas.service';
-
+import { MaasApi } from '@src/app/api/maas.api';
+import { TranslateService } from '@ngx-translate/core';
+import { MaasService } from '../maas-service.service';
+export type StatusEnum = 'typing' | 'finished';
+export type Chat = { question: string, answer: string, questionId: string, status: StatusEnum };
@Component({
selector: 'app-use-application',
templateUrl: './use-application.component.html',
@@ -14,17 +16,23 @@ export class UseApplicationComponent implements OnInit {
question: string;
communicationMessage: string;
- chatHistory: { question: string, answer: string }[] = [];
+ chatHistory: Chat[] = [];
apiUrl = '/api/usecaseui-llm-adaptation/v1/application/chat';
queryParams: { id?: string; name?: string } = {};
selectedName: string | null = null;
- options: any[] = [];
-
+ options: Array<{ nzValue: string, nzLabel: string }> = [];
+ send = this.translate.instant('maas.send');
+ private currentSSE: SSE | null = null;
+ isGeneratingAnswer: boolean = false;
+ stopGenerating = this.translate.instant('maas.stopGenerating');
+ questionId = '';
constructor(
- private http: HttpClient,
private message: NzMessageService,
private route: ActivatedRoute,
- private myhttp: MaasService,
+ private myhttp: MaasApi,
+ private translate: TranslateService,
+ private maasService: MaasService,
+ private renderer: Renderer2
) { }
ngOnInit() {
@@ -34,25 +42,66 @@ export class UseApplicationComponent implements OnInit {
this.selectedName = this.queryParams.id;
});
}
+
+ close() {
+ if (this.currentSSE) {
+ this.currentSSE.close();
+ }
+ }
+
+ doAction() {
+ if (this.isGeneratingAnswer) {
+ this.close();
+ this.chatHistory.forEach(item => {item.status = 'finished'});
+ this.isGeneratingAnswer = false;
+ } else {
+ this.submitQuestion();
+ }
+ }
submitQuestion() {
+ if (!this.question) {
+ return;
+ }
+ this.isGeneratingAnswer = true;
const chatParam = {
applicationId: this.selectedName,
- question: this.question
+ question: this.question,
+ questionId: this.maasService.generateUniqueId()
};
- const source = new SSE(this.apiUrl, { headers: { 'Content-Type': 'application/json' }, payload: JSON.stringify(chatParam), method: 'POST' });
- const lin = this.question;
- source.addEventListener('message', (event) => {
- const existingEntryIndex = this.chatHistory.findIndex(entry => entry.question === lin);
- if (existingEntryIndex !== -1) {
- this.chatHistory[existingEntryIndex].answer += event.data.replace(/__SPACE__/g, ' ');
- } else {
- this.chatHistory.push({ question: lin, answer: event.data });
+ this.currentSSE = new SSE(this.apiUrl, { headers: { 'Content-Type': 'application/json' }, payload: JSON.stringify(chatParam), method: 'POST' });
+ const questionId = chatParam.questionId;
+ this.chatHistory.push({ question: chatParam.question, questionId: chatParam.questionId, answer: '', status: 'typing' });
+ this.currentSSE.addEventListener('message', (event) => {
+ const chat = this.chatHistory.find(chatItem => chatItem.questionId === questionId);
+ if (chat) {
+ if (['[DONE]', 'Network Error'].includes(event.data)) {
+ chat.status = 'finished';
+ this.isGeneratingAnswer = false;
+ if (event.data === 'Network Error') {
+ this.updateAnswer(event, chat);
+ }
+ this.close();
+ } else {
+ this.updateAnswer(event, chat);
+ }
}
});
+ this.currentSSE.addEventListener('error', () => {
+ this.currentSSE = null;
+ this.isGeneratingAnswer = false;
+ });
+ this.currentSSE.addEventListener('close', () => {
+ this.currentSSE = null;
+ this.isGeneratingAnswer = false;
+ });
this.question = '';
}
+ updateAnswer(event: any, chat: Chat): void {
+ chat.answer += event.data.replace(/__SPACE__/g, ' ');
+ }
+
fetchAllApplication(): void {
this.myhttp.getAllApplication()
.subscribe(
@@ -61,10 +110,24 @@ export class UseApplicationComponent implements OnInit {
nzValue: item.applicationId,
nzLabel: item.applicationName
}));
+ this.selectedName = this.options.length > 0 ? this.options[0].nzValue : '';
},
() => {
this.message.error('Failed to obtain intent data');
}
)
}
+
+ async copy(content: string): Promise<void> {
+ try {
+ await (navigator as any).clipboard.writeText(content);
+ this.message.success(this.translate.instant('maas.copy_to_clipboard'));
+ } catch (err) {
+ console.error(this.translate.instant('maas.copy_failed') + ': ', err);
+ }
+ }
+
+ deleteQuestion(questionId: string): void {
+ this.chatHistory = this.chatHistory.filter(item => item.questionId !== questionId);
+ }
}