Skip to content

Commit c3ecddc

Browse files
committed
refactor: dropdownMenu
1 parent 2b74b84 commit c3ecddc

File tree

2 files changed

+142
-239
lines changed

2 files changed

+142
-239
lines changed
Lines changed: 83 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<template>
22
<div v-show="show" class="workflow-dropdown-menu border border-r-6 white-bg">
33
<el-tabs v-model="activeName" class="workflow-dropdown-tabs">
4-
<div style="display: flex; width: 100%; justify-content: center" class="mb-12">
5-
<el-input
6-
v-model="search_text"
7-
class="mr-12 ml-12"
8-
:placeholder="$t('views.applicationWorkflow.searchBar.placeholder')"
9-
>
4+
<div v-show="activeName === 'base'" style="display: flex; width: 100%; justify-content: center" class="mb-12 mt-12">
5+
<el-input v-model="search_text" class="mr-12 ml-12"
6+
:placeholder="$t('views.applicationWorkflow.searchBar.placeholder')">
107
<template #suffix>
11-
<el-icon class="el-input__icon"><search /></el-icon>
8+
<el-icon class="el-input__icon">
9+
<search />
10+
</el-icon>
1211
</template>
1312
</el-input>
1413
</div>
@@ -19,37 +18,25 @@
1918
<template v-for="(node, index) in filter_menu_nodes" :key="index">
2019
<el-text type="info" size="small" class="color-secondary ml-12">{{
2120
node.label
22-
}}</el-text>
23-
<div class="flex-wrap mt-8">
21+
}}</el-text>
22+
<div class="flex-wrap" style="gap: 12px; padding: 12px;">
2423
<template v-for="(item, index) in node.list" :key="index">
25-
<el-popover placement="right" :width="280">
24+
<el-popover placement="right" :width="280" :show-after="500">
2625
<template #reference>
27-
<div
28-
class="list-item flex align-center border border-r-6 mb-12 p-8-12 cursor ml-12"
29-
style="width: 39%"
30-
@click.stop="clickNodes(item)"
31-
@mousedown.stop="onmousedown(item)"
32-
>
33-
<component
34-
:is="iconComponent(`${item.type}-icon`)"
35-
class="mr-8"
36-
:size="32"
37-
/>
26+
<div class="list-item flex align-center border border-r-6 p-8-12 cursor"
27+
style="width: calc(50% - 6px)" @click.stop="clickNodes(item)" @mousedown.stop="onmousedown(item)">
28+
<component :is="iconComponent(`${item.type}-icon`)" class="mr-8" :size="32" />
3829
<div class="lighter">{{ item.label }}</div>
3930
</div>
4031
</template>
4132
<template #default>
4233
<div class="flex align-center mb-8">
43-
<component
44-
:is="iconComponent(`${item.type}-icon`)"
45-
class="mr-8"
46-
:size="32"
47-
/>
34+
<component :is="iconComponent(`${item.type}-icon`)" class="mr-8" :size="32" />
4835
<div class="lighter color-text-primary">{{ item.label }}</div>
4936
</div>
5037
<el-text type="info" size="small" class="color-secondary lighter">{{
5138
item.text
52-
}}</el-text>
39+
}}</el-text>
5340
</template>
5441
</el-popover>
5542
</template>
@@ -61,68 +48,34 @@
6148
</div>
6249
</el-scrollbar>
6350
</el-tab-pane>
51+
<!-- 工具 -->
6452
<el-tab-pane :label="$t('views.tool.title')" name="tool">
65-
<el-scrollbar height="400">
66-
<!-- 共享工具 -->
67-
<el-collapse expand-icon-position="left" v-if="user.isEE()">
68-
<el-collapse-item name="shared" :icon="CaretRight">
69-
<template #title>
70-
<div class="flex align-center">
71-
<AppIcon
72-
iconName="app-shared-active"
73-
style="font-size: 20px"
74-
class="color-primary"
75-
></AppIcon>
76-
<span class="ml-8 lighter">{{ $t('views.shared.shared_tool') }}</span>
77-
</div>
78-
</template>
79-
<NodeContent
80-
:list="sharedToolList"
81-
@clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
82-
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')"
83-
/>
84-
</el-collapse-item>
85-
</el-collapse>
86-
87-
<el-tree
88-
:data="toolTreeData"
89-
node-key="id"
90-
:props="{ children: 'children', isLeaf: 'isLeaf', class: getNodeClass }"
91-
lazy
92-
:load="loadNode"
93-
>
94-
<template #default="{ data, node }">
95-
<NodeContent
96-
v-if="!data._fake"
97-
:data="data"
98-
:node="node"
99-
@clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
100-
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')"
101-
/>
102-
</template>
103-
</el-tree>
104-
</el-scrollbar>
53+
<LayoutContainer>
54+
<template #left>
55+
<folder-tree :source="SourceTypeEnum.TOOL" :data="toolTreeData" :currentNodeKey="folder.currentFolder?.id"
56+
@handleNodeClick="folderClickHandle" :shareTitle="$t('views.shared.shared_tool')"
57+
:showShared="user.isEE()" class="p-8" :canOperation="false" />
58+
</template>
59+
<el-scrollbar height="450">
60+
<NodeContent :list="toolList" @clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
61+
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')" />
62+
</el-scrollbar>
63+
</LayoutContainer>
10564
</el-tab-pane>
65+
<!-- 应用 -->
10666
<el-tab-pane :label="$t('views.application.title')" name="application">
107-
<el-scrollbar height="400">
108-
<el-tree
109-
:data="applicationTreeData"
110-
node-key="id"
111-
:props="{ children: 'children', isLeaf: 'isLeaf', class: getNodeClass }"
112-
lazy
113-
:load="loadNode"
114-
>
115-
<template #default="{ data, node }">
116-
<NodeContent
117-
v-if="!data._fake"
118-
:data="data"
119-
:node="node"
120-
@clickNodes="(val: any) => clickNodes(applicationNode, val, 'application')"
121-
@onmousedown="(val: any) => onmousedown(applicationNode, val, 'application')"
122-
/>
123-
</template>
124-
</el-tree>
125-
</el-scrollbar>
67+
<LayoutContainer>
68+
<template #left>
69+
<folder-tree :source="SourceTypeEnum.APPLICATION" :data="applicationTreeData"
70+
:currentNodeKey="folder.currentFolder?.id" @handleNodeClick="folderClickHandle" class="p-8"
71+
:canOperation="false" />
72+
</template>
73+
<el-scrollbar height="450">
74+
<NodeContent :list="applicationList"
75+
@clickNodes="(val: any) => clickNodes(applicationNode, val, 'application')"
76+
@onmousedown="(val: any) => onmousedown(applicationNode, val, 'application')" />
77+
</el-scrollbar>
78+
</LayoutContainer>
12679
</el-tab-pane>
12780
</el-tabs>
12881
</div>
@@ -176,7 +129,6 @@ const filter_menu_nodes = computed(() => {
176129
}, [])
177130
})
178131
function clickNodes(item: any, data?: any, type?: string) {
179-
console.log('clickNodes', item, data, type)
180132
if (data) {
181133
item['properties']['stepName'] = data.name
182134
if (type == 'tool') {
@@ -237,52 +189,16 @@ function onmousedown(item: any, data?: any, type?: string) {
237189
emit('onmousedown', item)
238190
}
239191
240-
function getNodeClass(data: any) {
241-
return data._fake ? 'tree-node--hidden' : ''
242-
}
243-
244-
const loadNode = async (node: any, resolve: (children: any[]) => void) => {
245-
if (node.level === 0) return resolve([])
246-
try {
247-
let folders
248-
if (activeName.value === 'tool') {
249-
const res = await ToolApi.getToolList({ folder_id: node.data.id })
250-
node.data.cardList = res.data.tools
251-
folders = res.data?.folders
252-
} else {
253-
const res = await ApplicationApi.getAllApplication({ folder_id: node.data.id })
254-
node.data.cardList = res.data.filter((item) => item.resource_type === 'application')
255-
folders = res.data.filter((item) => item.resource_type === 'folder')
256-
}
257-
const children = folders.map((f) => ({
258-
...f,
259-
children: [],
260-
isLeaf: false,
261-
}))
262-
263-
if (folders.length === 0 && node.data.cardList.length > 0) {
264-
// 插一个假子节点,确保树节点是“可折叠”的
265-
children.push({
266-
id: `__placeholder__${node.data.id}`,
267-
isLeaf: true,
268-
_fake: true,
269-
})
270-
}
271-
272-
resolve(children)
273-
} catch (e: any) {
274-
resolve([]) // 失败也要 resolve,否则树会卡住
275-
}
276-
}
277-
278192
const toolTreeData = ref<any[]>([])
279-
function getToolFolder() {
280-
folder.asyncGetFolder(SourceTypeEnum.TOOL, {}, loading).then((res: any) => {
281-
toolTreeData.value = res.data
282-
})
193+
const toolList = ref<any[]>([])
194+
const sharedToolList = ref<any[]>([])
195+
196+
async function getToolFolder() {
197+
const res: any = await folder.asyncGetFolder(SourceTypeEnum.TOOL, {}, loading)
198+
toolTreeData.value = res.data
199+
folder.setCurrentFolder(res.data?.[0] || {})
283200
}
284201
285-
const sharedToolList = ref<any[]>([])
286202
async function getShareTool() {
287203
try {
288204
const res = await sharedWorkspaceApi.getToolList(loading)
@@ -292,19 +208,47 @@ async function getShareTool() {
292208
}
293209
}
294210
211+
async function getToolList() {
212+
if (folder.currentFolder.id === "share") {
213+
toolList.value = sharedToolList.value
214+
} else {
215+
const res = await ToolApi.getToolList({ folder_id: folder.currentFolder?.id || user.getWorkspaceId() })
216+
toolList.value = res.data.tools
217+
}
218+
}
219+
295220
const applicationTreeData = ref<any[]>([])
221+
const applicationList = ref<any[]>([])
222+
296223
function getApplicationFolder() {
297224
folder.asyncGetFolder(SourceTypeEnum.APPLICATION, {}, loading).then((res: any) => {
298225
applicationTreeData.value = res.data
226+
folder.setCurrentFolder(res.data?.[0] || {})
299227
})
300228
}
301229
302-
onMounted(() => {
230+
async function getApplicationList() {
231+
const res = await ApplicationApi.getAllApplication({ folder_id: folder.currentFolder?.id || user.getWorkspaceId() })
232+
applicationList.value = res.data.filter((item) => item.resource_type === 'application')
233+
}
234+
235+
function folderClickHandle(row: any) {
236+
folder.setCurrentFolder(row)
237+
if (activeName.value === 'tool') {
238+
getToolList();
239+
} else {
240+
getApplicationList()
241+
}
242+
}
243+
244+
onMounted(async () => {
303245
if (user.isEE()) {
304-
getShareTool()
246+
await getShareTool()
305247
}
306-
getToolFolder()
248+
await getToolFolder()
249+
getToolList()
307250
getApplicationFolder()
251+
getApplicationList()
308252
})
309253
</script>
310254
<style lang="scss" scoped>
@@ -319,7 +263,7 @@ onMounted(() => {
319263
top: 49px;
320264
right: 16px;
321265
z-index: 99;
322-
width: 400px;
266+
width: 600px;
323267
box-shadow: 0px 4px 8px 0px var(--app-text-color-light-1);
324268
padding-bottom: 8px;
325269
@@ -333,44 +277,18 @@ onMounted(() => {
333277
}
334278
335279
.list-item {
280+
box-sizing: border-box;
336281
&:hover {
337282
border-color: var(--el-color-primary);
338283
}
339284
}
340285
341-
:deep(.el-collapse) {
342-
border-top-width: 0;
343-
.el-collapse-item__header {
344-
height: 40px;
345-
gap: 0;
346-
.el-collapse-item__arrow {
347-
font-size: 16px;
348-
color: var(--app-text-color-secondary);
349-
padding: 6px;
350-
}
351-
}
352-
.el-collapse-item__content {
353-
padding: 0 12px 16px 12px;
354-
.list {
355-
margin-top: 0;
356-
transform: none;
357-
}
358-
}
359-
}
360-
361-
:deep(.el-tree-node):focus > .el-tree-node__content {
362-
background: transparent;
363-
}
364-
:deep(.el-tree-node__content) {
365-
height: auto;
366-
align-items: baseline;
367-
&:hover {
368-
background: transparent;
369-
}
286+
:deep(.el-tabs__header) {
287+
margin-bottom: 0;
370288
}
371289
372-
:deep(.tree-node--hidden) {
373-
display: none !important;
290+
:deep(.tree-height) {
291+
height: 400px;
374292
}
375293
}
376294
</style>

0 commit comments

Comments
 (0)