blob: 8fba1b96ff67e8a9020d47950fbe2206bc11e729 [file] [log] [blame]
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-->
<template>
<div class="data-list-tree">
<div class="data-list-top">
<span>{{ $t('rootPage.dataList') }}</span>
</div>
<div class="data-list-btn">
<el-button @click="newSource">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-add"></use>
</svg>
{{ $t('rootPage.newdatasource') }}
</el-button>
<el-button @click="sqlClick">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-add"></use>
</svg>
{{ $t('rootPage.newQueryWindow') }}
</el-button>
</div>
<!-- <div class="data-list-input">
<el-input size="small" placeholder="" v-model="searchVal">
<template #suffix>
<i @click="searchClick" class="el-icon-search"></i>
</template>
</el-input>
</div> -->
<el-tree
:expand-on-click-node="true"
:default-expanded-keys="treeExpandKey"
v-if="store.state?.userInfo?.userId !== undefined"
ref="treeRef"
highlight-current
node-key="id"
:indent="20"
:props="treeProps"
@node-click="nodeClick"
:load="loadNode"
lazy
:current-node-key="nodekey"
:key="treeKey"
@node-expand="expandNode"
@node-collapse="collapseNode"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<icon-types :data="data" :nodekey="nodekey" />
<span>{{ node.label }}</span>
</span>
</template>
</el-tree>
<NewSource v-if="showDialog" :func="func" :serverId="null" :showDialog="showDialog" :types="types" @close="close()" @successFunc="successFunc(data)" />
<SqlDrawer v-if="showDrawer" :func="funcdata" @coloseDrawer="coloseDrawer"></SqlDrawer>
</div>
</template>
<script>
import { ElTree, ElButton } from 'element-plus';
import { reactive, ref, computed } from 'vue';
import { useStore } from 'vuex';
import IconTypes from './iconTypes.vue';
import axios from '@/util/axios.js';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import NewSource from '../../Source/components/newSource';
import SqlDrawer from '../../SqlSerch/components/sqlDrawer';
export default {
name: 'DataListTree',
props: ['handleNodeClick', 'nodekey', 'func'],
setup(props) {
const treeProps = reactive({
label: 'name',
children: 'zones',
isLeaf: 'leaf',
disabled: 'disabled',
});
const searchVal = ref('');
const treeRef = ref(null);
const treeExpandKey = ref([]);
const store = useStore();
const showDialog = ref(false);
const showDrawer = ref(false);
const types = ref(null);
const treeKey = ref(1);
const funcdata = reactive(props.func);
const router = useRouter();
const { t } = useI18n();
const searchClick = () => {
console.log('jj');
};
const nodeClick = (data, node) => {
props.handleNodeClick(data, node);
};
/**
* 新建数据连接
*/
const newSource = () => {
showDialog.value = true;
types.value = 0;
};
/**
* 关闭或者取消新增/编辑数据连接操作
*/
const close = () => {
showDialog.value = false;
types.value = 0;
};
/**
* 新增或编辑数据源成功回调
*/
const successFunc = () => {
showDialog.value = false;
types.value = 0;
};
const sqlClick = () => {
showDrawer.value = true;
};
const updateTree = (params, clear) => {
if (params) {
let arr = treeExpandKey.value;
if (clear) {
arr = [];
}
arr = arr.concat(params);
treeExpandKey.value = arr;
}
treeKey.value += 1;
};
const coloseDrawer = () => {
showDrawer.value = false;
};
const expandNode = (data) => {
let arr = treeExpandKey.value;
arr.push(data.id);
treeExpandKey.value = arr;
};
const collapseNode = (data) => {
let arr = treeExpandKey.value;
let index = arr.indexOf(data.id);
if (index !== -1) {
arr.splice(index, 1);
}
treeExpandKey.value = arr;
};
const recurseDeviceTree = (data, node) => {
let newDevice = {
id: node.data.id + ':newdevice',
name: computed(() => t(`databasem.newDevice`)),
type: 'newdevice',
leaf: true,
parent: node.data,
connectionid: node.data.connectionid,
storagegroupid: node.data.storagegroupid,
};
let childs = data.map((e) => {
let child = {
parent: node.data,
name: e.name,
id: node.data.id + e.name + 'device',
type: 'device',
// leaf: e.children === null ? true : false,
leaf: false,
rawid: e.name,
storagegroupid: node.data.storagegroupid,
connectionid: node.data.connectionid,
deviceid: e.name,
};
// if (e.children) {
let innerChilds = recurseDeviceTree(e.children || [], { data: child });
child.zones = innerChilds;
// }
return child;
});
childs.unshift(newDevice);
return childs;
};
const loadNode = (node, resolve) => {
if (node?.data?.zones) {
resolve(node.data.zones);
return;
}
if (node.level === 0) {
axios
.get('/servers', { params: { userId: store.state?.userInfo?.userId } })
.then((res) => {
if (res?.code === '0') {
let data = (res.data.aliasList || []).map((e) => {
return {
name: e.alias,
id: e.id + 'connection',
type: 'connection',
rawid: e.id,
connectionid: e.id,
};
});
if (data.length === 0) {
router.push({ name: 'Empty' });
}
if (data.length > 0 && store.state.firstPageLoad) {
// router.push({ name: 'Root' });
props.func.addTab(data[0].id, {}, true);
}
store.commit('setFirstPageLoad', false);
return resolve(data);
} else {
resolve([]);
}
})
.catch(() => {
resolve([]);
});
}
if (node.level === 1) {
axios
.get(`/servers/${node.data.rawid}/storageGroups`, {})
.then((res) => {
let newStorageGroup = {
id: node.data.id + ':newstoragegroup',
name: computed(() => t(`databasem.newStoreGroup`)),
parent: node.data,
type: 'newstorageGroup',
leaf: true,
connectionid: node.data.connectionid,
};
let queryList = {
id: node.data.id + ':querylist',
name: computed(() => t(`databasem.query`)),
parent: node.data,
type: 'querylist',
connectionid: node.data.connectionid,
};
if (res?.code === '0') {
let data = (res.data || []).map((e) => {
return {
parent: node.data,
name: e.groupName,
id: node.data.id + e.groupName + 'storageGroup',
type: 'storageGroup',
rawid: e.groupName,
storagegroupid: e.groupName,
connectionid: node.data.connectionid,
};
});
data.unshift(queryList);
data.unshift(newStorageGroup);
return resolve(data);
} else {
resolve([]);
}
})
.catch(() => {
resolve([]);
});
}
if (node.level === 2 && node.data.type === 'storageGroup') {
let groupName = node.data.rawid;
let serverId = node.data.parent.rawid;
axios
.get(`/servers/${serverId}/storageGroups/${groupName}/devices/tree`, {})
.then((res) => {
if (res?.code === '0') {
if (!res.data) {
let newDevice = {
id: node.data.id + ':newdevice',
name: computed(() => t(`databasem.newDevice`)),
type: 'newdevice',
leaf: true,
parent: node.data,
connectionid: node.data.connectionid,
storagegroupid: node.data.storagegroupid,
};
resolve([newDevice]);
return;
}
if (res.data.name === null) {
let childs = recurseDeviceTree(res.data.children || [], node);
resolve(childs);
} else {
let rootDevice = {
// parent: node.data,
name: res.data.name,
// id: node.data.id + res.data.name + 'device',
// type: 'device',
// leaf: false,
// rawid: res.data.name,
// storagegroupid: node.data.storagegroupid,
// connectionid: node.data.connectionid,
// deviceid: res.data.name,
children: res.data.children,
};
let childs = recurseDeviceTree([rootDevice] || [], node);
node.zones = childs;
resolve(childs);
}
} else {
resolve([]);
}
})
.catch(() => {
resolve([]);
});
}
if (node.level === 2 && node.data.type === 'querylist') {
let serverId = node.data.parent.rawid;
axios
.get(`/servers/${serverId}/query`, {})
.then((res) => {
let newQuery = {
id: node.data.id + ':newquery',
name: computed(() => t(`databasem.newQuery`)),
type: 'newquery',
leaf: true,
parent: node.data,
storagegroupid: node.data.storagegroupid,
connectionid: node.data.connectionid,
};
if (res?.code === '0') {
let data = (res.data || []).map((e) => {
return {
parent: node.data,
name: e.queryName,
id: node.data.id + e.id + 'query',
type: 'query',
leaf: true,
rawid: e.id,
storagegroupid: node.data.storagegroupid,
connectionid: node.data.connectionid,
queryid: e.id,
};
});
data.unshift(newQuery);
return resolve(data);
} else {
resolve([]);
}
})
.catch(() => {
resolve([]);
});
}
};
return {
collapseNode,
expandNode,
treeExpandKey,
treeKey,
store,
loadNode,
searchClick,
nodeClick,
newSource,
treeProps,
searchVal,
treeRef,
close,
successFunc,
showDialog,
types,
showDrawer,
updateTree,
sqlClick,
coloseDrawer,
funcdata,
};
},
components: {
ElTree,
IconTypes,
ElButton,
// ElInput,
NewSource,
SqlDrawer,
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.data-list-tree {
height: 100%;
overflow: auto;
.data-list-top {
color: #333;
font-size: 12px;
line-height: 20px;
text-align: left;
margin: 14px 20px;
font-weight: 600;
}
.data-list-btn {
text-align: left;
padding: 0 0 14px;
border-width: 0;
border-bottom-width: 1px;
border-style: solid;
border-color: #f5f5f7;
margin: 0 14px 14px;
&::v-deep {
.el-button {
border-width: 0;
background-color: #f9fbfc;
color: #333;
font-size: 12px;
&:hover {
background-color: #edf8f5;
color: #16c493;
}
.icon {
font-size: 14px;
margin-right: 8px;
}
}
}
}
.data-list-input {
margin: 0 20px 15px;
}
.custom-tree-node {
font-size: 12px;
color: #333;
}
::v-deep(.el-tree) {
height: calc(100% - 105px);
width: 100%;
overflow: auto;
.el-tree-node {
min-width: fit-content;
&.is-current > .el-tree-node__content > .custom-tree-node {
& > span {
color: $theme-color;
}
}
}
.el-tree-node__content {
min-width: fit-content;
}
}
}
</style>