Repository navigation
fix: application export skills - #7788
Conversation
| <MkDropdownItem v-if="canExportApplication || canExportSkills" @click.prevent.stop class="p-0!"> | ||
| <MkDropdown class="w-full" trigger="hover" placement="right-start" :append-to="exportMenuContainer"> | ||
| <!-- 展开智能体导出菜单 --> | ||
| <div ref="exportTriggerRef" class="flex-between w-full gap-2 p-2"> |
There was a problem hiding this comment.
Here is an analysis of the provided code snippet, focusing on irregularities, potential issues, and optimizations.
1. Potential Logic Issue: canExportSkills Condition
Issue:
In the canExportSkills computed property, you added a check for props.application.is_publish.
const canExportSkills = computed(
() =>
props.application.is_publish && // <--- New condition
(isSystem.value ? perm.application.system.exportSkills() : perm.application.workspace.exportSkills(props.application.id)),
)Risk:
- If
props.applicationis undefined or null, accessing.is_publishwill throw a runtime error. Ensureprops.applicationis guaranteed to exist elsewhere or add optional chaining (props.application?.is_publish). - Business Logic: Does un-published applications really not allow exporting skills? If this is intended behavior, it is fine. If "exporting skills" should still be possible for non-published apps, this logic blocks it unnecessarily.
2. Template Logic Inconsistency
Issue:
In the template, the dropdown toggle visibility is conditioned by:
<MkDropdownItem v-if="canExportApplication || canExportSkills" ...>However, inside the dropdown, there are likely separate options for "Export Application" and "Export Skills."
Problem:
If canExportApplication is false but canExportSkills is true, the dropdown opens. The user might see a menu with only one item ("Export Skills"), or worse, if the inner components don't individually check permissions, they might render disabled/broken buttons for Export Application.
Suggestion:
Ensure that the individual options inside the <MkDropdown> also respect their respective permissions. For example:
<!-- Inside MkDropdown -->
<MenuItem v-if="canExportApplication" @click="handleExportApplication">Export App</MenuItem>
<MenuItem v-if="canExportSkills" @click="handleExportSkills">Export Skills</MenuItem>Without internal v-ifs, showing a parent menu based on || could lead to UX confusion if one permission fails while the other passes.
3. Code Style & Readability
Suggestion:
The canExportSkills computed property spans multiple lines awkwardly. While prettier might format it this way, it can be made cleaner for readability.
Optimized Version:
const canExportSkills = computed(() => {
// Early return if not published (clearer intent than long boolean chain)
if (!props.application?.is_publish) {
return false;
}
return isSystem.value
? perm.application.system.exportSkills()
: perm.application.workspace.exportSkills(props.application.id);
});4. Dependency Safety (props.application.id)
Issue:
In canExportApplication:
perm.application.workspace.export(props.application.id)If isSystem is false, we assume a workspace context. If props.application is undefined here, it crashes.
Best Practice:
Ideally, canExportApplication and canExportSkills should share a common safety check or rely on a precomputed safe state object for the application data.
Summary of Recommendations
- Add Optional Chaining/Checks: Ensure
props.applicationexists before accessing.is_publishor.id. - Internal Menu Filtering: Verify that child elements inside
MkDropdownare conditionally rendered based on their specific permissions (canExportApplicationvscanExportSkills), not just the combined flag. This prevents displaying empty/disabled states incorrectly. - Readability: Use early returns in
canExportSkillsto handle theis_publishgate clearly.
Corrected/Cleaned Code Example
// Script section
const canExportApplication = computed(() => {
if (!props.application) return false; // Safety guard
return isSystem.value
? perm.application.system.export()
: perm.application.workspace.export(props.application.id);
});
const canExportSkills = computed(() => {
// Ensure app exists and is published
if (!props.application?.is_publish) return false;
return isSystem.value
? perm.application.system.exportSkills()
: perm.application.workspace.exportSkills(props.application.id);
});<!-- Template section -->
<template>
<!-- Parent visibility relies on at least one action being available -->
<MkDropdownItem
v-if="canExportApplication || canExportSkills"
@click.prevent.stop
class="p-0!"
>
<MkDropdown
class="w-full"
trigger="hover"
placement="right-start"
:append-to="exportMenuContainer"
>
<!-- Option 1: Export Application -->
<div
v-if="canExportApplication"
class="flex-between w-full gap-2 p-2"
@click="handleExportApplication"
>
<!-- Label/icons -->
</div>
<!-- Option 2: Export Skills -->
<div
v-if="canExportSkills"
class="flex-between w-full gap-2 p-2"
@click="handleExportSkills"
>
<!-- Label/icons -->
</div>
<!-- Note: Adjust structure based on actual component hierarchy -->
</MkDropdown>
</MkDropdownItem>
</template>
【【智能体】「未发布」状态的智能体,菜单中的「导出为Skills」按钮可点击】
https://www.tapd.cn/tapd_fe/45245355/bug/detail/1145245355001079078