|
1 | 1 | <template> |
2 | 2 | <el-dialog |
3 | | - align-center |
4 | | - :title="$t('common.setting')" |
5 | 3 | v-model="dialogVisible" |
6 | | - style="width: 550px" |
| 4 | + width="1000" |
7 | 5 | append-to-body |
| 6 | + class="addTool-dialog" |
| 7 | + align-center |
8 | 8 | :close-on-click-modal="false" |
9 | 9 | :close-on-press-escape="false" |
10 | 10 | > |
11 | | - <el-form |
12 | | - label-position="top" |
13 | | - ref="paramFormRef" |
14 | | - :model="form" |
15 | | - require-asterisk-position="right" |
16 | | - > |
17 | | - <el-form-item> |
18 | | - <el-select v-model="form.tool_ids" filterable multiple> |
19 | | - <el-option |
20 | | - v-for="mcpTool in toolSelectOptions" |
21 | | - :key="mcpTool.id" |
22 | | - :label="mcpTool.name" |
23 | | - :value="mcpTool.id" |
24 | | - > |
25 | | - <span>{{ mcpTool.name }}</span> |
26 | | - <el-tag v-if="mcpTool.scope === 'SHARED'" type="info" class="info-tag ml-8 mt-4"> |
27 | | - {{ $t('views.shared.title') }} |
28 | | - </el-tag> |
29 | | - </el-option> |
30 | | - </el-select> |
31 | | - </el-form-item> |
32 | | - </el-form> |
| 11 | + <template #header="{ titleId, titleClass }"> |
| 12 | + <div class="flex-between mb-8"> |
| 13 | + <div class="flex"> |
| 14 | + <h4 :id="titleId" :class="titleClass" class="mr-8"> |
| 15 | + {{ $t('views.tool.settingTool') }} |
| 16 | + </h4> |
| 17 | + </div> |
33 | 18 |
|
34 | | - <template #footer> |
35 | | - <span class="dialog-footer"> |
36 | | - <el-button @click.prevent="dialogVisible = false">{{ $t('common.cancel') }}</el-button> |
37 | | - <el-button type="primary" @click="submit()" :loading="loading"> |
38 | | - {{ $t('common.save') }} |
| 19 | + <el-button link class="mr-24" @click="refresh"> |
| 20 | + <el-icon :size="18"><Refresh /></el-icon> |
39 | 21 | </el-button> |
40 | | - </span> |
| 22 | + </div> |
| 23 | + </template> |
| 24 | + <LayoutContainer class="application-manage"> |
| 25 | + <template #left> |
| 26 | + <div class="p-8"> |
| 27 | + <folder-tree |
| 28 | + :data="folderList" |
| 29 | + :currentNodeKey="currentFolder?.id" |
| 30 | + @handleNodeClick="folderClickHandle" |
| 31 | + v-loading="folderLoading" |
| 32 | + :canOperation="false" |
| 33 | + showShared |
| 34 | + :shareTitle="$t('views.shared.shared_tool')" |
| 35 | + :treeStyle="{ height: 'calc(100vh - 240px)' }" |
| 36 | + /> |
| 37 | + </div> |
| 38 | + </template> |
| 39 | + <div class="layout-bg"> |
| 40 | + <div class="flex-between p-16 ml-8"> |
| 41 | + <h4>{{ currentFolder?.name }}</h4> |
| 42 | + <el-input |
| 43 | + v-model="searchValue" |
| 44 | + :placeholder="$t('common.search')" |
| 45 | + prefix-icon="Search" |
| 46 | + class="w-240 mr-8" |
| 47 | + clearable |
| 48 | + /> |
| 49 | + </div> |
| 50 | + |
| 51 | + <el-scrollbar> |
| 52 | + <div class="p-16-24 pt-0" style="height: calc(100vh - 200px)"> |
| 53 | + <el-row :gutter="12" v-loading="apiLoading" v-if="searchData.length"> |
| 54 | + <el-col :span="12" v-for="(item, index) in searchData" :key="index" class="mb-16"> |
| 55 | + <CardCheckbox |
| 56 | + value-field="id" |
| 57 | + :data="item" |
| 58 | + v-model="checkList" |
| 59 | + @change="changeHandle" |
| 60 | + > |
| 61 | + <template #icon> |
| 62 | + <el-avatar |
| 63 | + v-if="item?.icon" |
| 64 | + shape="square" |
| 65 | + :size="32" |
| 66 | + style="background: none" |
| 67 | + class="mr-8" |
| 68 | + > |
| 69 | + <img :src="resetUrl(item?.icon)" alt="" /> |
| 70 | + </el-avatar> |
| 71 | + <ToolIcon v-else :size="32" :type="item?.tool_type" /> |
| 72 | + </template> |
| 73 | + <span class="ellipsis cursor ml-12" :title="item.name"> {{ item.name }}</span> |
| 74 | + </CardCheckbox> |
| 75 | + </el-col> |
| 76 | + </el-row> |
| 77 | + <el-empty :description="$t('common.noData')" v-else /> |
| 78 | + </div> |
| 79 | + </el-scrollbar> |
| 80 | + </div> |
| 81 | + </LayoutContainer> |
| 82 | + |
| 83 | + <template #footer> |
| 84 | + <div class="flex-between"> |
| 85 | + <div class="flex"> |
| 86 | + <el-text type="info" class="color-secondary mr-8" v-if="checkList.length > 0"> |
| 87 | + {{ $t('common.selected') }} {{ checkList.length }} |
| 88 | + </el-text> |
| 89 | + <el-button link type="primary" v-if="checkList.length > 0" @click="clearCheck"> |
| 90 | + {{ $t('common.clear') }} |
| 91 | + </el-button> |
| 92 | + </div> |
| 93 | + <span> |
| 94 | + <el-button @click.prevent="dialogVisible = false"> |
| 95 | + {{ $t('common.cancel') }} |
| 96 | + </el-button> |
| 97 | + <el-button type="primary" @click="submitHandle"> |
| 98 | + {{ $t('common.add') }} |
| 99 | + </el-button> |
| 100 | + </span> |
| 101 | + </div> |
41 | 102 | </template> |
42 | 103 | </el-dialog> |
43 | 104 | </template> |
44 | 105 | <script setup lang="ts"> |
45 | | -import {ref, watch} from 'vue' |
| 106 | +import { computed, ref, watch } from 'vue' |
| 107 | +import { useRoute } from 'vue-router' |
| 108 | +import useStore from '@/stores' |
| 109 | +import { loadSharedApi } from '@/utils/dynamics-api/shared-api' |
| 110 | +import { uniqueArray } from '@/utils/array' |
| 111 | +import { resetUrl } from '@/utils/common' |
| 112 | +const route = useRoute() |
46 | 113 |
|
47 | 114 | const emit = defineEmits(['refresh']) |
48 | | -
|
49 | | -const paramFormRef = ref() |
50 | | -
|
51 | | -const form = ref<any>({ |
52 | | - tool_ids: [], |
| 115 | +const { folder, user } = useStore() |
| 116 | +const apiType = computed(() => { |
| 117 | + if (route.path.includes('shared')) { |
| 118 | + return 'systemShare' |
| 119 | + } else if (route.path.includes('resource-management')) { |
| 120 | + return 'systemManage' |
| 121 | + } else { |
| 122 | + return 'workspace' |
| 123 | + } |
53 | 124 | }) |
54 | 125 |
|
55 | | -const toolSelectOptions = ref<any[]>([]) |
56 | | -
|
57 | 126 | const dialogVisible = ref<boolean>(false) |
58 | | -
|
59 | | -const loading = ref(false) |
| 127 | +const checkList = ref<Array<string>>([]) |
| 128 | +const searchValue = ref('') |
| 129 | +const searchData = ref<Array<any>>([]) |
| 130 | +const toolList = ref<Array<any>>([]) |
| 131 | +const apiLoading = ref(false) |
60 | 132 |
|
61 | 133 | watch(dialogVisible, (bool) => { |
62 | 134 | if (!bool) { |
63 | | - form.value = { |
64 | | - tool_ids: [], |
65 | | - } |
| 135 | + checkList.value = [] |
| 136 | + searchValue.value = '' |
| 137 | + searchData.value = [] |
| 138 | + toolList.value = [] |
| 139 | + } |
| 140 | +}) |
| 141 | +
|
| 142 | +watch(searchValue, (val) => { |
| 143 | + if (val) { |
| 144 | + searchData.value = toolList.value.filter((v) => v.name.includes(val)) |
| 145 | + } else { |
| 146 | + searchData.value = toolList.value |
66 | 147 | } |
67 | 148 | }) |
68 | 149 |
|
| 150 | +function changeHandle() {} |
| 151 | +function clearCheck() { |
| 152 | + checkList.value = [] |
| 153 | +} |
69 | 154 |
|
70 | | -const open = (data: any, selectOptions: any) => { |
71 | | - form.value = {...form.value, ...data} |
| 155 | +const open = (checked: any) => { |
| 156 | + checkList.value = checked || [] |
| 157 | + getFolder() |
72 | 158 | dialogVisible.value = true |
73 | | - toolSelectOptions.value = selectOptions |
74 | 159 | } |
75 | 160 |
|
76 | | -const submit = () => { |
77 | | - paramFormRef.value.validate().then((valid: any) => { |
78 | | - if (valid) { |
79 | | - emit('refresh', form.value) |
80 | | - dialogVisible.value = false |
81 | | - } |
| 161 | +const submitHandle = () => { |
| 162 | + emit('refresh', { |
| 163 | + tool_ids: checkList.value, |
82 | 164 | }) |
| 165 | + dialogVisible.value = false |
| 166 | +} |
| 167 | +
|
| 168 | +const refresh = () => { |
| 169 | + searchValue.value = '' |
| 170 | + toolList.value = [] |
| 171 | + getList() |
83 | 172 | } |
84 | 173 |
|
| 174 | +const folderList = ref<any[]>([]) |
| 175 | +const currentFolder = ref<any>({}) |
| 176 | +const folderLoading = ref(false) |
| 177 | +// 文件 |
| 178 | +function folderClickHandle(row: any) { |
| 179 | + if (row.id === currentFolder.value?.id) { |
| 180 | + return |
| 181 | + } |
| 182 | + currentFolder.value = row |
| 183 | + getList() |
| 184 | +} |
85 | 185 |
|
| 186 | +function getFolder() { |
| 187 | + const params = {} |
| 188 | + folder.asyncGetFolder('TOOL', params, folderLoading).then((res: any) => { |
| 189 | + folderList.value = res.data |
| 190 | + currentFolder.value = res.data?.[0] || {} |
| 191 | + getList() |
| 192 | + }) |
| 193 | +} |
86 | 194 |
|
87 | | -defineExpose({open}) |
| 195 | +function getList() { |
| 196 | + const folder_id = currentFolder.value?.id || user.getWorkspaceId() |
| 197 | + loadSharedApi({ |
| 198 | + type: 'tool', |
| 199 | + systemType: apiType.value, |
| 200 | + }) |
| 201 | + .getToolList({ folder_id }, apiLoading) |
| 202 | + .then((res: any) => { |
| 203 | + toolList.value = uniqueArray([...toolList.value, ...res.data.tools], 'id') |
| 204 | + searchData.value = res.data.tools |
| 205 | + }) |
| 206 | +} |
| 207 | +
|
| 208 | +defineExpose({ open }) |
88 | 209 | </script> |
89 | | -<style lang="scss" scoped></style> |
| 210 | +<style lang="scss"> |
| 211 | +.addTool-dialog { |
| 212 | + padding: 0; |
| 213 | + .el-dialog__header { |
| 214 | + padding: 12px 20px 4px 24px; |
| 215 | + border-bottom: 1px solid var(--el-border-color-light); |
| 216 | + } |
| 217 | + .el-dialog__footer { |
| 218 | + padding: 12px 24px 12px 24px; |
| 219 | + border-top: 1px solid var(--el-border-color-light); |
| 220 | + } |
| 221 | +
|
| 222 | + .el-dialog__headerbtn { |
| 223 | + top: 2px; |
| 224 | + right: 6px; |
| 225 | + } |
| 226 | +} |
| 227 | +</style> |
0 commit comments