forked from github/dataease
feat:仪表板和仪表板分组允许移动
This commit is contained in:
parent
de717cd026
commit
d10e4b5ca6
@ -115,6 +115,21 @@ public class PanelGroupService {
|
||||
newPanel.setId(panelId);
|
||||
newPanel.setCreateBy(AuthUtils.getUser().getUsername());
|
||||
panelGroupMapper.insertSelective(newPanel);
|
||||
} else if ("move".equals(request.getOptType())) {
|
||||
PanelGroupWithBLOBs panelInfo = panelGroupMapper.selectByPrimaryKey(request.getId());
|
||||
if(panelInfo.getPid().equalsIgnoreCase(request.getPid())){
|
||||
DataEaseException.throwException(Translator.get("i18n_select_diff_folder"));
|
||||
}
|
||||
// 移动校验
|
||||
if (StringUtils.isNotEmpty(request.getName())) {
|
||||
checkPanelName(request.getName(), request.getPid(), PanelConstants.OPT_TYPE_INSERT, request.getId());
|
||||
}
|
||||
PanelGroupWithBLOBs record = new PanelGroupWithBLOBs();
|
||||
record.setName(request.getName());
|
||||
record.setId(request.getId());
|
||||
record.setPid(request.getPid());
|
||||
panelGroupMapper.updateByPrimaryKeySelective(record);
|
||||
|
||||
}else {
|
||||
// 更新
|
||||
if (StringUtils.isNotEmpty(request.getName())) {
|
||||
|
@ -234,6 +234,7 @@ i18n_chart_count=Count*
|
||||
i18n_excel_have_merge_region=Excel has merged region
|
||||
i18n_cron_expression_error=Cron expression error
|
||||
i18n_same_folder_can_not_repeat=Name is already used in the same folder
|
||||
i18n_select_diff_folder= Select Diff Folder
|
||||
i18n_default_panel=Default Dashboard
|
||||
i18n_panel_list=Dashboard
|
||||
i18n_processing_data=Processing data now, Refresh later
|
||||
@ -281,4 +282,4 @@ i18n_check_sql_error=Check incremental SQL exception,
|
||||
i18n_change_task_status_error=Suspension is not allowed. The task status is:
|
||||
i18n_Stopped=END
|
||||
i18n_Exec=Running
|
||||
i18n_no_trigger=The current setting does not trigger task generation.
|
||||
i18n_no_trigger=The current setting does not trigger task generation.
|
||||
|
@ -233,6 +233,7 @@ i18n_chart_count=记录数*
|
||||
i18n_excel_have_merge_region=Excel 存在合并单元格
|
||||
i18n_cron_expression_error=Cron 表达式校验错误
|
||||
i18n_same_folder_can_not_repeat=同一目录下该名称已被使用
|
||||
i18n_select_diff_folder= 请选择不通的目录
|
||||
i18n_default_panel=默认仪表板
|
||||
i18n_panel_list=仪表板
|
||||
i18n_processing_data=正在处理数据,稍后刷新
|
||||
|
@ -236,6 +236,7 @@ i18n_chart_count=記錄數*
|
||||
i18n_excel_have_merge_region=Excel存在合並單元格
|
||||
i18n_cron_expression_error=Cron表達式校驗錯誤
|
||||
i18n_same_folder_can_not_repeat=同一目錄下該名稱已被使用
|
||||
i18n_select_diff_folder= 请选择不通的目录
|
||||
i18n_default_panel=默認儀表板
|
||||
i18n_panel_list=儀表板
|
||||
i18n_processing_data=正在處理數據,稍後刷新
|
||||
@ -283,4 +284,4 @@ i18n_check_sql_error=校驗增量SQL異常,
|
||||
i18n_change_task_status_error=不允許暫停,任務狀態為:
|
||||
i18n_Stopped=執行結束
|
||||
i18n_Exec=運行中
|
||||
i18n_no_trigger=当前设置没有触发任务生成 當前設置沒有觸發任務生成.
|
||||
i18n_no_trigger=当前设置没有触发任务生成 當前設置沒有觸發任務生成.
|
||||
|
77
frontend/src/components/TreeSelector/index.vue
Normal file
77
frontend/src/components/TreeSelector/index.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<el-col style="height: 400px;overflow-y: auto;margin-bottom: 10px;">
|
||||
<el-tree
|
||||
:data="tData"
|
||||
node-key="id"
|
||||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" :class="treeClass(data,node)">
|
||||
<span style="display: flex;flex: 1;width: 0;">
|
||||
<span v-if="data.type === 'scene'">
|
||||
<svg-icon icon-class="scene" class="ds-icon-scene" />
|
||||
</span>
|
||||
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TreeSelector',
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
tData: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currGroup: '',
|
||||
groupForm: {
|
||||
name: '',
|
||||
pid: '0',
|
||||
level: 0,
|
||||
type: 'group',
|
||||
children: [],
|
||||
sort: 'type desc,name asc'
|
||||
},
|
||||
targetGroup: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
nodeClick(data, node) {
|
||||
this.targetGroup = data
|
||||
this.$emit('targetGroup', data)
|
||||
},
|
||||
treeClass(data, node) {
|
||||
if (data.id === this.item.id) {
|
||||
node.visible = false
|
||||
}
|
||||
return 'custom-tree-node'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right:8px;
|
||||
}
|
||||
</style>
|
77
frontend/src/views/chart/components/TreeSelector/index.vue
Normal file
77
frontend/src/views/chart/components/TreeSelector/index.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<el-col style="height: 400px;overflow-y: auto;margin-bottom: 10px;">
|
||||
<el-tree
|
||||
:data="tData"
|
||||
node-key="id"
|
||||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" :class="treeClass(data,node)">
|
||||
<span style="display: flex;flex: 1;width: 0;">
|
||||
<span v-if="data.type === 'scene'">
|
||||
<svg-icon icon-class="scene" class="ds-icon-scene" />
|
||||
</span>
|
||||
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TreeSelector',
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
tData: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currGroup: '',
|
||||
groupForm: {
|
||||
name: '',
|
||||
pid: '0',
|
||||
level: 0,
|
||||
type: 'group',
|
||||
children: [],
|
||||
sort: 'type desc,name asc'
|
||||
},
|
||||
targetGroup: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
nodeClick(data, node) {
|
||||
this.targetGroup = data
|
||||
this.$emit('targetGroup', data)
|
||||
},
|
||||
treeClass(data, node) {
|
||||
if (data.id === this.item.id) {
|
||||
node.visible = false
|
||||
}
|
||||
return 'custom-tree-node'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right:8px;
|
||||
}
|
||||
</style>
|
@ -112,6 +112,9 @@
|
||||
<el-dropdown-item v-if="data.nodeType==='panel'" icon="el-icon-document-copy" :command="beforeClickMore('copy',data,node)">
|
||||
{{ $t('panel.copy') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-right" :command="beforeClickMore('move',data,node)">
|
||||
{{ $t('dataset.move_to') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="data.nodeType==='panel'" icon="el-icon-paperclip" :command="beforeClickMore('link',data,node)">
|
||||
{{ $t('panel.create_public_links') }}
|
||||
</el-dropdown-item>
|
||||
@ -169,6 +172,16 @@
|
||||
<el-dialog v-dialogDrag :title="panelDialogTitle" :visible.sync="editPanel.visible" :show-close="true" width="600px">
|
||||
<edit-panel v-if="editPanel.visible" :edit-panel-out="editPanel" @closeEditPanelDialog="closeEditPanelDialog" @newPanelSave="newPanelSave" />
|
||||
</el-dialog>
|
||||
|
||||
<!--移动-->
|
||||
<el-dialog v-if="moveGroup" v-dialogDrag :title="moveDialogTitle" :visible="moveGroup" :show-close="false" width="30%" class="dialog-css">
|
||||
<tree-selector :item="moveInfo" :t-data="tGroupData" @targetGroup="targetGroup" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button size="mini" @click="closeMoveGroup()">{{ $t('dataset.cancel') }}</el-button>
|
||||
<el-button :disabled="groupMoveConfirmDisabled" type="primary" size="mini" @click="saveMoveGroup(tGroup)">{{ $t('dataset.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</template>
|
||||
@ -179,16 +192,18 @@ import LinkGenerate from '@/views/link/generate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import bus from '@/utils/bus'
|
||||
import EditPanel from './EditPanel'
|
||||
import { addGroup, delGroup, groupTree, defaultTree, findOne } from '@/api/panel/panel'
|
||||
import { addGroup, delGroup, groupTree, defaultTree, findOne, panelSave } from '@/api/panel/panel'
|
||||
import { getPanelAllLinkageInfo } from '@/api/panel/linkage'
|
||||
import { mapState } from 'vuex'
|
||||
import {
|
||||
DEFAULT_COMMON_CANVAS_STYLE_STRING
|
||||
} from '@/views/panel/panel'
|
||||
import TreeSelector from '@/components/TreeSelector'
|
||||
import { post } from '@/api/chart/chart'
|
||||
|
||||
export default {
|
||||
name: 'PanelList',
|
||||
components: { GrantAuth, LinkGenerate, EditPanel },
|
||||
components: { GrantAuth, LinkGenerate, EditPanel, TreeSelector },
|
||||
data() {
|
||||
return {
|
||||
lastActiveNode: null, // 激活的节点 在这个节点下面动态放置子节点
|
||||
@ -273,7 +288,13 @@ export default {
|
||||
mode: [
|
||||
{ required: true, message: this.$t('commons.input_content'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
},
|
||||
moveGroup: false,
|
||||
groupMoveConfirmDisabled: true,
|
||||
moveDialogTitle: '',
|
||||
moveInfo: {},
|
||||
tGroup: {},
|
||||
tGroupData: [] // 所有目录
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -413,8 +434,6 @@ export default {
|
||||
case 'rename':
|
||||
this.showEditPanel(param)
|
||||
break
|
||||
case 'move':
|
||||
break
|
||||
case 'delete':
|
||||
this.delete(param.data)
|
||||
break
|
||||
@ -427,6 +446,9 @@ export default {
|
||||
case 'link':
|
||||
this.link(param.data)
|
||||
break
|
||||
case 'move':
|
||||
this.moveTo(param.data)
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
@ -649,6 +671,45 @@ export default {
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
moveTo(data) {
|
||||
const _this = this
|
||||
this.moveInfo = data
|
||||
this.moveDialogTitle = this.$t('dataset.m1') + (data.name.length > 10 ? (data.name.substr(0, 10) + '...') : data.name) + this.$t('dataset.m2')
|
||||
const queryInfo = JSON.parse(JSON.stringify(this.groupForm))
|
||||
queryInfo['nodeType'] = 'folder'
|
||||
groupTree(queryInfo).then(res => {
|
||||
if (data.nodeType === 'folder') {
|
||||
_this.tGroupData = [
|
||||
{
|
||||
id: 'panel_list',
|
||||
name: _this.$t('panel.panel_list'),
|
||||
label: _this.$t('panel.panel_list'),
|
||||
children: res.data
|
||||
}
|
||||
]
|
||||
// console.log('tGroupData=>' + JSON.stringify(_this.tGroupData))
|
||||
} else {
|
||||
_this.tGroupData = res.data
|
||||
}
|
||||
_this.moveGroup = true
|
||||
})
|
||||
},
|
||||
closeMoveGroup() {
|
||||
this.moveGroup = false
|
||||
this.tGroup = {}
|
||||
},
|
||||
saveMoveGroup() {
|
||||
this.moveInfo.pid = this.tGroup.id
|
||||
this.moveInfo['optType'] = 'move'
|
||||
panelSave(this.moveInfo).then(response => {
|
||||
this.tree(this.groupForm)
|
||||
this.closeMoveGroup()
|
||||
})
|
||||
},
|
||||
targetGroup(val) {
|
||||
this.tGroup = val
|
||||
this.groupMoveConfirmDisabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user