refactor: dropdownMenu
This commit is contained in:
parent
2b74b8415f
commit
c3ecddcd1b
@ -1,14 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-show="show" class="workflow-dropdown-menu border border-r-6 white-bg">
|
<div v-show="show" class="workflow-dropdown-menu border border-r-6 white-bg">
|
||||||
<el-tabs v-model="activeName" class="workflow-dropdown-tabs">
|
<el-tabs v-model="activeName" class="workflow-dropdown-tabs">
|
||||||
<div style="display: flex; width: 100%; justify-content: center" class="mb-12">
|
<div v-show="activeName === 'base'" style="display: flex; width: 100%; justify-content: center" class="mb-12 mt-12">
|
||||||
<el-input
|
<el-input v-model="search_text" class="mr-12 ml-12"
|
||||||
v-model="search_text"
|
:placeholder="$t('views.applicationWorkflow.searchBar.placeholder')">
|
||||||
class="mr-12 ml-12"
|
|
||||||
:placeholder="$t('views.applicationWorkflow.searchBar.placeholder')"
|
|
||||||
>
|
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<el-icon class="el-input__icon"><search /></el-icon>
|
<el-icon class="el-input__icon">
|
||||||
|
<search />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
@ -19,37 +18,25 @@
|
|||||||
<template v-for="(node, index) in filter_menu_nodes" :key="index">
|
<template v-for="(node, index) in filter_menu_nodes" :key="index">
|
||||||
<el-text type="info" size="small" class="color-secondary ml-12">{{
|
<el-text type="info" size="small" class="color-secondary ml-12">{{
|
||||||
node.label
|
node.label
|
||||||
}}</el-text>
|
}}</el-text>
|
||||||
<div class="flex-wrap mt-8">
|
<div class="flex-wrap" style="gap: 12px; padding: 12px;">
|
||||||
<template v-for="(item, index) in node.list" :key="index">
|
<template v-for="(item, index) in node.list" :key="index">
|
||||||
<el-popover placement="right" :width="280">
|
<el-popover placement="right" :width="280" :show-after="500">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div
|
<div class="list-item flex align-center border border-r-6 p-8-12 cursor"
|
||||||
class="list-item flex align-center border border-r-6 mb-12 p-8-12 cursor ml-12"
|
style="width: calc(50% - 6px)" @click.stop="clickNodes(item)" @mousedown.stop="onmousedown(item)">
|
||||||
style="width: 39%"
|
<component :is="iconComponent(`${item.type}-icon`)" class="mr-8" :size="32" />
|
||||||
@click.stop="clickNodes(item)"
|
|
||||||
@mousedown.stop="onmousedown(item)"
|
|
||||||
>
|
|
||||||
<component
|
|
||||||
:is="iconComponent(`${item.type}-icon`)"
|
|
||||||
class="mr-8"
|
|
||||||
:size="32"
|
|
||||||
/>
|
|
||||||
<div class="lighter">{{ item.label }}</div>
|
<div class="lighter">{{ item.label }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex align-center mb-8">
|
<div class="flex align-center mb-8">
|
||||||
<component
|
<component :is="iconComponent(`${item.type}-icon`)" class="mr-8" :size="32" />
|
||||||
:is="iconComponent(`${item.type}-icon`)"
|
|
||||||
class="mr-8"
|
|
||||||
:size="32"
|
|
||||||
/>
|
|
||||||
<div class="lighter color-text-primary">{{ item.label }}</div>
|
<div class="lighter color-text-primary">{{ item.label }}</div>
|
||||||
</div>
|
</div>
|
||||||
<el-text type="info" size="small" class="color-secondary lighter">{{
|
<el-text type="info" size="small" class="color-secondary lighter">{{
|
||||||
item.text
|
item.text
|
||||||
}}</el-text>
|
}}</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
@ -61,68 +48,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<!-- 工具 -->
|
||||||
<el-tab-pane :label="$t('views.tool.title')" name="tool">
|
<el-tab-pane :label="$t('views.tool.title')" name="tool">
|
||||||
<el-scrollbar height="400">
|
<LayoutContainer>
|
||||||
<!-- 共享工具 -->
|
<template #left>
|
||||||
<el-collapse expand-icon-position="left" v-if="user.isEE()">
|
<folder-tree :source="SourceTypeEnum.TOOL" :data="toolTreeData" :currentNodeKey="folder.currentFolder?.id"
|
||||||
<el-collapse-item name="shared" :icon="CaretRight">
|
@handleNodeClick="folderClickHandle" :shareTitle="$t('views.shared.shared_tool')"
|
||||||
<template #title>
|
:showShared="user.isEE()" class="p-8" :canOperation="false" />
|
||||||
<div class="flex align-center">
|
</template>
|
||||||
<AppIcon
|
<el-scrollbar height="450">
|
||||||
iconName="app-shared-active"
|
<NodeContent :list="toolList" @clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
|
||||||
style="font-size: 20px"
|
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')" />
|
||||||
class="color-primary"
|
</el-scrollbar>
|
||||||
></AppIcon>
|
</LayoutContainer>
|
||||||
<span class="ml-8 lighter">{{ $t('views.shared.shared_tool') }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<NodeContent
|
|
||||||
:list="sharedToolList"
|
|
||||||
@clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
|
|
||||||
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')"
|
|
||||||
/>
|
|
||||||
</el-collapse-item>
|
|
||||||
</el-collapse>
|
|
||||||
|
|
||||||
<el-tree
|
|
||||||
:data="toolTreeData"
|
|
||||||
node-key="id"
|
|
||||||
:props="{ children: 'children', isLeaf: 'isLeaf', class: getNodeClass }"
|
|
||||||
lazy
|
|
||||||
:load="loadNode"
|
|
||||||
>
|
|
||||||
<template #default="{ data, node }">
|
|
||||||
<NodeContent
|
|
||||||
v-if="!data._fake"
|
|
||||||
:data="data"
|
|
||||||
:node="node"
|
|
||||||
@clickNodes="(val: any) => clickNodes(toolLibNode, val, 'tool')"
|
|
||||||
@onmousedown="(val: any) => onmousedown(toolLibNode, val, 'tool')"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</el-tree>
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<!-- 应用 -->
|
||||||
<el-tab-pane :label="$t('views.application.title')" name="application">
|
<el-tab-pane :label="$t('views.application.title')" name="application">
|
||||||
<el-scrollbar height="400">
|
<LayoutContainer>
|
||||||
<el-tree
|
<template #left>
|
||||||
:data="applicationTreeData"
|
<folder-tree :source="SourceTypeEnum.APPLICATION" :data="applicationTreeData"
|
||||||
node-key="id"
|
:currentNodeKey="folder.currentFolder?.id" @handleNodeClick="folderClickHandle" class="p-8"
|
||||||
:props="{ children: 'children', isLeaf: 'isLeaf', class: getNodeClass }"
|
:canOperation="false" />
|
||||||
lazy
|
</template>
|
||||||
:load="loadNode"
|
<el-scrollbar height="450">
|
||||||
>
|
<NodeContent :list="applicationList"
|
||||||
<template #default="{ data, node }">
|
@clickNodes="(val: any) => clickNodes(applicationNode, val, 'application')"
|
||||||
<NodeContent
|
@onmousedown="(val: any) => onmousedown(applicationNode, val, 'application')" />
|
||||||
v-if="!data._fake"
|
</el-scrollbar>
|
||||||
:data="data"
|
</LayoutContainer>
|
||||||
:node="node"
|
|
||||||
@clickNodes="(val: any) => clickNodes(applicationNode, val, 'application')"
|
|
||||||
@onmousedown="(val: any) => onmousedown(applicationNode, val, 'application')"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</el-tree>
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
@ -176,7 +129,6 @@ const filter_menu_nodes = computed(() => {
|
|||||||
}, [])
|
}, [])
|
||||||
})
|
})
|
||||||
function clickNodes(item: any, data?: any, type?: string) {
|
function clickNodes(item: any, data?: any, type?: string) {
|
||||||
console.log('clickNodes', item, data, type)
|
|
||||||
if (data) {
|
if (data) {
|
||||||
item['properties']['stepName'] = data.name
|
item['properties']['stepName'] = data.name
|
||||||
if (type == 'tool') {
|
if (type == 'tool') {
|
||||||
@ -237,52 +189,16 @@ function onmousedown(item: any, data?: any, type?: string) {
|
|||||||
emit('onmousedown', item)
|
emit('onmousedown', item)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNodeClass(data: any) {
|
|
||||||
return data._fake ? 'tree-node--hidden' : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadNode = async (node: any, resolve: (children: any[]) => void) => {
|
|
||||||
if (node.level === 0) return resolve([])
|
|
||||||
try {
|
|
||||||
let folders
|
|
||||||
if (activeName.value === 'tool') {
|
|
||||||
const res = await ToolApi.getToolList({ folder_id: node.data.id })
|
|
||||||
node.data.cardList = res.data.tools
|
|
||||||
folders = res.data?.folders
|
|
||||||
} else {
|
|
||||||
const res = await ApplicationApi.getAllApplication({ folder_id: node.data.id })
|
|
||||||
node.data.cardList = res.data.filter((item) => item.resource_type === 'application')
|
|
||||||
folders = res.data.filter((item) => item.resource_type === 'folder')
|
|
||||||
}
|
|
||||||
const children = folders.map((f) => ({
|
|
||||||
...f,
|
|
||||||
children: [],
|
|
||||||
isLeaf: false,
|
|
||||||
}))
|
|
||||||
|
|
||||||
if (folders.length === 0 && node.data.cardList.length > 0) {
|
|
||||||
// 插一个假子节点,确保树节点是“可折叠”的
|
|
||||||
children.push({
|
|
||||||
id: `__placeholder__${node.data.id}`,
|
|
||||||
isLeaf: true,
|
|
||||||
_fake: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(children)
|
|
||||||
} catch (e: any) {
|
|
||||||
resolve([]) // 失败也要 resolve,否则树会卡住
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const toolTreeData = ref<any[]>([])
|
const toolTreeData = ref<any[]>([])
|
||||||
function getToolFolder() {
|
const toolList = ref<any[]>([])
|
||||||
folder.asyncGetFolder(SourceTypeEnum.TOOL, {}, loading).then((res: any) => {
|
const sharedToolList = ref<any[]>([])
|
||||||
toolTreeData.value = res.data
|
|
||||||
})
|
async function getToolFolder() {
|
||||||
|
const res: any = await folder.asyncGetFolder(SourceTypeEnum.TOOL, {}, loading)
|
||||||
|
toolTreeData.value = res.data
|
||||||
|
folder.setCurrentFolder(res.data?.[0] || {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sharedToolList = ref<any[]>([])
|
|
||||||
async function getShareTool() {
|
async function getShareTool() {
|
||||||
try {
|
try {
|
||||||
const res = await sharedWorkspaceApi.getToolList(loading)
|
const res = await sharedWorkspaceApi.getToolList(loading)
|
||||||
@ -292,19 +208,47 @@ async function getShareTool() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getToolList() {
|
||||||
|
if (folder.currentFolder.id === "share") {
|
||||||
|
toolList.value = sharedToolList.value
|
||||||
|
} else {
|
||||||
|
const res = await ToolApi.getToolList({ folder_id: folder.currentFolder?.id || user.getWorkspaceId() })
|
||||||
|
toolList.value = res.data.tools
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const applicationTreeData = ref<any[]>([])
|
const applicationTreeData = ref<any[]>([])
|
||||||
|
const applicationList = ref<any[]>([])
|
||||||
|
|
||||||
function getApplicationFolder() {
|
function getApplicationFolder() {
|
||||||
folder.asyncGetFolder(SourceTypeEnum.APPLICATION, {}, loading).then((res: any) => {
|
folder.asyncGetFolder(SourceTypeEnum.APPLICATION, {}, loading).then((res: any) => {
|
||||||
applicationTreeData.value = res.data
|
applicationTreeData.value = res.data
|
||||||
|
folder.setCurrentFolder(res.data?.[0] || {})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
async function getApplicationList() {
|
||||||
if (user.isEE()) {
|
const res = await ApplicationApi.getAllApplication({ folder_id: folder.currentFolder?.id || user.getWorkspaceId() })
|
||||||
getShareTool()
|
applicationList.value = res.data.filter((item) => item.resource_type === 'application')
|
||||||
|
}
|
||||||
|
|
||||||
|
function folderClickHandle(row: any) {
|
||||||
|
folder.setCurrentFolder(row)
|
||||||
|
if (activeName.value === 'tool') {
|
||||||
|
getToolList();
|
||||||
|
} else {
|
||||||
|
getApplicationList()
|
||||||
}
|
}
|
||||||
getToolFolder()
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
if (user.isEE()) {
|
||||||
|
await getShareTool()
|
||||||
|
}
|
||||||
|
await getToolFolder()
|
||||||
|
getToolList()
|
||||||
getApplicationFolder()
|
getApplicationFolder()
|
||||||
|
getApplicationList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -319,7 +263,7 @@ onMounted(() => {
|
|||||||
top: 49px;
|
top: 49px;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
width: 400px;
|
width: 600px;
|
||||||
box-shadow: 0px 4px 8px 0px var(--app-text-color-light-1);
|
box-shadow: 0px 4px 8px 0px var(--app-text-color-light-1);
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
|
||||||
@ -333,44 +277,18 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list-item {
|
.list-item {
|
||||||
|
box-sizing: border-box;
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--el-color-primary);
|
border-color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-collapse) {
|
:deep(.el-tabs__header) {
|
||||||
border-top-width: 0;
|
margin-bottom: 0;
|
||||||
.el-collapse-item__header {
|
|
||||||
height: 40px;
|
|
||||||
gap: 0;
|
|
||||||
.el-collapse-item__arrow {
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--app-text-color-secondary);
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-collapse-item__content {
|
|
||||||
padding: 0 12px 16px 12px;
|
|
||||||
.list {
|
|
||||||
margin-top: 0;
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-tree-node):focus > .el-tree-node__content {
|
:deep(.tree-height) {
|
||||||
background: transparent;
|
height: 400px;
|
||||||
}
|
|
||||||
:deep(.el-tree-node__content) {
|
|
||||||
height: auto;
|
|
||||||
align-items: baseline;
|
|
||||||
&:hover {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.tree-node--hidden) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,97 +1,78 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<el-input v-model.trim="filterText" :placeholder="$t('common.search')" prefix-icon="Search" clearable
|
||||||
<div v-if="data" class="flex align-center">
|
style="padding: 12px 12px 0 12px;" />
|
||||||
<AppIcon iconName="app-folder" style="font-size: 20px"></AppIcon>
|
<div class="list flex-wrap">
|
||||||
<span
|
<template v-if="filterList.length">
|
||||||
class="ml-8 ellipsis color-text-primary lighter"
|
<el-popover v-for="item in filterList" :key="item.id" placement="right" :width="280" :show-after="500">
|
||||||
style="max-width: 110px"
|
<template #reference>
|
||||||
:title="data.name"
|
<div class="list-item flex align-center border border-r-6 p-8-12 cursor" style="width: calc(50% - 6px)"
|
||||||
>
|
@click.stop="emit('clickNodes', item)" @mousedown.stop="emit('onmousedown', item)">
|
||||||
{{ data.name }}
|
<LogoIcon v-if="item.resource_type === 'application'" height="32px" />
|
||||||
</span>
|
<el-avatar v-else-if="isAppIcon(item?.icon)" shape="square" :size="32" style="background: none">
|
||||||
</div>
|
<img :src="resetUrl(item?.icon)" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
||||||
|
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<span class="ml-8 ellipsis" :title="item.name">{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<transition name="el-fade-in-linear">
|
<template #default>
|
||||||
<div
|
<div class="flex-between">
|
||||||
v-if="props.list?.length || (props.node?.expanded && toolList.length)"
|
<div class="flex align-center">
|
||||||
class="list border-r-4 layout-bg flex-wrap"
|
|
||||||
@click.stop
|
|
||||||
>
|
|
||||||
<el-popover v-for="item in toolList" :key="item.id" placement="right" :width="280">
|
|
||||||
<template #reference>
|
|
||||||
<div
|
|
||||||
class="list-item flex align-center border border-r-6 p-8-12 cursor"
|
|
||||||
style="width: 39%"
|
|
||||||
@click.stop="emit('clickNodes', item)"
|
|
||||||
@mousedown.stop="emit('onmousedown', item)"
|
|
||||||
>
|
|
||||||
<LogoIcon v-if="item.resource_type === 'application'" height="32px" />
|
<LogoIcon v-if="item.resource_type === 'application'" height="32px" />
|
||||||
<el-avatar
|
<el-avatar v-else-if="isAppIcon(item?.icon)" shape="square" :size="32" style="background: none">
|
||||||
v-else-if="isAppIcon(item?.icon)"
|
|
||||||
shape="square"
|
|
||||||
:size="32"
|
|
||||||
style="background: none"
|
|
||||||
>
|
|
||||||
<img :src="resetUrl(item?.icon)" alt="" />
|
<img :src="resetUrl(item?.icon)" alt="" />
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
||||||
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<span class="ml-8 ellipsis" :title="item.name">{{ item.name }}</span>
|
<span class="font-medium ml-8 break-all" :title="item.name">{{ item.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div v-if="item.type" class="status-tag" style="margin-left: auto">
|
||||||
|
<el-tag type="warning" v-if="isWorkFlow(item.type)" style="height: 22px">
|
||||||
<template #default>
|
{{ $t('views.application.workflow') }}
|
||||||
<div class="flex-between">
|
</el-tag>
|
||||||
<div class="flex align-center">
|
<el-tag class="blue-tag" v-else style="height: 22px">
|
||||||
<LogoIcon v-if="item.resource_type === 'application'" height="32px" />
|
{{ $t('views.application.simple') }}
|
||||||
<el-avatar
|
</el-tag>
|
||||||
v-else-if="isAppIcon(item?.icon)"
|
|
||||||
shape="square"
|
|
||||||
:size="32"
|
|
||||||
style="background: none"
|
|
||||||
>
|
|
||||||
<img :src="resetUrl(item?.icon)" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<el-avatar v-else class="avatar-green" shape="square" :size="32">
|
|
||||||
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<span class="medium ml-8 ellipsis" :title="item.name">{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="item.type" class="status-tag" style="margin-left: auto">
|
|
||||||
<el-tag type="warning" v-if="isWorkFlow(item.type)" style="height: 22px">
|
|
||||||
{{ $t('views.application.workflow') }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag class="blue-tag" v-else style="height: 22px">
|
|
||||||
{{ $t('views.application.simple') }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<el-text type="info" size="small" class="mt-4">{{ item.desc }}</el-text>
|
</div>
|
||||||
</template>
|
<el-text type="info" size="small" class="mt-4">{{ item.desc }}</el-text>
|
||||||
</el-popover>
|
</template>
|
||||||
</div>
|
</el-popover>
|
||||||
</transition>
|
</template>
|
||||||
|
<el-empty v-else :description="$t('common.noData')" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { watch, ref } from 'vue'
|
||||||
import { isAppIcon, resetUrl } from '@/utils/common'
|
import { isAppIcon, resetUrl } from '@/utils/common'
|
||||||
import { isWorkFlow } from '@/utils/application'
|
import { isWorkFlow } from '@/utils/application'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data?: any
|
list: any[]
|
||||||
node?: any
|
|
||||||
list?: any[]
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'clickNodes', item: any): void
|
(e: 'clickNodes', item: any): void;
|
||||||
(e: 'onmousedown', item: any): void
|
(e: 'onmousedown', item: any): void;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const toolList = computed(() => props.list ?? props.data?.cardList ?? [])
|
const filterText = ref('')
|
||||||
|
const filterList = ref<any[]>([])
|
||||||
|
function filter(list: any[], filterText: string) {
|
||||||
|
if (!filterText.length) {
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return list.filter((v: any) => v.name.toLowerCase().includes(filterText.toLowerCase()))
|
||||||
|
}
|
||||||
|
|
||||||
|
watch([() => filterText.value, () => props.list], () => {
|
||||||
|
filterList.value = filter(props.list, filterText.value)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -99,15 +80,19 @@ const toolList = computed(() => props.list ?? props.data?.cardList ?? [])
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
margin-top: 12px;
|
box-sizing: border-box;
|
||||||
transform: translate(-16px, 0);
|
|
||||||
|
|
||||||
.list-item {
|
.list-item {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--el-color-primary);
|
border-color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-empty {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user