Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ def reset_field(self, field):
reset_field = ['field', 'label', 'default_value']
for f in reset_field:
_value = field[f]
if _value is None:
continue
if isinstance(_value, str):
field[f] = self.workflow_manage.generate_prompt(_value)
else:
elif f == 'label':
_label_value = _value.get('label')
_value['label'] = self.workflow_manage.generate_prompt(_label_value)
tooltip = _value.get('attrs').get('tooltip')
Expand Down
126 changes: 98 additions & 28 deletions ui/src/components/ai-chat/index.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,92 @@
<template>
<div ref="aiChatRef" class="ai-chat" :class="type" :style="{
height: firsUserInput ? '100%' : undefined,
paddingBottom: applicationDetails.disclaimer ? '20px' : 0,
}">
<div v-show="showUserInputContent" :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="UserFormCancel" ref="userFormRef">
<div
ref="aiChatRef"
class="ai-chat"
:class="type"
:style="{
height: firsUserInput ? '100%' : undefined,
paddingBottom: applicationDetails.disclaimer ? '20px' : 0,
}"
>
<div
v-show="showUserInputContent"
: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="UserFormCancel"
ref="userFormRef"
>
</UserForm>
</div>
<template v-if="!(isUserInput || isAPIInput) || !firsUserInput || type === 'log'">
<el-scrollbar ref="scrollDiv" @scroll="handleScrollTop">
<div ref="dialogScrollbar" class="ai-chat__content p-16">
<PrologueContent :type="type" :application="applicationDetails" :available="available"
:send-message="sendMessage"></PrologueContent>
<PrologueContent
:type="type"
:application="applicationDetails"
:available="available"
:send-message="sendMessage"
></PrologueContent>

<template v-for="(item, index) in chatList" :key="index">
<!-- 问题 -->
<QuestionContent :type="type" :application="applicationDetails" :chat-record="item"></QuestionContent>
<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
:application="applicationDetails"
:loading="loading"
v-model:chat-record="chatList[index]"
:type="type"
:send-message="sendMessage"
:chat-management="ChatManagement"
:executionIsRightPanel="props.executionIsRightPanel"
@open-execution-detail="emit('openExecutionDetail', chatList[index])"
@openParagraph="emit('openParagraph', chatList[index])"
@openParagraphDocument="
(val: any) => emit('openParagraphDocument', chatList[index], val)
"></AnswerContent>
"
></AnswerContent>
</template>
<TransitionContent v-if="transcribing" :text="t('chat.transcribing')" :type="type"
:application="applicationDetails">
<TransitionContent
v-if="transcribing"
:text="t('chat.transcribing')"
:type="type"
:application="applicationDetails"
>
</TransitionContent>
</div>
</el-scrollbar>

<ChatInputOperate :app-id="appId" :application-details="applicationDetails" :is-mobile="isMobile" :type="type"
:send-message="sendMessage" :open-chat-id="openChatId" :validate="validate" :chat-management="ChatManagement"
v-model:chat-id="chartOpenId" v-model:loading="loading" v-model:show-user-input="showUserInput"
v-if="type !== 'log'">
<ChatInputOperate
:app-id="appId"
:application-details="applicationDetails"
:is-mobile="isMobile"
:type="type"
:send-message="sendMessage"
:open-chat-id="openChatId"
:validate="validate"
:chat-management="ChatManagement"
v-model:chat-id="chartOpenId"
v-model:loading="loading"
v-model:show-user-input="showUserInput"
v-if="type !== 'log'"
>
<template #userInput>
<el-button v-if="isUserInput || isAPIInput" class="user-input-button mb-8" @click="toggleUserInput">
<el-button
v-if="isUserInput || isAPIInput"
class="user-input-button mb-8"
@click="toggleUserInput"
>
<AppIcon iconName="app-edit" :size="16" class="mr-4"></AppIcon>
<span class="ellipsis">
{{ userInputTitle || $t('chat.userInput') }}
Expand All @@ -52,11 +100,21 @@
</div>
</template>
<script setup lang="ts">
import { type Ref, ref, nextTick, computed, watch, reactive, onMounted, onBeforeUnmount } from 'vue'
import {
type Ref,
ref,
nextTick,
computed,
watch,
reactive,
onMounted,
onBeforeUnmount,
provide,
} from 'vue'
import { useRoute } from 'vue-router'
import applicationApi from '@/api/application/application'
import chatAPI from '@/api/chat/chat'
import SystemResourceManagementApplicationAPI from "@/api/system-resource-management/application.ts"
import SystemResourceManagementApplicationAPI from '@/api/system-resource-management/application.ts'
import syetrmResourceManagementChatLogApi from '@/api/system-resource-management/chat-log'
import chatLogApi from '@/api/application/chat-log'
import { ChatManagement, type chatType } from '@/api/type/application'
Expand All @@ -72,6 +130,11 @@ import UserForm from '@/components/ai-chat/component/user-form/index.vue'
import Control from '@/components/ai-chat/component/control/index.vue'
import { t } from '@/locales'
import bus from '@/bus'
provide('upload', (file: any, loading?: Ref<boolean>) => {
return props.type === 'debug-ai-chat'
? applicationApi.postUploadFile(file, 'TEMPORARY_120_MINUTE', 'TEMPORARY_120_MINUTE', loading)
: chatAPI.postUploadFile(file, chartOpenId.value, 'CHAT', loading)
})
const transcribing = ref<boolean>(false)
defineOptions({ name: 'AiChat' })
const route = useRoute()
Expand Down Expand Up @@ -301,17 +364,25 @@ const getChatRecordDetailsAPI = (row: any) => {
if (row.record_id) {
if (props.type === 'debug-ai-chat') {
if (route.path.includes('resource-management')) {
return syetrmResourceManagementChatLogApi
.getChatRecordDetails(id || props.appId, row.chat_id, row.record_id, loading)
return syetrmResourceManagementChatLogApi.getChatRecordDetails(
id || props.appId,
row.chat_id,
row.record_id,
loading,
)
} else {
return chatLogApi
.getChatRecordDetails(id || props.appId, row.chat_id, row.record_id, loading)
return chatLogApi.getChatRecordDetails(
id || props.appId,
row.chat_id,
row.record_id,
loading,
)
}
} else {
return chatAPI.getChatRecord(row.chat_id, row.record_id, loading)
}
}
return Promise.reject("404")
return Promise.reject('404')
}
/**
* 获取对话详情
Expand All @@ -326,7 +397,6 @@ function getSourceDetail(row: any) {
}
})
})

}
/**
* 对话
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several issues and optimizations that can be made to the provided code:

Issues:

  1. Duplicate Code: Some components like PrologueContent have duplicate content across different sections of the component.
  2. Redundant Watchers: Using watch() for simple computations can lead to performance issues. Consider using computed properties instead.
  3. Inconsistent Template Syntax: There are multiple inconsistent syntaxes used for <template> elements, which might cause render issues.

Optimizations:

  1. Combine Similar Components:

    • If PrologueContent, QuestionContent, and AnswerContent share common props, combine them into a single reusable component.
  2. Use Computed Properties:

    • Replace simple watches with computed properties where possible to improve performance.
  3. Consistent Template Syntax:

    • Ensure consistent use of double quotes ("") for string literals to avoid potential bugs.
  4. Simplify Imports:

    • Combine imports when they belong together to reduce clutter.

Here's an optimized version of the code considering these points:

<template>
  <div ref="aiChatRef" :class="type" :style="{ height: firsUserInput ? '100%' : undefined }">
    <div v-show="showUserInputContent && !(isUserInput || isAPIInput)" :class="firsUserInput ? 'firstUserInput' : 'popperUserInput'" style="padding-top: 20px;">
      <UserForm v-model:api_form_data="api_form_data" v-model:form_data="form_data" :application="applicationDetails" :type="type" :first="firsUserInput" @confirm="UserFormConfirm" @cancel="UserFormCancel" />
    </div>

    <el-scrollbar ref="scrollDiv" @scroll="handleScrollTop">
      <div ref="dialogScrollbar" class="ai-chat__content p-16">
        <CommonComponent :type="type" :application="applicationDetails" :chat-data="getSortedChatData()" />
      </div>
    </el-scrollbar>

    <ChatInputOperate
      :app-id="appId"
      :application-details="applicationDetails"
      :is-mobile="isMobile"
      :type="type"
      :send-message="sendMessage"
      :open-chat-id="openChatId"
      :validate="validate"
      :chat-management="ChatManagement"
      v-model:chat-id="chartOpenId"
      v-model:loading="loading"
      v-model:show-user-input="showUserInput"
      v-if="type !== 'log'"
    />

    <Control />
</template>
<script setup lang="ts">
import { ref, nextTick, computed, onMounted, onBeforeUnmount, provide } from 'vue';
import { useRoute } from 'vue-router';
import applicationApi from '@/api/application/application';
import chatAPI from '@/api/chat/chat.js';
import ApplicationManagementApplicationAPI from "@/api/system-resource-management/application.ts";
import systemResourceManagementChatLogApi from '@/api/system-resource-management/chat-log';
import chatLogApi from '@/api/application/chat-log';

// Define constants and context providers
export const CommonContextProvider = {};
export const ContextKey = {};

provide(CommonContextProvider.Key, ContextKey);

// Provide custom upload function for debugging AI chat only
provide('upload', (file: any) => {
  return props.type === 'debug-ai-chat'
    ? applicationApi.postUploadFile(file, 'TEMPORARY_120_MINUTE', 'TEMPORARY_120_MINUTE')
    : chatAPI.postUploadFile(file, chartOpenId.value, 'CHAT');
});

const transcribing = ref(false);

defineOptions({ name: 'AiChat' });
const route = useRoute();

// State management
const api_form_data = ref<any>({});
const form_data = ref<any>({});
const showUserInput = ref(true);
const firsUserInput = ref<boolean>(true); // Initial value needs clarification
const openChatId = ref<string | null>(null);
const isLoading = ref<boolean>(false);

// Methods
async function sendMessage(message: string) {
  console.log('Sending message:', message);
}

function getSourceDetail(row: Record<string, any>) {
  // ...
}

// Other methods...

// Combining similar components into one here
function getSortedChatData() {
  // Sort and map chat data as needed
}

onMounted(() => {
  // Mount logic...
});
onBeforeUnmount(() => {
  // Cleanup logic...
});
</script>

This example combines PrologueContent, QuestionContent, and AnswerContent into a shared CommonComponent. It also uses a new context provider for managing components and simplifies some imports. This should improve the maintainability and readability of your codebase while addressing identified issues.

Expand Down
30 changes: 19 additions & 11 deletions ui/src/components/dynamics-form/constructor/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,51 @@ import { t } from '@/locales'
const input_type_list = [
{
label: t('dynamicsForm.input_type_list.TextInput'),
value: 'TextInput'
value: 'TextInput',
},
{
label: t('dynamicsForm.input_type_list.PasswordInput'),
value: 'PasswordInput'
value: 'PasswordInput',
},
{
label: t('dynamicsForm.input_type_list.Slider'),
value: 'Slider'
value: 'Slider',
},
{
label: t('dynamicsForm.input_type_list.SwitchInput'),
value: 'SwitchInput'
value: 'SwitchInput',
},
{
label: t('dynamicsForm.input_type_list.SingleSelect'),
value: 'SingleSelect'
value: 'SingleSelect',
},
{
label: t('dynamicsForm.input_type_list.MultiSelect'),
value: 'MultiSelect'
value: 'MultiSelect',
},
{
label: t('dynamicsForm.input_type_list.DatePicker'),
value: 'DatePicker'
value: 'DatePicker',
},
{
label: t('dynamicsForm.input_type_list.JsonInput'),
value: 'JsonInput'
value: 'JsonInput',
},
{
label: t('dynamicsForm.input_type_list.RadioCard'),
value: 'RadioCard'
value: 'RadioCard',
},
{
label: t('dynamicsForm.input_type_list.RadioRow'),
value: 'RadioRow'
}
value: 'RadioRow',
},
{
label: t('dynamicsForm.input_type_list.UploadInput'),
value: 'UploadInput',
},
{
label: t('dynamicsForm.input_type_list.TextareaInput'),
value: 'TextareaInput',
},
]
export { input_type_list }
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,32 @@

<el-row style="width: 100%" :gutter="10">
<el-radio-group v-model="formValue.assignment_method">
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list">{{
item.label
}}</el-radio>
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
>{{ item.label }}
<el-popover
width="300px"
v-if="item.value == 'ref_variables'"
class="box-item"
placement="top-start"
>
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
[<br />
{<br />
"label": "xx",<br />
"value": "xx",<br />
"default": false<br />
}<br />
]<br />
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
{{ $t('common.required') }}<br />
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
{{ $t('common.required') }}<br />
default: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
<template #reference>
<el-icon><InfoFilled /></el-icon>
</template>
</el-popover>
</el-radio>
</el-radio-group>
</el-row>
</el-form-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,32 @@

<el-row style="width: 100%" :gutter="10">
<el-radio-group v-model="formValue.assignment_method">
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list">{{
item.label
}}</el-radio>
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
>{{ item.label }}
<el-popover
width="300px"
v-if="item.value == 'ref_variables'"
class="box-item"
placement="top-start"
>
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
[<br />
{<br />
"label": "xx",<br />
"value": "xx",<br />
"default": false<br />
}<br />
]<br />
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
{{ $t('common.required') }}<br />
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
{{ $t('common.required') }}<br />
default:{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
<template #reference>
<el-icon><InfoFilled /></el-icon>
</template>
</el-popover>
</el-radio>
</el-radio-group>
</el-row>
</el-form-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,31 @@

<el-row style="width: 100%" :gutter="10">
<el-radio-group v-model="formValue.assignment_method">
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list">{{
item.label
}}</el-radio>
<el-radio :value="item.value" size="large" v-for="item in assignment_method_option_list"
>{{ item.label }}
<el-popover
width="300px"
v-if="item.value == 'ref_variables'"
class="box-item"
placement="top-start"
>
{{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover') }}:<br />
[<br />
{<br />
"label": "xx",<br />
"value": "xx",<br />
"default": false<br />
}<br />
]<br />
label: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_label') }}
{{ $t('common.required') }}<br />
value: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_value') }}
{{ $t('common.required') }}<br />
default: {{ $t('dynamicsForm.AssignmentMethod.ref_variables.popover_default') }}
<template #reference>
<el-icon><InfoFilled /></el-icon>
</template> </el-popover
></el-radio>
</el-radio-group>
</el-row>
</el-form-item>
Expand Down
Loading
Loading