|
1 | 1 | <script setup lang="ts"> |
2 | 2 | import type { McpAccessKey, McpTool, UpdateMcpAccessKeyRequest } from '@/api' |
3 | 3 | import McpToolCard from '@/components/McpToolCard.vue' |
4 | | -import { ALL_TOOLS, groupTools } from '@/utils/tool' |
| 4 | +import { ALL_TOOLS, groupTools, type ToolCategoryGroup } from '@/utils/tool' |
5 | 5 | import { submitForm } from '@formkit/core' |
6 | 6 | import { VAlert, VButton, VSpace, VTag } from '@halo-dev/components' |
7 | 7 | import { utils } from '@halo-dev/ui-shared' |
@@ -43,6 +43,20 @@ const unavailableAllowedTools = shallowRef( |
43 | 43 |
|
44 | 44 | const selectedCount = computed(() => props.tools.filter((tool) => selected[tool.name]).length) |
45 | 45 |
|
| 46 | +function isCategoryFullySelected(category: ToolCategoryGroup) { |
| 47 | + return category.tools.every((tool) => selected[tool.name]) |
| 48 | +} |
| 49 | +
|
| 50 | +function isCategoryPartiallySelected(category: ToolCategoryGroup) { |
| 51 | + return !isCategoryFullySelected(category) && category.tools.some((tool) => selected[tool.name]) |
| 52 | +} |
| 53 | +
|
| 54 | +function toggleCategory(category: ToolCategoryGroup, checked: boolean) { |
| 55 | + for (const tool of category.tools) { |
| 56 | + selected[tool.name] = checked |
| 57 | + } |
| 58 | +} |
| 59 | +
|
46 | 60 | function applyPreset(preset: 'read' | 'content' | 'all' | 'none') { |
47 | 61 | if (preset === 'none') { |
48 | 62 | unavailableAllowedTools.value = [] |
@@ -174,8 +188,18 @@ defineExpose({ |
174 | 188 | </div> |
175 | 189 | <div class=":uno: flex flex-col gap-4"> |
176 | 190 | <div v-for="category in group.categories" :key="category.category"> |
177 | | - <div class=":uno: mb-2 flex items-center gap-2 text-xs text-gray-500 font-medium"> |
178 | | - <span>{{ category.label }}</span> |
| 191 | + <div class=":uno: mb-3 flex items-center gap-2 text-xs text-gray-500 font-medium"> |
| 192 | + <label class=":uno: flex cursor-pointer items-center gap-1.5"> |
| 193 | + <input |
| 194 | + type="checkbox" |
| 195 | + class=":uno: h-3.5 w-3.5 accent-[rgb(var(--colors-primary))]" |
| 196 | + :checked="isCategoryFullySelected(category)" |
| 197 | + :indeterminate.prop="isCategoryPartiallySelected(category)" |
| 198 | + :aria-label="`选择${category.label}分组全部工具`" |
| 199 | + @change="toggleCategory(category, ($event.target as HTMLInputElement).checked)" |
| 200 | + /> |
| 201 | + <span>{{ category.label }}</span> |
| 202 | + </label> |
179 | 203 | <span>{{ category.tools.length }}</span> |
180 | 204 | </div> |
181 | 205 | <div class=":uno: grid grid-cols-1 gap-3 sm:grid-cols-2"> |
|
0 commit comments