-
Notifications
You must be signed in to change notification settings - Fork 2.8k
perf: User input interaction style optimization #2565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,56 +1,76 @@ | ||
| <template> | ||
| <div ref="aiChatRef" class="ai-chat" :class="type"> | ||
| <UserForm | ||
| v-model:api_form_data="api_form_data" | ||
| v-model:form_data="form_data" | ||
| :application="applicationDetails" | ||
| :type="type" | ||
| ref="userFormRef" | ||
| ></UserForm> | ||
| <el-scrollbar ref="scrollDiv" @scroll="handleScrollTop"> | ||
| <div ref="dialogScrollbar" class="ai-chat__content p-24"> | ||
| <PrologueContent | ||
| :type="type" | ||
| :application="applicationDetails" | ||
| :available="available" | ||
| :send-message="sendMessage" | ||
| ></PrologueContent> | ||
|
|
||
| <template v-for="(item, index) in chatList" :key="index"> | ||
| <!-- 问题 --> | ||
| <QuestionContent | ||
| <div | ||
| v-show="(isUserInput && firsUserInput) || showUserInput" | ||
| :class="firsUserInput ? 'firstUserInput' : 'popperUserInput'" | ||
| > | ||
| <UserForm | ||
| v-model:api_form_data="api_form_data" | ||
| v-model:form_data="form_data" | ||
| :application="applicationDetails" | ||
| :type="type" | ||
| :first="firsUserInput" | ||
| @confirm="UserFormConfirm" | ||
| @cancel="() => (showUserInput = false)" | ||
| ref="userFormRef" | ||
| ></UserForm> | ||
| </div> | ||
| <template v-if="!firsUserInput"> | ||
| <el-scrollbar ref="scrollDiv" @scroll="handleScrollTop"> | ||
| <div ref="dialogScrollbar" class="ai-chat__content p-24"> | ||
| <PrologueContent | ||
| :type="type" | ||
| :application="applicationDetails" | ||
| :chat-record="item" | ||
| ></QuestionContent> | ||
| <!-- 回答 --> | ||
| <AnswerContent | ||
| :application="applicationDetails" | ||
| :loading="loading" | ||
| v-model:chat-record="chatList[index]" | ||
| :type="type" | ||
| :available="available" | ||
| :send-message="sendMessage" | ||
| :chat-management="ChatManagement" | ||
| ></AnswerContent> | ||
| ></PrologueContent> | ||
|
|
||
| <template v-for="(item, index) in chatList" :key="index"> | ||
| <!-- 问题 --> | ||
| <QuestionContent | ||
| :type="type" | ||
| :application="applicationDetails" | ||
| :chat-record="item" | ||
| ></QuestionContent> | ||
| <!-- 回答 --> | ||
| <AnswerContent | ||
| :application="applicationDetails" | ||
| :loading="loading" | ||
| v-model:chat-record="chatList[index]" | ||
| :type="type" | ||
| :send-message="sendMessage" | ||
| :chat-management="ChatManagement" | ||
| ></AnswerContent> | ||
| </template> | ||
| </div> | ||
| </el-scrollbar> | ||
|
|
||
| <ChatInputOperate | ||
| :app-id="appId" | ||
| :application-details="applicationDetails" | ||
| :is-mobile="isMobile" | ||
| :type="type" | ||
| :send-message="sendMessage" | ||
| :open-chat-id="openChatId" | ||
| :chat-management="ChatManagement" | ||
| v-model:chat-id="chartOpenId" | ||
| v-model:loading="loading" | ||
| v-if="type !== 'log'" | ||
| > | ||
| <template #operateBefore> | ||
| <div class="flex-between"> | ||
| <slot name="operateBefore"> | ||
| <span></span> | ||
| </slot> | ||
| <el-button class="user-input-button mb-8" type="primary" text @click="toggleUserInput"> | ||
| <AppIcon iconName="app-user-input"></AppIcon> | ||
| </el-button> | ||
| </div> | ||
| </template> | ||
| </div> | ||
| </el-scrollbar> | ||
| </ChatInputOperate> | ||
|
|
||
| <ChatInputOperate | ||
| :app-id="appId" | ||
| :application-details="applicationDetails" | ||
| :is-mobile="isMobile" | ||
| :type="type" | ||
| :send-message="sendMessage" | ||
| :open-chat-id="openChatId" | ||
| :chat-management="ChatManagement" | ||
| v-model:chat-id="chartOpenId" | ||
| v-model:loading="loading" | ||
| v-if="type !== 'log'" | ||
| > | ||
| <template #operateBefore> <slot name="operateBefore" /> </template> | ||
| </ChatInputOperate> | ||
| <Control></Control> | ||
| <Control></Control> | ||
| </template> | ||
| </div> | ||
| </template> | ||
| <script setup lang="ts"> | ||
|
|
@@ -62,7 +82,7 @@ import { ChatManagement, type chatType } from '@/api/type/application' | |
| import { randomId } from '@/utils/utils' | ||
| import useStore from '@/stores' | ||
| import { isWorkFlow } from '@/utils/application' | ||
| import { debounce } from 'lodash' | ||
| import { debounce, first } from 'lodash' | ||
| import AnswerContent from '@/components/ai-chat/component/answer-content/index.vue' | ||
| import QuestionContent from '@/components/ai-chat/component/question-content/index.vue' | ||
| import ChatInputOperate from '@/components/ai-chat/component/chat-input-operate/index.vue' | ||
|
|
@@ -106,13 +126,25 @@ const chatList = ref<any[]>([]) | |
| const form_data = ref<any>({}) | ||
| const api_form_data = ref<any>({}) | ||
| const userFormRef = ref<InstanceType<typeof UserForm>>() | ||
| // 用户输入 | ||
| const firsUserInput = ref(true) | ||
| const showUserInput = ref(false) | ||
|
|
||
| const isUserInput = computed( | ||
| () => | ||
| props.applicationDetails.work_flow?.nodes?.filter((v: any) => v.id === 'base-node')[0] | ||
| .properties.user_input_field_list.length > 0 | ||
| ) | ||
|
|
||
| watch( | ||
| () => props.chatId, | ||
| (val) => { | ||
| if (val && val !== 'new') { | ||
| chartOpenId.value = val | ||
| firsUserInput.value = false | ||
| } else { | ||
| chartOpenId.value = '' | ||
| firsUserInput.value = true | ||
| } | ||
| }, | ||
| { deep: true } | ||
|
|
@@ -136,6 +168,15 @@ watch( | |
| } | ||
| ) | ||
|
|
||
| const toggleUserInput = () => { | ||
| showUserInput.value = !showUserInput.value | ||
| } | ||
|
|
||
| function UserFormConfirm() { | ||
| firsUserInput.value = false | ||
| showUserInput.value = false | ||
| } | ||
|
|
||
| function sendMessage(val: string, other_params_data?: any, chat?: chatType) { | ||
| if (!userFormRef.value?.checkInputParam()) { | ||
| return | ||
|
|
@@ -467,4 +508,18 @@ defineExpose({ | |
| </script> | ||
| <style lang="scss" scoped> | ||
| @import './index.scss'; | ||
| .firstUserInput { | ||
| height: 100%; | ||
| display: flex; | ||
| justify-content: center; | ||
| align-items: center; | ||
| } | ||
| .popperUserInput { | ||
| position: absolute; | ||
| z-index: 999; | ||
| right: 50px; | ||
| bottom: 80px; | ||
| width: calc(100% - 50px); | ||
| max-width: 400px; | ||
| } | ||
| </style> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code you provided contains some improvements and optimizations over its initial version. Here's an overview of the changes:
Potential Improvements:While these refinements enhance both usability and maintainability, there might be areas for further improvement depending on specific requirements such as performance tuning or additional functionality. For instance:
Overall, this refactored codebase is well-structured and ready for enhancements based on further development needs or feedback. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1394,5 +1394,26 @@ export const iconMap: any = { | |
| ) | ||
| ]) | ||
| } | ||
| }, | ||
| 'app-user-input': { | ||
| iconReader: () => { | ||
| return h('i', [ | ||
| h( | ||
| 'svg', | ||
| { | ||
| style: { height: '100%', width: '100%' }, | ||
| viewBox: '0 0 1024 1024', | ||
| version: '1.1', | ||
| xmlns: 'http://www.w3.org/2000/svg' | ||
| }, | ||
| [ | ||
| h('path', { | ||
| d: 'M85.333333 234.666667a149.333333 149.333333 0 0 1 292.48-42.666667H917.333333a21.333333 21.333333 0 0 1 21.333334 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333334 21.333333H377.813333A149.418667 149.418667 0 0 1 85.333333 234.666667z m21.333334 320a21.333333 21.333333 0 0 1-21.333334-21.333334v-42.666666a21.333333 21.333333 0 0 1 21.333334-21.333334h262.186666a149.418667 149.418667 0 0 1 286.293334 0H917.333333a21.333333 21.333333 0 0 1 21.333334 21.333334v42.666666a21.333333 21.333333 0 0 1-21.333334 21.333334h-262.186666a149.418667 149.418667 0 0 1-286.293334 0H106.666667z m405.333333 21.333333a64 64 0 1 0 0-128 64 64 0 0 0 0 128z m-405.333333 256A21.333333 21.333333 0 0 1 85.333333 810.666667v-42.666667a21.333333 21.333333 0 0 1 21.333334-21.333333h539.52a149.418667 149.418667 0 0 1 292.48 42.666666 149.333333 149.333333 0 0 1-292.48 42.666667H106.666667z m682.666666-106.666667a64 64 0 1 0 0 128 64 64 0 0 0 0-128zM234.666667 298.666667a64 64 0 1 0 0-128 64 64 0 0 0 0 128z', | ||
| fill: 'currentColor' | ||
| }) | ||
| ] | ||
| ) | ||
| ]) | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There seem to be no errors in this code snippet. The |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The provided code snippet seems to be a template file for an El-Cli application using Vue.js and Element Plus. Here are some points to consider regarding irregularities, potential issues, and optimization suggestions:
Irregularities
styleattribute has bothmax-widthset but no corresponding CSS rules applying it. This might result in unexpected behavior.Potential Issues
Uninitialized Variables:
dynamicsForm_refresh,inputFieldList,api_inputFieldList,inputFieldConfig,showUserInputmean based solely on this code.Code Duplication:
startChat,cancel) in two places within the card's footer.Function Handling:
checkInputParam()function exists and is called conditionally, its logic isn't shown. Ensure that this function correctly checks input conditions before proceeding with confirmation/abort actions.Missing Event Handlers:
emits at the bottom of the component script.Template Logic Flaws:
showUserInputseems unnecessary since the initial value (true) implies it should always be visible unless explicitly toggled elsewhere in the lifecycle hooks/functions.Dynamic Form Behavior:
handleInputFieldListsuggests dynamic loading of form fields, yet there’s limited context about how this works or the purpose ofdynamicFormRefresh.Optimization Suggestions
Separation Concerns: Try separating styles and scripts from the HTML templating. Currently everything is mixed together, which can lead to bloated templates.
Consistent Button Text Usage: If
startChat&confirmbuttons appear multiple times without any significant difference between them, consolidate these into one with conditional labels like:<el-button>{{ first ? $t('chat.operation.startChat') : $t('common.confirm') }}</el-button>.Refactor Code Organization: Consider organizing related variables/functions more clearly so that each part can have a specific and descriptive responsibility.
Here is improved version reflecting above considerations:
Ensure further adjustments according to project standards and actual requirements.