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
12 changes: 12 additions & 0 deletions ui/src/views/tool/component/ToolListContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@
ref="ResourceAuthorizationDrawerRef"
v-if="apiType === 'workspace'"
/>
<ToolStoreDescDrawer ref="toolStoreDescDrawerRef" />
</template>

<script lang="ts" setup>
Expand All @@ -383,6 +384,7 @@ import permissionMap from '@/permission'
import useStore from '@/stores'
import { t } from '@/locales'
import ToolStoreApi from '@/api/tool/store.ts'
import ToolStoreDescDrawer from "@/views/tool/component/ToolStoreDescDrawer.vue";
const route = useRoute()
const { folder, user, tool } = useStore()
onBeforeRouteLeave((to, from) => {
Expand Down Expand Up @@ -473,12 +475,22 @@ function openAuthorizedWorkspaceDialog(row: any) {
}
}

const toolStoreDescDrawerRef = ref<InstanceType<typeof ToolStoreDescDrawer>>()
function openCreateDialog(data?: any) {
// mcp工具
if (data?.tool_type === 'MCP') {
openCreateMcpDialog(data)
return
}
// 有版本号的展示readme,是商店更新过来的
if (data?.version) {
let readMe = ''
storeTools.value.filter((item) => item.id === data.template_id).forEach((item) => {
readMe = item.readMe
})
toolStoreDescDrawerRef.value?.open(readMe, data)
return
}
// 有template_id的不允许编辑,是模板转换来的
if (data?.template_id) {
return
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 is mostly clean and well-written, but there is one issue related to the ToolStoreDescDrawer component:

  1. Potential Missing Initialization: The ref for toolStoreDescDrawerRef might not be initialized correctly within the same scope where it is being referenced. Ensure that if this ref needs initialization before you call its methods, it should be set up properly.

Additionally, here's a minor suggestion for optimization:

if (data?.version && storeTools.value.some(item => item.id === data.template_id)) {

instead of

storeTools.value.filter((item) => item.id === data.template_id).forEach(() => {})

This change reduces unneccesary iteration over the list when only checking existence.

Other than these changes, the code seems complete and functional, with good separation of concerns and appropriate event handling. Keep in mind that without more context about how storeTools, useRoute(), and t()` functions are used elsewhere in the application, I can't address all aspects, but the issues listed above have been identified as potential areas for improvement.

Expand Down
89 changes: 89 additions & 0 deletions ui/src/views/tool/component/ToolStoreDescDrawer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<template>
<el-drawer v-model="visibleInternalDesc" size="60%" :append-to-body="true">
<template #header>
<div class="flex align-center" style="margin-left: -8px">
<el-button class="cursor mr-4" link @click.prevent="visibleInternalDesc = false">
<el-icon :size="20">
<Back />
</el-icon>
</el-button>
<h4>详情</h4>
</div>
</template>

<div>
<div class="card-header">
<div class="flex-between">
<div class="title flex align-center">
<el-avatar
v-if="isAppIcon(toolDetail?.icon)"
shape="square"
:size="64"
style="background: none"
class="mr-8"
>
<img :src="toolDetail?.icon" alt="" />
</el-avatar>
<el-avatar
v-else-if="toolDetail?.name"
:name="toolDetail?.name"
pinyinColor
shape="square"
:size="64"
class="mr-8"
/>
<div class="ml-16">
<h3 class="mb-8">{{ toolDetail.name }}</h3>
<el-text type="info" v-if="toolDetail?.desc">
{{ toolDetail.desc }}
</el-text>
</div>
</div>
</div>

<div class="mt-16">
<el-text type="info">
<div>{{ $t('common.author') }}: MaxKB</div>
</el-text>
</div>
</div>
<MdPreview
ref="editorRef"
editorId="preview-only"
:modelValue="markdownContent"
style="background: none"
noImgZoomIn
/>
</div>
</el-drawer>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { cloneDeep } from 'lodash'
import { isAppIcon } from '@/utils/common'
const emit = defineEmits(['refresh', 'addTool'])
const visibleInternalDesc = ref(false)
const markdownContent = ref('')
const toolDetail = ref<any>({})
watch(visibleInternalDesc, (bool) => {
if (!bool) {
markdownContent.value = ''
}
})
const open = (data: any, detail: any) => {
toolDetail.value = detail
if (data) {
markdownContent.value = cloneDeep(data)
}
visibleInternalDesc.value = true
}
defineExpose({
open
})
</script>
<style lang="scss"></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 seems to be a Vue.js component template file that defines an el-drawer dialog for displaying details of a tool. Here's a concise list of some improvements and potential optimizations:

  1. Template Cleanup:

    • Remove leading/trailing spaces within lines.
    • Simplify attribute definitions with shorthand.
  2. Script Setup Improvements:

    • Use reactive instead of ref when handling complex objects like toolDetail.
    • Inline conditional styles using CSS literals where possible.
  3. Markdown Preview Enhancements:

    • Ensure the noImgZoomIn option does not affect other images on the page.
    • Consider adding a placeholder image until the actual Markdown content loads.
  4. Component Documentation:

    • Add JSDoc comments to explain public methods (open) and their parameters (e.g., data, detail).
    • Document private properties (like visibleInternalDesc) and how they are used/modified.
  5. State Management:

    • Instead of cloning deeply, consider reusing existing data structures if possible, or provide a method to update the detailed content without creating unnecessary copies.

Here’s an updated version with these suggestions addressed:

<template>
  <el-drawer v-model="visibleInternalDesc" size="60%" append-to-body>
    <template #header>
      <div class="flex align-center d-flex justify-content-between m-0 px-4 py-1" style="color: var(--el-color-info)">
        <el-button class="close-btn text-black cursor-pointer" link @click.prevent="toggleDrawer">
          <i class="ri-arrow-left-line mx-1"></i> 返回
        </el-button>
        <h4 class="text-xl font-bold">详情</h4>
      </div>
    </template>

    <div>
      <div class="d-flex justify-content-between mb-8">
        <el-avatar
          v-if="isAppIcon(toolDetail.icon)"
          shape="square"
          :size="64"
          class="m-2"
          bg-color="#fff"
        >
          <img :src="toolDetail.icon" alt="" />
        </el-avatar>
        <div class="pl-2 flex-grow-1">
          <h3>{{ toolDetail.name }}</h3>
          <el-tooltip placement="top-start" trigger="hover" content="描述">
            <p v-if="toolDetail.desc" class="text-gray-700">{{ toolDetail.desc }}</p>
          </el-tooltip>
        </div>
      </div>

      <div class="mb-4">
        <span class="font-medium text-sm">开发者:</span><span class="ml-2 text-base font-semibold">{{
          toolDetail?.author || '未填写' // Handle case where author might be missing
        }}</span>
      </div>

      <md-preview ref="editorRef" editor-id="preview-only" :model-value="markdownContent" bg="none" no-img-zoom-in></md-preview>
    </div>
  </el-drawer>
</template>

<script setup lang="ts">
import { reactive, watch } from 'vue';
import MdPreview from '@/components/MdPreview.vue';
import { isAppIcon } from "@/utils/common";

// Data declarations
const drawerState = reactive({ visible: false });
const markdownContent = reactive('');
const toolDetail = reactive<any>({});

const toggleDrawer = () => {
  drawerState.visible = !drawerState.visible;
};

const open = (data?: any, detail: any) => {
  Object.assign(toolDetail, detail);
  if (data) {
    markDownContent.value = data;
  }
  drawerState.visible = true;
}

defineExpose({
  open,
});
</script>

<style scoped lang="scss">
.close-btn {
  color: inherit;
}

.card-header {
  h3 {
    margin-bottom: 1rem;
  }
}
</style>

These modifications improve readability, performance, and usability while maintaining functionality.

2 changes: 1 addition & 1 deletion ui/src/workflow/nodes/mcp-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
v-model="item.source"
size="small"
style="width: 85px"
@change="form_data.tool_params[form_data.params_nested] = {}; form_data.tool_params[form_data.params_nested][item.label.label]"
@change="form_data.tool_params[form_data.params_nested] = {}; form_data.tool_params[form_data.params_nested][item.label.label] = ''"
>
<el-option
:label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.reference')"
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 appears to have a logical error in its @change event handler. The original version attempts to set an empty object as the value for form_data.tool_params[form_data.params_nested][item.label.label] if there is no change, which might not be intended behavior.

Here's a corrected and optimized version of the line:

@change="handleParamChange(item)"

In addition, you should define handleParamChange somewhere in your component file to handle the parameter change more appropriately. This function can then manage state changes based on the new values or trigger further logic as needed.

Example of how you could define this function:

methods: {
  handleParamChange(item) {
    // Handle the change here, e.g., update tool_params
    const label = item.label ? item.label.label : '';
    form_data.tool_params[form_data.params_nested] = { [label]: true }; // Or any other appropriate default value
  }
}

By separating out the logic into a dedicated method, you make the code cleaner and easier to maintain.


For a complete example context understanding and adjustments might be required depending on surrounding JavaScript and template structures within the application workflow nodes context. Ensure that you have reviewed related components for proper data flow and interactions with the form.

Expand Down
Loading