From 6f8694edd30c021bea991ce5a7adf85359f9a6d8 Mon Sep 17 00:00:00 2001 From: kaixiliu Date: Fri, 17 Jan 2025 17:01:17 +0800 Subject: [PATCH] Optimize your code and the Q&A assistant page has a shortcut to send questions. Issue-ID: USECASEUI-844 Change-Id: I652edab1945e3c2366fea388d6e3d8e5360d2922 Signed-off-by: kaixiliu --- .../src/app/views/maas/use/code-block.directive.ts | 51 ++++++++++++---------- .../views/maas/use/use-application.component.html | 4 +- .../views/maas/use/use-application.component.less | 1 + .../views/maas/use/use-application.component.ts | 42 ++++++++++++++++-- usecaseui-portal/src/assets/i18n/cn.json | 4 +- usecaseui-portal/src/assets/i18n/cn_maas.json | 4 +- usecaseui-portal/src/assets/i18n/en.json | 4 +- usecaseui-portal/src/assets/i18n/en_maas.json | 4 +- 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"> - + @@ -57,7 +57,7 @@
- +
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 -- 2.16.6