summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaixiliu <liukaixi@chinamobile.com>2025-01-17 17:01:17 +0800
committerkaixiliu <liukaixi@chinamobile.com>2025-01-20 11:35:33 +0800
commit6f8694edd30c021bea991ce5a7adf85359f9a6d8 (patch)
tree6ee41c9ab98a413771dd7729dce97e14137f5ece
parentd67b4b25e73bba60cc72a5c1c68e178d9ad93b3c (diff)
Optimize your code and the Q&A assistant page has a shortcut to send questions.15.0.1
Issue-ID: USECASEUI-844 Change-Id: I652edab1945e3c2366fea388d6e3d8e5360d2922 Signed-off-by: kaixiliu <liukaixi@chinamobile.com>
-rw-r--r--usecaseui-portal/src/app/views/maas/use/code-block.directive.ts51
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.html4
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.less1
-rw-r--r--usecaseui-portal/src/app/views/maas/use/use-application.component.ts42
-rw-r--r--usecaseui-portal/src/assets/i18n/cn.json4
-rw-r--r--usecaseui-portal/src/assets/i18n/cn_maas.json4
-rw-r--r--usecaseui-portal/src/assets/i18n/en.json4
-rw-r--r--usecaseui-portal/src/assets/i18n/en_maas.json4
8 files changed, 81 insertions, 33 deletions
diff --git a/usecaseui-portal/src/app/views/maas/use/code-block.directive.ts b/usecaseui-portal/src/app/views/maas/use/code-block.directive.ts
index 31247184..08efe92c 100644
--- a/usecaseui-portal/src/app/views/maas/use/code-block.directive.ts
+++ b/usecaseui-portal/src/app/views/maas/use/code-block.directive.ts
@@ -1,4 +1,4 @@
-import { AfterViewChecked, AfterViewInit, Directive, ElementRef, Renderer2 } from '@angular/core';
+import { Directive, ElementRef, Renderer2, Input } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { NzMessageService } from 'ng-zorro-antd';
import { ClipboardService } from 'ngx-clipboard';
@@ -6,33 +6,36 @@ import { ClipboardService } from 'ngx-clipboard';
@Directive({
selector: '[appCodeBlock]'
})
-export class CodeBlockDirective implements AfterViewChecked {
+export class CodeBlockDirective {
+ @Input() set appCodeBlock(status: string) {
+ if (status === 'finished') {
+ setTimeout(() => {
+ this.setCopyButton();
+ }, 0);
+
+ }
+ }
constructor(private el: ElementRef, private renderer: Renderer2, private clipboardService: ClipboardService,
private message: NzMessageService, private translate: TranslateService
) { }
- ngAfterViewChecked() {
- this.setCopyButton();
- }
-
-setCopyButton() {
- const preElements = this.el.nativeElement.querySelectorAll('pre');
-
- preElements.forEach(pre => {
- const codeElement = pre.querySelector('code');
- const copyButtonExists = pre.querySelector('button.copy-button');
- if (codeElement && !copyButtonExists) {
- const copyButton = this.renderer.createElement('button');
- this.renderer.addClass(copyButton, 'copy-button');
- this.renderer.setProperty(copyButton, 'innerHTML', 'Copy');
- this.renderer.listen(copyButton, 'click', () => {
- this.clipboardService.copyFromContent(codeElement.innerText);
- this.message.success(this.translate.instant('maas.copy_to_clipboard'));
- });
- this.renderer.insertBefore(pre, copyButton, codeElement);
- }
- });
-}
+ setCopyButton() {
+ const preElements = this.el.nativeElement.querySelectorAll('pre');
+ preElements.forEach(pre => {
+ const codeElement = pre.querySelector('code');
+ const copyButtonExists = pre.querySelector('button.copy-button');
+ if (codeElement && !copyButtonExists) {
+ const copyButton = this.renderer.createElement('button');
+ this.renderer.addClass(copyButton, 'copy-button');
+ this.renderer.setProperty(copyButton, 'innerHTML', 'Copy');
+ this.renderer.listen(copyButton, 'click', () => {
+ this.clipboardService.copyFromContent(codeElement.innerText);
+ this.message.success(this.translate.instant('maas.copy_to_clipboard'));
+ });
+ this.renderer.insertBefore(pre, copyButton, codeElement);
+ }
+ });
+ }
}
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 6509fbbe..25c39f7b 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
@@ -45,7 +45,7 @@
[nz-tooltip]="'maas.copy' | translate"></span>
</div>
<span class="answer-text">
- <markdown appCodeBlock class="markdown answer-markdown" [ngClass]="{'hidden-cursor': chat.status==='finished'}" *ngIf="chat.answer else default" [data]="chat.answer"></markdown>
+ <markdown appCodeBlock="{{chat.status}}" class="markdown answer-markdown" [ngClass]="{'hidden-cursor': chat.status==='finished'}" *ngIf="chat.answer else default" [data]="chat.answer"></markdown>
<ng-template #default>
<span class="answer default" [ngClass]="{'hidden-cursor': chat.status==='finished'}" #answerText>
</span>
@@ -57,7 +57,7 @@
</div>
<div class="input-wrapper">
- <textarea nzAutosize nz-input [(ngModel)]="question" class="text-input question-input"></textarea>
+ <textarea #questionInput nzAutosize nz-input [(ngModel)]="question" class="text-input question-input" placeholder="{{'maas.questionPlaceholder' | translate}}" nzSize="small"></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}"
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 bb2e0d12..d57a6900 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
@@ -105,6 +105,7 @@
}
.answer-text {
+ max-width: 100%;
margin: 8px 0;
background-color: white;
display: inline-block;
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 b02a2d60..f0ce4f7e 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,4 +1,4 @@
-import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
+import { Component, ElementRef, OnInit, Renderer2, ViewChild, OnDestroy } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { SSE } from "sse.js";
import { ActivatedRoute } from '@angular/router';
@@ -12,7 +12,7 @@ export type Chat = { question: string, answer: string, questionId: string, statu
templateUrl: './use-application.component.html',
styleUrls: ['./use-application.component.less']
})
-export class UseApplicationComponent implements OnInit {
+export class UseApplicationComponent implements OnInit, OnDestroy {
question: string;
communicationMessage: string;
chatHistory: Chat[] = [];
@@ -25,12 +25,16 @@ export class UseApplicationComponent implements OnInit {
isGeneratingAnswer: boolean = false;
stopGenerating = this.translate.instant('maas.stopGenerating');
questionId = '';
+ @ViewChild('questionInput') questionInput: ElementRef;
+ private keydownListener: () => void;
+ perHight = 21;
constructor(
private message: NzMessageService,
private route: ActivatedRoute,
private myhttp: MaasApi,
private translate: TranslateService,
- private maasService: MaasService
+ private maasService: MaasService,
+ private renderer: Renderer2
) { }
async ngOnInit() {
@@ -39,8 +43,15 @@ export class UseApplicationComponent implements OnInit {
this.queryParams = params;
this.selectedName = this.queryParams.id || this.selectedName;
});
+ this.keydownListener = this.renderer.listen(this.questionInput.nativeElement, 'keydown', this.handleKeyDown.bind(this));
}
+ ngOnDestroy() {
+ if (this.keydownListener) {
+ this.keydownListener();
+ }
+ }
+
close() {
if (this.currentSSE) {
this.currentSSE.close();
@@ -125,4 +136,29 @@ export class UseApplicationComponent implements OnInit {
deleteQuestion(questionId: string): void {
this.chatHistory = this.chatHistory.filter(item => item.questionId !== questionId);
}
+
+ handleKeyDown(event: KeyboardEvent) {
+ if (event.key === 'Enter') {
+ if (event.shiftKey || event.ctrlKey || event.altKey) {
+ const TextareaDom = this.questionInput.nativeElement;
+ const height = parseInt(TextareaDom.style.height.split('px')[0], 10) + this.perHight;
+ TextareaDom.style.height = `${height}px`;
+ if(event.ctrlKey || event.altKey) {
+ const index = TextareaDom.selectionStart;
+ const val = TextareaDom.value;
+ TextareaDom.value = `${val.slice(0, index)}\n${val.slice(index)}`;
+ TextareaDom.selectionStart = index + 1;
+ TextareaDom.selectionEnd = index + 1;
+ }
+ } else {
+ event.preventDefault();
+ if (this.isGeneratingAnswer) {
+ this.message.warning(this.translate.instant('maas.is_chatting'));
+ } else {
+ this.doAction();
+ }
+
+ }
+ }
+ }
}
diff --git a/usecaseui-portal/src/assets/i18n/cn.json b/usecaseui-portal/src/assets/i18n/cn.json
index 883439bd..2c5567a3 100644
--- a/usecaseui-portal/src/assets/i18n/cn.json
+++ b/usecaseui-portal/src/assets/i18n/cn.json
@@ -199,6 +199,8 @@
"application": {
"deleteApplicationContent": "确认删除该应用?删除后数据无法恢复,请确认!",
"promptTip": "提示词需要大于20个字符"
- }
+ },
+ "questionPlaceholder": "输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]",
+ "is_chatting": "正在聊天中...请等待结束"
}
} \ No newline at end of file
diff --git a/usecaseui-portal/src/assets/i18n/cn_maas.json b/usecaseui-portal/src/assets/i18n/cn_maas.json
index a6fcab57..7aa4981a 100644
--- a/usecaseui-portal/src/assets/i18n/cn_maas.json
+++ b/usecaseui-portal/src/assets/i18n/cn_maas.json
@@ -17,7 +17,9 @@
"application": {
"deleteApplicationContent": "确认删除该应用?删除后数据无法恢复,请确认!",
"promptTip": "提示词需要大于20个字符"
- }
+ },
+ "questionPlaceholder" : "输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]",
+ "is_chatting": "正在聊天中...请等待结束"
}
} \ No newline at end of file
diff --git a/usecaseui-portal/src/assets/i18n/en.json b/usecaseui-portal/src/assets/i18n/en.json
index f68588fc..7e2f55ab 100644
--- a/usecaseui-portal/src/assets/i18n/en.json
+++ b/usecaseui-portal/src/assets/i18n/en.json
@@ -199,6 +199,8 @@
"application": {
"deleteApplicationContent": "Confirm deletion of this application? Data cannot be recovered after deletion, please confirm!",
"promptTip": "The prompt needs to be larger than 20 characters."
- }
+ },
+ "questionPlaceholder": "Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line",
+ "is_chatting": "Chatting in progress... please wait until it finishes"
}
} \ No newline at end of file
diff --git a/usecaseui-portal/src/assets/i18n/en_maas.json b/usecaseui-portal/src/assets/i18n/en_maas.json
index a53c56be..ed85771c 100644
--- a/usecaseui-portal/src/assets/i18n/en_maas.json
+++ b/usecaseui-portal/src/assets/i18n/en_maas.json
@@ -17,6 +17,8 @@
"application": {
"deleteApplicationContent": "Confirm deletion of this application? Data cannot be recovered after deletion, please confirm!",
"promptTip": "The prompt needs to be larger than 20 characters."
- }
+ },
+ "questionPlaceholder" : "Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line",
+ "is_chatting": "Chatting in progress... please wait until it finishes"
}
} \ No newline at end of file