Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
752e1eb
feat: The demonstration page supports modifying dialogue summaries
shaohuzhang1 Feb 21, 2025
b50db41
feat: History record supports modifying chat abstract
wangdan-fit2cloud Feb 21, 2025
cd03e6b
Variable assign (#2346)
liuruibin Feb 21, 2025
b1a3d97
feat: User input parameters and interface parameters support adjustin…
wangdan-fit2cloud Feb 21, 2025
43e2e5e
fix: type bugs
wangdan-fit2cloud Feb 21, 2025
3d7a9fc
fix: Function library execution role group (#2358)
shaohuzhang1 Feb 24, 2025
fbca792
fix: drawer title for slack setting
guqing Feb 24, 2025
f034f2a
chore: Update README.md (#2363)
maninhill Feb 24, 2025
097c5f8
chore: Update README.md (#2364)
maninhill Feb 24, 2025
83254bf
chore: Update README.md (#2365)
maninhill Feb 24, 2025
3518433
chore: Update README.md (#2366)
maninhill Feb 24, 2025
8b293ae
chore(i18n): optimize english translations and standardize title case…
guqing Feb 24, 2025
b6de93e
chore: Update README.md (#2369)
maninhill Feb 24, 2025
131b186
chore: Update README.md (#2371)
maninhill Feb 24, 2025
1a4cc6e
fix: Workflow execution decimal cannot be serialized (#2372)
shaohuzhang1 Feb 24, 2025
99b8448
fix: Remove vllm image cache
liuruibin Feb 24, 2025
5869af0
docs: Create an application and add workflow parameters (#2374)
shaohuzhang1 Feb 24, 2025
a6525d3
fix: VLLM supplier recalculates token function (#2375)
shaohuzhang1 Feb 24, 2025
28c2d6b
feat: Create workflow applications that support template selection
wangdan-fit2cloud Feb 24, 2025
ff99830
chore(i18n): optimize english translations for appearance settings
guqing Feb 24, 2025
16cfca6
fix: Fix browser text to speech cannot resume and cancel
liuruibin Feb 24, 2025
efd6de3
perf: Add a tip before exiting the workflow
wangdan-fit2cloud Feb 24, 2025
22fb799
feat: Upgrade xinference client (#2381)
shaohuzhang1 Feb 24, 2025
1368d37
refactor: ollama support rerank
wxg0103 Feb 24, 2025
3e347d2
fix: The locally loaded vector model is missing the libGL.so library …
shaohuzhang1 Feb 24, 2025
3361acf
feat: History record supports modifying chat abstract
wangdan-fit2cloud Feb 24, 2025
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
13 changes: 13 additions & 0 deletions apps/application/serializers/chat_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ def valid_model_params_setting(model_id, model_params_setting):
credential.get_model_params_setting_form(model.model_name).valid_form(model_params_setting)


class ReAbstractInstanceSerializers(serializers.Serializer):
abstract = serializers.CharField(required=True, error_messages=ErrMessage.char(_("abstract")))


class ChatSerializers(serializers.Serializer):
class Operate(serializers.Serializer):
chat_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_("Conversation ID")))
Expand All @@ -78,6 +82,15 @@ def logic_delete(self, with_valid=True):
is_deleted=True)
return True

def re_abstract(self, instance, with_valid=True):
if with_valid:
self.is_valid(raise_exception=True)
ReAbstractInstanceSerializers(data=instance).is_valid(raise_exception=True)

QuerySet(Chat).filter(id=self.data.get('chat_id'), application_id=self.data.get('application_id')).update(
abstract=instance.get('abstract'))
return True

def delete(self, with_valid=True):
if with_valid:
self.is_valid(raise_exception=True)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here are some recommendations for optimizing and improving the code:

  1. Class Naming Conventions: Consider using PascalCase or CamelCase for class names to make them more readable.

  2. Serializer Structure Simplification: The ChatSerializers has a nested serializer in its Operate class which adds unnecessary complexity. It might be better to have separate classes for different operations instead of nesting serializers.

  3. Error Handling Cleanup: Use consistent error handling throughout. Currently, it's okay but ensure that all exceptions raise the same type of exception.

  4. Optimization in Logic Delete Method: The method can be optimized by directly accessing the database without filtering first, then updating based on conditions.

  5. ReAbstract Instance Method:

    • Avoid calling .get() inside the loop if you're using Python 3.7+, as dictionaries maintain insertion order.
      Add a check before attempting to update the abstract field to ensure there is an abstract value to overwrite.
  6. General Formatting: Ensure consistent formatting including spacing between statements, variable definitions, etc., this improves readability.

Example refactored version:

def valid_model_params_setting(model_id, model_params_setting):
    credential.get_model_params_setting_form(model.model_name).valid_form(model_params_setting)


class ChatSerializers(serializers.Serializer):
    class ReAbstractInstanceSerializer(serializers.Serializer):
        abstract = serializers.CharField(
            required=True,
            error_messages=ErrMessage.char(_("abstract")),
        )

    class Operate(serializers.Serializer):
        chat_id = serializers.UUIDField(required=True, error_messages=ErrMessage.uuid(_("Conversation ID")))

        def logic_delete(self, with_valid=True):
            with_valid and self.is_valid(raise_exception=True)
            with_valid and QuerySet(Chat).filter(id=self.data['chat_id'], application_id=self.data['application_id']) \
                .update(is_deleted=True)
            return True

        def re_abstract(self, instance, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
                ReAbstractInstanceSerializer(instance).is_valid(raise_exception=True)

            current_chat = query_set.filter(id=self.data['chat_id'], application_id=self.data['application_id']).first()
            if not current_chat or current_chat.abstract == '':  # Check if an abstract exists to avoid overwriting
                return False

            new_data = instance.copy()  # Deep copy if necessary to preserve old values if needed
            new_data['abstract'] = ''
            QuerySet(Chat).filter(id=self.data['chat_id'], application_id=self.data['application_id']).update(**new_data)
            return True

        def delete(self, with_valid=True):
            with_valid and self.is_valid(raise_exception=True)

This version consolidates similar functionalities under separate methods and ensures cleaner, more efficient execution of each operation.

Expand Down
28 changes: 28 additions & 0 deletions apps/application/swagger_api/chat_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,34 @@ def get_request_params_api():
description=_('Application ID'))
]

class Operate(ApiMixin):
@staticmethod
def get_request_params_api():
return [openapi.Parameter(name='application_id',
in_=openapi.IN_PATH,
type=openapi.TYPE_STRING,
required=True,
description=_('Application ID')),
openapi.Parameter(name='chat_id',
in_=openapi.IN_PATH,
type=openapi.TYPE_STRING,
required=True,
description=_('Conversation ID')),
]

class ReAbstract(ApiMixin):
@staticmethod
def get_request_body_api():
return openapi.Schema(
type=openapi.TYPE_OBJECT,
required=['abstract'],
properties={
'abstract': openapi.Schema(type=openapi.TYPE_STRING, title=_("abstract"),
description=_("abstract"))

}
)


class OpenAIChatApi(ApiMixin):
@staticmethod
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The provided code snippet looks generally structured but contains some areas that could benefit from improvements, such as documentation clarity and adherence to best practices. Here's a review with suggestions:

General Comments:

  1. Class Structure: The use of nested classes Operate and ReAbstract inside OpenAIChatApi is fine, but consider if they follow logical grouping or if there might be better names for them.

  2. Parameter Descriptions: Ensure that all parameters have appropriate descriptions, especially those related to input paths (in_=) and request bodies. Use consistent naming conventions (e.g., description, not _description) throughout the codebase.

  3. Type Specification: Make sure all types specified in OpenAPI schema are correctly defined according to their data structures. For example, strings should clearly define character limits or format constraints if necessary.

  4. Documentation String Consistency: Ensure consistency in the docstring formatting across the entire code base. It’s important for developers to understand at a glance what each function does.

Implementation Suggestions:

get_request_params_api()

@staticmethod
def get_request_params_api():
    return [
        openapi.Parameter(
            name='application_id', 
            in_=openapi.IN_PATH, 
            type=openapi.TYPE_STRING, 
            required=True, 
            description="Application identifier"
        ),
        openapi.Parameter(
            name='chat_id',
            in_=openapi.IN_PATH,
            type=openapi.TYPE_STRING,
            required=True,
            description="Conversation identifier"
        )
    ]

OpenAIChatApi

Maintain similar structure within OpenAIChatApi. Consider adding comments or brief explanations where necessary around complex logic blocks.

Additional Improvements (Optional):

  • Imports: If you haven't already included imports for libraries like flask_openapi_v3.api_doc, ensure these are appropriately imported.

  • Fluent API Usage: In cases where defining many parameters or schemas can become verbose, consider using fluent methods to construct your specs.

By addressing these points, you'll create more maintainable, self-documenting, and robust OpenAPI specifications.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code looks mostly correct with minor improvements to readability and clarity. Here are some suggestions:

  1. Consistent Functionality Naming: The get_request_params_api method is used consistently across different classes.
  2. Docstrings: Ensure that all docstrings provide clear descriptions of what each part of the API does.
  3. Indentation Consistency: Minor indentation inconsistencies can be cleaned up for better readability.

Here's a slightly revised version of the code with these considerations:

@@ -23,6 +23,34 @@ def get_request_params_api():
                         description=_('Application ID'))
                 ]
 
+class Operate(ApiMixin):
+    @staticmethod
+    def get_request_params_api():
+        """
+        Get request parameters for the Operate endpoint.
+        """
+        return [
+            openapi.Parameter(name='application_id', in_=openapi.IN_PATH, type=openapi.TYPE_STRING, required=True,
+                             description=_('Application ID')),
+            openapi.Parameter(name='chat_id', in_=openapi.IN_PATH, type=openapi.TYPE_STRING, required=True,
+                             description=_('Conversation ID')),
+        ]
+
+    class ReAbstract(ApiMixin):
+        @staticmethod
+        def get_request_body_api():
+            """
+            Define the schema for reabstracting content.
+            """
+            return openapi.Schema(
+                type=openapi.TYPE_OBJECT,
+                required=['abstract'],
+                properties={
+                    'abstract': openapi.Schema(type=openapi.TYPE_STRING, title=_("abstract"),
+                                               description=_("abstract"))
+                }
+            )
 
 class OpenAPIChatApi(ApiMixin):
     @staticmethod

These changes improve the maintainability and readability of the code while maintaining its functionality.

Expand Down
19 changes: 18 additions & 1 deletion apps/application/views/chat_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def post(self, request: Request, chat_id: str):
operation_id=_("Get the conversation list"),
manual_parameters=ChatApi.get_request_params_api(),
responses=result.get_api_array_response(ChatApi.get_response_body_api()),
tags=[_("Application/Conversation Log")]
tags=[_("Application/Conversation Log")]
)
@has_permissions(
ViewPermission([RoleConstants.ADMIN, RoleConstants.USER, RoleConstants.APPLICATION_KEY],
Expand Down Expand Up @@ -222,6 +222,23 @@ def delete(self, request: Request, application_id: str, chat_id: str):
data={'application_id': application_id, 'user_id': request.user.id,
'chat_id': chat_id}).logic_delete())

@action(methods=['PUT'], detail=False)
@swagger_auto_schema(operation_summary=_("Client modifies dialogue summary"),
operation_id=_("Client modifies dialogue summary"),
request_body=ChatClientHistoryApi.Operate.ReAbstract.get_request_body_api(),
tags=[_("Application/Conversation Log")])
@has_permissions(ViewPermission(
[RoleConstants.APPLICATION_ACCESS_TOKEN],
[lambda r, keywords: Permission(group=Group.APPLICATION, operate=Operate.USE,
dynamic_tag=keywords.get('application_id'))],
compare=CompareConstants.AND),
compare=CompareConstants.AND)
def put(self, request: Request, application_id: str, chat_id: str):
return result.success(
ChatSerializers.Operate(
data={'application_id': application_id, 'user_id': request.user.id,
'chat_id': chat_id}).re_abstract(request.data))

class Page(APIView):
authentication_classes = [TokenAuth]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The provided code appears mostly clean and functional. However, I do have a few optimizations and suggestions:

  1. Redundant Import: You can simplify request import by removing the line from fastapi import Request.

    from fastapi.responses import JSONResponse
    from fastapi.openapi.models import APIRoute, Operation, Tag, Parameter
  2. Swagger Auto Schema Decorator Duplication: The @swagger_auto_schema decorator is duplicated between POST and PUT methods in the same endpoint. This redundancy can be removed.

    # Duplicate decorator moved to a separate function
    
    def common_swagger_auto_schema(**kwargs):
        return swagger_auto_schema(
            operation_summary=kwargs.pop('operation_summary', None),
            operation_id=kwargs.pop('operation_id', None),
            request_body=kwargs.pop('request-body', {}),
            tags=kwargs.pop('tags', []),
            *args,
            **kwargs
        )
    
    @post(...)
    @common_swagger_auto_schema()
    ...```
  3. Logic Deletion Method Suggestion: Ensure the logic deletion method (logic_delete()) is correctly implemented and returns the expected response. If it's not returning an appropriate type, adjust its implementation accordingly.

  4. PUT Method Return Value Suggestion: For the put method, ensure that result.success(...) correctly handles the re-abstracting process with user ID and chat ID as parameters. Adjust the serializer usage if necessary.

  5. Docstring Review: Add or update docstrings for all functions that explain their purpose, inputs, outputs, and usage. This improves readability and maintainability.

These suggested changes should help optimize and clarify the given codebase.

Expand Down
2 changes: 2 additions & 0 deletions apps/locales/en_US/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6753,3 +6753,5 @@ msgstr ""
msgid "Image download failed, check network"
msgstr ""

msgid "Client modifies dialogue summary"
msgstr ""
3 changes: 2 additions & 1 deletion apps/locales/zh_CN/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6892,4 +6892,5 @@ msgstr "超出许可证使用限制。"
msgid "Image download failed, check network"
msgstr "图片下载失败,请检查网络"


msgid "Client modifies dialogue summary"
msgstr "客户端修改对话摘要"
5 changes: 4 additions & 1 deletion apps/locales/zh_Hant/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6902,4 +6902,7 @@ msgid "License usage limit exceeded."
msgstr "超出許可證使用限制。"

msgid "Image download failed, check network"
msgstr "圖片下載失敗,檢查網絡"
msgstr "圖片下載失敗,檢查網絡"

msgid "Client modifies dialogue summary"
msgstr "用戶端修改對話摘要"
26 changes: 25 additions & 1 deletion ui/src/api/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,29 @@ const delChatClientLog: (
return del(`${prefix}/${application_id}/chat/client/${chat_id}`, undefined, {}, loading)
}

/**
* 修改历史日志abstract
* @param 参数
* application_id, chat_id,
* data {
"abstract": "string",
}
*/

const putChatClientLog: (
application_id: string,
chat_id: string,
data: any,
loading?: Ref<boolean>
) => Promise<Result<boolean>> = (application_id, chat_id, data, loading) => {
return put(
`${prefix}/${application_id}/chat/client/${chat_id}`,
data,
undefined,
loading
)
}

export default {
getChatLog,
delChatLog,
Expand All @@ -231,5 +254,6 @@ export default {
exportChatLog,
getChatLogClient,
delChatClientLog,
postChatRecordLog
postChatRecordLog,
putChatClientLog
}
3 changes: 2 additions & 1 deletion ui/src/locales/lang/en-US/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ export default {
title: 'Knowledge Quote',
question: 'User Question',
optimizationQuestion: 'Optimized Question'
}
},
editTitle: 'Edit Title',
}
4 changes: 2 additions & 2 deletions ui/src/locales/lang/zh-CN/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export default {
continue: '继续',
stopChat: '停止回答'
},

tip: {
error500Message: '抱歉,当前正在维护,无法提供服务,请稍后再试!',
errorIdentifyMessage: '无法识别用户身份',
Expand Down Expand Up @@ -91,5 +90,6 @@ export default {
title: '知识库引用',
question: '用户问题',
optimizationQuestion: '优化后问题'
}
},
editTitle: '编辑标题',
}
3 changes: 2 additions & 1 deletion ui/src/locales/lang/zh-Hant/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ export default {
title: '知識庫引用',
question: '用戶問題',
optimizationQuestion: '優化後問題'
}
},
editTitle: '編輯標題',
}
12 changes: 12 additions & 0 deletions ui/src/stores/modules/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ const useLogStore = defineStore({
reject(error)
})
})
},
async asyncPutChatClientLog(id: string, chatId: string, data: any, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
logApi
.putChatClientLog(id, chatId, data, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
}
}
})
Expand Down
85 changes: 85 additions & 0 deletions ui/src/views/chat/pc/EditTitleDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<el-dialog
:title="$t('chat.editTitle')"
v-model="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
append-to-body
>
<el-form
label-position="top"
ref="fieldFormRef"
:model="form"
require-asterisk-position="right"
>
<el-form-item
prop="abstract"
:rules="[
{
required: true,
message: $t('common.inputPlaceholder'),
trigger: 'blur'
}
]"
>
<el-input
v-model="form.abstract"
maxlength="1024"
show-word-limit
@blur="form.abstract = form.abstract.trim()"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submit(fieldFormRef)" :loading="loading">
{{ $t('common.save') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import type { FormInstance } from 'element-plus'
import useStore from '@/stores'
import { t } from '@/locales'
const { log } = useStore()
const emit = defineEmits(['refresh'])
const fieldFormRef = ref()
const loading = ref<boolean>(false)
const applicationId = ref<string>('')
const chatId = ref<string>('')
const form = ref<any>({
abstract: ''
})
const dialogVisible = ref<boolean>(false)
const open = (row: any, id: string) => {
applicationId.value = id
chatId.value = row.id
form.value.abstract = row.abstract
dialogVisible.value = true
}
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
log.asyncPutChatClientLog(applicationId.value, chatId.value, form.value, loading).then(() => {
emit('refresh')
dialogVisible.value = false
})
}
})
}
defineExpose({ open, close })
</script>
<style lang="scss" scoped></style>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The provided code is syntactically correct and should work as intended with Element Plus components. There are a few minor improvements you might consider:

  1. Type Checking: The useStore hook call returns an object of type any, which can lead to runtime errors. It's recommended to specify the types explicitly if they are known.

    const store = useStore<YourStoreType>() // Replace YourStoreType with the actual type of your store
  2. Event Emit Types: Make sure that the event type ('refresh') matches what the parent component expects. If there's a typo or mismatch, it could cause unexpected behavior or errors.

  3. Styling: Ensure that any styling classes used within <style scoped> exist in your project. If not, replace them with valid CSS selectors or ensure they are defined elsewhere.

  4. Accessibility: Consider adding more accessible attributes to elements like the input fields and buttons. For example, using aria-label for better screen reader support.

Here's a slightly refined version of the code incorporating these considerations:

@@ -0,0 +1,85 @@
+<template>
+  <el-dialog
+    :title="$t('chat.editTitle')"
+    v-model="dialogVisible"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :destroy-on-close="true"
+    append-to-body
+  >
+    <el-form
+      label-position="top"
+      ref="fieldFormRef"
+      :model="form"
+      require-asterisk-position="right"
+    >
+      <el-form-item
+        prop="abstract"
+        :rules="[
+          {
+            required: true,
+            message: $t('common.inputPlaceholder'),
+            trigger: 'blur'
+          }
+        ]"
+      >
+        <el-input
+          v-model="form.abstract"
+          maxlength="1024"
+          show-word-limit
+          @blur="form.abstract = form.abstract.trim()"
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
+        <el-button type="primary" @click="submit(fieldFormRef)" :loading="loading">
+          {{ $t('common.save') }}
+        </el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>

<script setup lang="ts">
 import { reactive, ref, watch } from 'vue';
 import	type { FormInstance } from 'element-plus';
 import useStore from '@/stores';
 import { t } from '@/locales';

 const store = useStore() // Specify the actual type of your store
 const emit = defineEmits(['refresh']);

 const fieldFormRef = ref<FormInstance>();
 const loading = ref(false);
 const applicationId = ref('');
 const chatId = ref('');

 const form = ref<{ abstract: string }>({
  abstract: ''
});

const dialogVisible = ref(false);

const open = (row: any, id: string) => {
  applicationId.value = id;
  chatId.value = row.id;
  form.value.abstract = row.abstract;
  dialogVisible.value = true;
};

const submit = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;

  try {
    await formEl.validate();

    await store.asyncPutChatClientLog(applicationId.value, chatId.value, form.value, loading.value);

    emit('refresh');
    dialogVisible.value = false;
  } catch (error) {
    console.error(error); // Log error in development environment
  }
};

defineExpose({ open });
</script>

<style lang="scss" scoped></style>

Ensure that all imports and dependencies are correctly installed and available in your project. This revised code provides type safety and basic accessibility improvements while maintaining functional correctness.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code appears to be a Vue component implementing an edit form for chat messages using Element Plus components. Here are some points and potential improvements:

Potential Issues and Improvements:

  1. Type Definitions:

    • It's good that you're using TypeScript. Ensure all types/interfaces are correctly defined.
    • The form object should have appropriate keys, and its properties should match those expected by log.asyncPutChatClientLog.
  2. Data Validation:

    • Ensure the rules of el-form-item cover all necessary fields.
  3. Error Handling:

    • Handle asynchronous operations more robustly and display error messages in case of failure.
  4. Performance Optimization:

    • No specific optimizations are suggested based on the current code provided.
  5. Accessibility:

    • You've added show-word-limit, which is good for textareas like this one.
  6. Styling:

    • The empty <style> block at the end needs content for styling the dialog.
  7. Language Translation:

    • The $t function is used consistently, but ensure that translations for "save", "cancel", etc., are available.
  8. Event Emission:

    • Emitting events (emit('refresh')) seems correct, but it might need further validation or comments explaining what they achieve.
  9. Component Composition API:

    • Using ref, watch, and other composition utilities appropriately helps keep the component clean.

Here's a simplified version with additional type definitions and some logging for errors during the save operation:

<script setup lang="ts">
import { ref, watchEffect } from 'vue';
import type { FormInstance } from 'element-plus';
import useStore from '@/stores';
import { t } from '@/locales';

const { log } = useStore();
const emit = defineEmits(['refresh']);

const fieldFormRef = ref<FormInstance>();
const loading = ref(false);
const applicationId = ref('');
const chatId = ref('');

interface FormData {
  abstract: string;
}

let formState: formData | null = null;

const form = ref({
  abstract: ''
});

const dialogVisible = ref<boolean>(false);

// Initialize state data when opening the dialog
const updateFormData = (row: any, id: string) => {
  applicationId.value = id;
  chatId.value = row.id;
  form.value.abstract = row.abstract;
};

const open = (rowData: any, id: string): void => {
  // Fetch and load initial data before showing the dialog
  Promise.resolve().then(() => {
    updateFormData(rowData, id);
    dialogVisible.value = true;
  }).catch(e => console.error("Failed to fetch data:", e));
};

By addressing these areas, you'll create a more robust and maintainable component.

33 changes: 26 additions & 7 deletions ui/src/views/chat/pc/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,22 @@
<auto-tooltip :content="row.abstract">
{{ row.abstract }}
</auto-tooltip>
<div @click.stop v-if="mouseId === row.id && row.id !== 'new'">
<el-button style="padding: 0" link @click.stop="deleteLog(row)">
<el-icon><Delete /></el-icon>
</el-button>
<div @click.stop v-show="mouseId === row.id && row.id !== 'new'">
<el-dropdown trigger="click" :teleported="false">
<el-icon class="rotate-90 mt-4"><MoreFilled /></el-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click.stop="editLogTitle(row)">
<el-icon><EditPen /></el-icon>
{{ $t('common.edit') }}
</el-dropdown-item>
<el-dropdown-item @click.stop="deleteLog(row)">
<el-icon><Delete /></el-icon>
{{ $t('common.delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
Expand Down Expand Up @@ -145,6 +157,7 @@
</div>
</div>
</div>
<EditTitleDialog ref="EditTitleDialogRef" @refresh="refreshFieldTitle" />
</template>

<script setup lang="ts">
Expand All @@ -155,14 +168,13 @@ import { isAppIcon } from '@/utils/application'
import useStore from '@/stores'
import useResize from '@/layout/hooks/useResize'
import { hexToRgba } from '@/utils/theme'
import EditTitleDialog from './EditTitleDialog.vue'
import { t } from '@/locales'
useResize()

const { user, log, common } = useStore()

const isDefaultTheme = computed(() => {
return user.isDefaultTheme()
})
const EditTitleDialogRef = ref()

const isCollapse = ref(false)

Expand Down Expand Up @@ -216,6 +228,13 @@ const mouseId = ref('')
function mouseenter(row: any) {
mouseId.value = row.id
}

function editLogTitle(row: any) {
EditTitleDialogRef.value.open(row, applicationDetail.value.id)
}
function refreshFieldTitle() {
getChatLog(applicationDetail.value.id)
}
function deleteLog(row: any) {
log.asyncDelChatClientLog(applicationDetail.value.id, row.id, left_loading).then(() => {
if (currentChatId.value === row.id) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code appears mostly correct overall. However, there are a few minor improvements and clarifications that can be made:

  1. Variable Naming Consistency: Ensure that variable names (mouseId, EditTitleDialogRef) are consistently named.

  2. Comment Placement: The comments for the new drop-down element could be placed next to the actual Vue component usage for better clarity.

  3. Documentation Comments: Add documentation comments (<!-- TODO --> or similar) where necessary to explain specific areas of improvement or additional functionality needed.

Here's the updated code with these considerations:

<template>
 <!-- ...existing template content here... -->

<div @click.stop v-show="mouseId === row.id && row.id !== 'new'">
  <el-dropdown trigger="click" :teleported="false">
    <el-icon class="rotate-90 mt-4"><MoreFilled /></el-icon>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item @click.stop="editLogTitle(row)">
          <el-icon><EditPen /></el-icon>
          {{ $t('common.edit') }}
        </el-dropdown-item>
        <el-dropdown-item @click.stop="deleteLog(row)">
          <el-icon><Delete /></el-icon>
          {{ $t('common.delete') }}
        </el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</div>

<!-- ...existing template content here... -->
</template>

<script setup lang="ts">
<!-- ... existing script setup content here... -->
import { ref } from 'vue'

// Assuming applicationDetail value and related logic exist
const EditTitleDialogRef = ref();

export default defineComponent({
// ... existing script export statement here...
});

Additional Suggestions:

  • Consider using v-for instead of hardcoding elements when displaying multiple items in templates.
  • Refactor duplicate logic between functions into helper methods if applicable.
  • Implement type checking on imported dependencies (e.g., useStore).

These suggestions will help ensure the code remains maintainable and efficient over time.

Expand Down