Repository navigation
feat: trigger permission #7740
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
feat: trigger permission #7740
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 |
|---|---|---|
|
|
@@ -9,6 +9,14 @@ import type { ToolItem, ResourceTrigger, ResourceTriggerResource, TriggerSetting | |
| import { RESOURCE_TYPE, TRIGGER_TYPE, SCHEDULE_TYPE } from '@/api/enums' | ||
| import { MsgSuccess } from '@/utils/message' | ||
| import TriggerFormDrawer from '@/views/trigger/trigger-form/TriggerFormDrawer.vue' | ||
| import perm from '@/permission' | ||
| import { isSystemResource } from '@/utils/resource-context' | ||
|
|
||
| type ToolTriggerPermissionMethod = 'triggerCreate' | 'triggerEdit' | 'triggerDelete' | ||
| function toolTriggerPermission(method: ToolTriggerPermissionMethod): boolean { | ||
| if (isSystemResource()) return Boolean(perm.tool.system[method]()) | ||
| return Boolean(perm.tool.workspace[method](props.tool.id)) | ||
| } | ||
|
|
||
| const props = defineProps<{ | ||
| toolApi?: typeof ToolApi | typeof SystemToolApi | ||
|
|
@@ -98,7 +106,7 @@ defineExpose({ open }) | |
| <h4>触发器</h4> | ||
| <div class="flex-align-center"> | ||
| <!-- 添加触发器 --> | ||
| <el-button text :disabled="loading" @click="handleOpenForm()" class="text-N900!"> | ||
| <el-button v-if="toolTriggerPermission('triggerCreate')" text :disabled="loading" @click="handleOpenForm()" class="text-N900!"> | ||
| <MkIcon name="icon_add_outlined" /> | ||
| <span>添加</span> | ||
| </el-button> | ||
|
|
@@ -121,11 +129,11 @@ defineExpose({ open }) | |
| <div class="flex-align-center shrink-0"> | ||
| <!-- 编辑触发器 --> | ||
|
|
||
| <el-button text :disabled="loading" @click="handleOpenForm(trigger.id)"><MkIcon name="icon_edit_outlined" /></el-button> | ||
| <el-button v-if="toolTriggerPermission('triggerEdit')" text :disabled="loading" @click="handleOpenForm(trigger.id)"><MkIcon name="icon_edit_outlined" /></el-button> | ||
|
|
||
| <!-- 移除当前资源的触发器 --> | ||
|
|
||
| <el-button text :disabled="loading" @click="handleRemoveTrigger(trigger)"><MkIcon name="icon_close_outlined" /></el-button> | ||
| <el-button v-if="toolTriggerPermission('triggerDelete')" text :disabled="loading" @click="handleRemoveTrigger(trigger)"><MkIcon name="icon_close_outlined" /></el-button> | ||
| </div> | ||
| </div> | ||
| </el-card> | ||
|
Contributor
Author
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. Review1.
Fix: Move the function below 2. The permission result depends on:
If any of these can change at runtime (e.g., props change, permission store updates), the Recommended fix — use a computed: import { computed } from 'vue'
const triggerPermissions = computed(() => {
const system = isSystemResource()
return {
create: system ? !!perm.tool.system.triggerCreate() : !!perm.tool.workspace.triggerCreate(props.tool.id),
edit: system ? !!perm.tool.system.triggerEdit() : !!perm.tool.workspace.triggerEdit(props.tool.id),
delete: system ? !!perm.tool.system.triggerDelete() : !!perm.tool.workspace.triggerDelete(props.tool.id),
}
})Then in template: This also avoids calling three separate functions per render item. 3. Minor style nit — 4. Repeated calls per trigger row With N triggers, 5. Type union literal lacks exhaustiveness safety If new methods are added to 6. Silent denial vs. disabled state You switched from 7. Handle empty-state UI If a user has no 8. Assumption about
9. Testing / mocking risk Importing Summary of priorities:
|
||
|
|
||
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.
Here is the review of the provided code diff, highlighting potential issues and optimization suggestions:
1. Critical Logic Issue:
propsAccessibility in Helper FunctionThe
applicationTriggerPermissionfunction referencesprops.application.id. However, in Vue<script setup>, functions defined outside the script setup context (or in certain utility scopes) might not have direct access topropsunless they are defined correctly within the component setup or closed over properly.propsis not explicitly passed intoapplicationTriggerPermissionor if TypeScript/ESLint complains about implicit dependency, this could break.propsis accessible via closure (which it likely is since it's inside.vuefile script setup), but consider makingpropsan explicit parameter for clarity and testability:propsis initialized before this function is ever called. SincedefinePropsreturns reactive props, accessingprops.application.idinside a helper function defined afterdefinePropsis standard and safe.2. Performance & Reactive Updates
v-if="applicationTriggerPermission('...')"is evaluated on every render cycle. While Boolean checks are cheap,isSystemResource()andperm[...]()might involve non-trivial logic.computed:v-if="canEdit"andv-if="canDelete"in the template for each trigger card.3. UX Consistency: Hidden vs. Disabled Buttons
v-if) when permission is denied.:disabled="!applicationTriggerPermission(...)") instead of hiding them. Hiding can make the UI feel inconsistent or "broken" if users expect controls to be visible but inactive.aria-disabledattributes may also be needed.4. Type Safety & Enum Usage
ApplicationTriggerPermissionMethodis well-defined and restricts allowed strings. ✅ Good practice.perm.application.systemandperm.application.workspaceobjects actually contain methods named exactly'triggerCreate','triggerEdit','triggerDelete'. Mismatched names will result in runtime errors (though TypeScript should catch this if types are strict).5. Security & Backend Validation
v-if) are for UX only. They do not provide security.handleOpenForm,handleRemoveTrigger) are also protected by backend authentication/authorization checks. Never rely solely on the UI hiding buttons.6. Code Style & Naming
applicationTriggerPermissionis good, but consider naming ithasTriggerPermissionfor better readability.computedfromvueif you adopt the optimization suggestion above.✅ Recommended Refactored Code Snippet (with
computed)And in the template:
This approach improves performance, readability, and guards against potential null/undefined errors.