mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: Folder directories support moving or dragging.
This commit is contained in:
parent
6df1e19eaa
commit
1263592221
|
|
@ -3,14 +3,34 @@
|
|||
{{ breadcrumbData[0]?.name }}
|
||||
</h2>
|
||||
<el-breadcrumb separator-icon="ArrowRight" style="line-height: normal" class="mt-4" v-else>
|
||||
<el-breadcrumb-item v-for="(item, index) in breadcrumbData" :key="index">
|
||||
<h5 class="ml-4 ellipsis" v-if="index === breadcrumbData.length - 1" :title="item.name">
|
||||
{{ item.name }}
|
||||
</h5>
|
||||
<el-button v-else link @click="handleClick(item)" :title="item.name">
|
||||
<span class="ellipsis"> {{ item.name }}</span>
|
||||
</el-button>
|
||||
</el-breadcrumb-item>
|
||||
<template v-if="breadcrumbData.length > 3">
|
||||
<el-breadcrumb-item>
|
||||
<el-button link @click="handleClick(breadcrumbData[0])" :title="breadcrumbData[0].name">
|
||||
<span class="ellipsis"> {{ breadcrumbData[0].name }}</span>
|
||||
</el-button>
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>
|
||||
<el-button link @click="handleClick(breadcrumbData[breadcrumbData.length - 2])">
|
||||
<el-icon><MoreFilled /></el-icon>
|
||||
</el-button>
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>
|
||||
<h5 class="ml-4 ellipsis" :title="breadcrumbData[breadcrumbData.length - 1].name">
|
||||
{{ breadcrumbData[breadcrumbData.length - 1].name }}
|
||||
</h5>
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-breadcrumb-item v-for="(item, index) in breadcrumbData" :key="index">
|
||||
<h5 class="ml-4 ellipsis" v-if="index === breadcrumbData.length - 1" :title="item.name">
|
||||
{{ item.name }}
|
||||
</h5>
|
||||
|
||||
<el-button v-else link @click="handleClick(item)" :title="item.name">
|
||||
<span class="ellipsis"> {{ item.name }}</span>
|
||||
</el-button>
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,6 @@
|
|||
ref="treeRef"
|
||||
:source="source"
|
||||
:data="folderList"
|
||||
:treeStyle="{
|
||||
height: 'calc(100vh - 320px)',
|
||||
border: '1px solid #ebeef5',
|
||||
borderRadius: '6px',
|
||||
padding: '8px',
|
||||
}"
|
||||
:default-expanded-keys="[currentNodeKey]"
|
||||
:canOperation="false"
|
||||
class="move-to-dialog-tree"
|
||||
|
|
@ -74,7 +68,7 @@ watch(dialogVisible, (bool) => {
|
|||
|
||||
const isFolder = ref<boolean>(false)
|
||||
|
||||
const open = (data: any, is_folder?:any) => {
|
||||
const open = (data: any, is_folder?: any) => {
|
||||
detail.value = data
|
||||
isFolder.value = is_folder
|
||||
getFolder()
|
||||
|
|
@ -105,17 +99,17 @@ const submitHandle = async () => {
|
|||
}
|
||||
if (isFolder.value) {
|
||||
const folder_obj = {
|
||||
...detail.value,
|
||||
parent_id: selectForderId.value,
|
||||
}
|
||||
folderApi.putFolder(detail.value.id, detail.value.folder_type, folder_obj, loading)
|
||||
...detail.value,
|
||||
parent_id: selectForderId.value,
|
||||
}
|
||||
folderApi
|
||||
.putFolder(detail.value.id, detail.value.folder_type, folder_obj, loading)
|
||||
.then(() => {
|
||||
MsgSuccess(t('common.saveSuccess'))
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
else if (props.source === SourceTypeEnum.KNOWLEDGE) {
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
} else if (props.source === SourceTypeEnum.KNOWLEDGE) {
|
||||
if (detail.value.type === 2) {
|
||||
KnowledgeApi.putLarkKnowledge(detail.value.id, obj, loading).then(() => {
|
||||
MsgSuccess(t('common.saveSuccess'))
|
||||
|
|
@ -155,8 +149,12 @@ defineExpose({ open })
|
|||
padding: 0 !important;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
:deep(.tree-label) {
|
||||
max-width: 100% !important;
|
||||
:deep(.el-scrollbar) {
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
border-radius: 6px;
|
||||
}
|
||||
:deep(.el-tree) {
|
||||
height: calc(100vh - 320px)!important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -5,27 +5,28 @@
|
|||
:placeholder="$t('common.search')"
|
||||
prefix-icon="Search"
|
||||
clearable
|
||||
class="p-8"
|
||||
class="p-16 pb-0"
|
||||
/>
|
||||
|
||||
<div v-if="showShared && hasPermission(EditionConst.IS_EE, 'OR')" class="border-b mb-4">
|
||||
<div
|
||||
@click="handleSharedNodeClick"
|
||||
class="shared-button flex cursor"
|
||||
:class="currentNodeKey === 'share' && 'active'"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-shared-active"
|
||||
style="font-size: 18px"
|
||||
class="color-primary"
|
||||
></AppIcon>
|
||||
<span class="ml-8">{{ shareTitle }}</span>
|
||||
<div class="p-8 pb-0" v-if="showShared && hasPermission(EditionConst.IS_EE, 'OR')">
|
||||
<div class="border-b">
|
||||
<div
|
||||
@click="handleSharedNodeClick"
|
||||
class="shared-button flex cursor border-r-6"
|
||||
:class="currentNodeKey === 'share' && 'active'"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-shared-active"
|
||||
style="font-size: 18px"
|
||||
class="color-primary"
|
||||
></AppIcon>
|
||||
<span class="ml-8">{{ shareTitle }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-scrollbar>
|
||||
<el-tree
|
||||
class="overflow-inherit_node__children"
|
||||
class="folder-tree__main p-8"
|
||||
:class="
|
||||
showShared && hasPermission(EditionConst.IS_EE, 'OR')
|
||||
? 'tree-height-shared'
|
||||
|
|
@ -40,7 +41,7 @@
|
|||
:default-expanded-keys="[currentNodeKey]"
|
||||
:current-node-key="currentNodeKey"
|
||||
highlight-current
|
||||
draggable
|
||||
:draggable="draggable"
|
||||
:allow-drop="allowDrop"
|
||||
:allow-drag="allowDrag"
|
||||
@node-drop="handleDrop"
|
||||
|
|
@ -49,13 +50,12 @@
|
|||
v-bind="$attrs"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="flex-between w-full" @mouseenter.stop="handleMouseEnter(data)">
|
||||
<div class="flex align-center">
|
||||
<AppIcon iconName="app-folder" style="font-size: 20px"></AppIcon>
|
||||
<span class="ml-8 ellipsis tree-label" style="max-width: 110px" :title="node.label">{{
|
||||
i18n_name(node.label)
|
||||
}}</span>
|
||||
</div>
|
||||
<div
|
||||
@mouseenter.stop="handleMouseEnter(data)"
|
||||
class="flex align-center w-full custom-tree-node"
|
||||
>
|
||||
<AppIcon iconName="app-folder" style="font-size: 20px"></AppIcon>
|
||||
<span class="tree-label ml-8" :title="node.label">{{ i18n_name(node.label) }}</span>
|
||||
|
||||
<div
|
||||
v-if="canOperation && MoreFilledPermission(node, data)"
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
v-show="hoverNodeId === data.id"
|
||||
@mouseenter.stop="handleMouseEnter(data)"
|
||||
@mouseleave.stop="handleMouseleave"
|
||||
class="mr-16"
|
||||
class="mr-8 tree-operation-button"
|
||||
>
|
||||
<el-dropdown trigger="click" :teleported="false">
|
||||
<el-button text class="w-full" v-if="MoreFilledPermission(node, data)">
|
||||
|
|
@ -178,6 +178,10 @@ const props = defineProps({
|
|||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
const resourceType = computed(() => {
|
||||
if (props.source === 'APPLICATION') {
|
||||
|
|
@ -399,7 +403,7 @@ onUnmounted(() => {
|
|||
padding-top: 4px;
|
||||
height: calc(100vh - 180px);
|
||||
}
|
||||
:deep(.el-tree) {
|
||||
:deep(.folder-tree__main) {
|
||||
.el-tree-node.is-dragging {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
|
@ -408,11 +412,19 @@ onUnmounted(() => {
|
|||
border: 2px dashed var(--el-color-primary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.custom-tree-node {
|
||||
box-sizing: content-box;
|
||||
width: calc(100% - 27px);
|
||||
}
|
||||
.tree-label {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.el-tree-node__content {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
:deep(.overflow-inherit_node__children) {
|
||||
.el-tree-node__children {
|
||||
overflow: inherit !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@
|
|||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.el-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
// card
|
||||
.el-card {
|
||||
|
|
|
|||
|
|
@ -75,18 +75,16 @@
|
|||
<el-tab-pane :label="$t('views.tool.title')" name="tool">
|
||||
<LayoutContainer>
|
||||
<template #left>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.TOOL"
|
||||
:data="toolTreeData"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
:canOperation="false"
|
||||
:treeStyle="{ height: '400px' }"
|
||||
/>
|
||||
</div>
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.TOOL"
|
||||
:data="toolTreeData"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
:canOperation="false"
|
||||
:treeStyle="{ height: '400px' }"
|
||||
/>
|
||||
</template>
|
||||
<el-scrollbar height="450">
|
||||
<NodeContent
|
||||
|
|
@ -101,16 +99,14 @@
|
|||
<el-tab-pane :label="$t('views.application.title')" name="application">
|
||||
<LayoutContainer>
|
||||
<template #left>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.APPLICATION"
|
||||
:data="applicationTreeData"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:canOperation="false"
|
||||
:treeStyle="{ height: '400px' }"
|
||||
/>
|
||||
</div>
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.APPLICATION"
|
||||
:data="applicationTreeData"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:canOperation="false"
|
||||
:treeStyle="{ height: '400px' }"
|
||||
/>
|
||||
</template>
|
||||
<el-scrollbar height="450">
|
||||
<NodeContent
|
||||
|
|
|
|||
|
|
@ -27,18 +27,16 @@
|
|||
</template>
|
||||
<LayoutContainer class="application-manage">
|
||||
<template #left>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
v-loading="folderLoading"
|
||||
:canOperation="false"
|
||||
showShared
|
||||
:shareTitle="$t('views.shared.shared_knowledge')"
|
||||
:treeStyle="{ height: 'calc(100vh - 240px)' }"
|
||||
/>
|
||||
</div>
|
||||
<folder-tree
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
v-loading="folderLoading"
|
||||
:canOperation="false"
|
||||
showShared
|
||||
:shareTitle="$t('views.shared.shared_knowledge')"
|
||||
:treeStyle="{ height: 'calc(100vh - 240px)' }"
|
||||
/>
|
||||
</template>
|
||||
<div class="layout-bg">
|
||||
<div class="flex-between p-16 ml-8">
|
||||
|
|
|
|||
|
|
@ -23,18 +23,16 @@
|
|||
</template>
|
||||
<LayoutContainer class="application-manage">
|
||||
<template #left>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
v-loading="folderLoading"
|
||||
:canOperation="false"
|
||||
showShared
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:treeStyle="{ height: 'calc(100vh - 240px)' }"
|
||||
/>
|
||||
</div>
|
||||
<folder-tree
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
v-loading="folderLoading"
|
||||
:canOperation="false"
|
||||
showShared
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:treeStyle="{ height: 'calc(100vh - 240px)' }"
|
||||
/>
|
||||
</template>
|
||||
<div class="layout-bg">
|
||||
<div class="flex-between p-16 ml-8">
|
||||
|
|
@ -198,15 +196,17 @@ function getList() {
|
|||
type: 'tool',
|
||||
isShared: folder_id === 'share',
|
||||
systemType: 'workspace',
|
||||
}).getToolList({
|
||||
folder_id: folder_id,
|
||||
tool_type: 'CUSTOM'
|
||||
}).then((res: any) => {
|
||||
toolList.value = res.data?.tools || res.data || []
|
||||
toolList.value = toolList.value?.filter((item: any) => item.is_active)
|
||||
searchData.value = res.data.tools || res.data
|
||||
searchData.value = searchData.value?.filter((item: any) => item.is_active)
|
||||
})
|
||||
.getToolList({
|
||||
folder_id: folder_id,
|
||||
tool_type: 'CUSTOM',
|
||||
})
|
||||
.then((res: any) => {
|
||||
toolList.value = res.data?.tools || res.data || []
|
||||
toolList.value = toolList.value?.filter((item: any) => item.is_active)
|
||||
searchData.value = res.data.tools || res.data
|
||||
searchData.value = searchData.value?.filter((item: any) => item.is_active)
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
<LayoutContainer showCollapse class="application-manage">
|
||||
<template #left>
|
||||
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.application.title') }}</h4>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.APPLICATION"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
@refreshTree="refreshFolder"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.APPLICATION"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
@refreshTree="refreshFolder"
|
||||
:draggable="true"
|
||||
/>
|
||||
</template>
|
||||
<ContentContainer>
|
||||
<template #header>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
<LayoutContainer showCollapse class="knowledge-manage">
|
||||
<template #left>
|
||||
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.knowledge.title') }}</h4>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.KNOWLEDGE"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:shareTitle="$t('views.shared.shared_knowledge')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
@refreshTree="refreshFolder"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.KNOWLEDGE"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
:shareTitle="$t('views.shared.shared_knowledge')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
@refreshTree="refreshFolder"
|
||||
:draggable="true"
|
||||
/>
|
||||
</template>
|
||||
<KnowledgeListContainer @refreshFolder="refreshFolder">
|
||||
<template #header>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
<LayoutContainer showCollapse class="tool-manage">
|
||||
<template #left>
|
||||
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.tool.title') }}</h4>
|
||||
<div class="p-8">
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.TOOL"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
@refreshTree="refreshFolder"
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<folder-tree
|
||||
:source="SourceTypeEnum.TOOL"
|
||||
:data="folderList"
|
||||
:currentNodeKey="folder.currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandle"
|
||||
@refreshTree="refreshFolder"
|
||||
:shareTitle="$t('views.shared.shared_tool')"
|
||||
:showShared="permissionPrecise['is_share']()"
|
||||
:draggable="true"
|
||||
/>
|
||||
</template>
|
||||
<ToolListContainer @refreshFolder="refreshFolder">
|
||||
<template #header>
|
||||
|
|
@ -40,7 +40,7 @@ import { SourceTypeEnum } from '@/enums/common'
|
|||
import permissionMap from '@/permission'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useStore from '@/stores'
|
||||
import bus from "@/bus"
|
||||
import bus from '@/bus'
|
||||
const route = useRoute()
|
||||
const { folder, tool } = useStore()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue