NEZ-290 feat: 增加project类型的chart
This commit is contained in:
@@ -1556,6 +1556,12 @@ li{
|
||||
.grey {
|
||||
background-color:lightGrey;
|
||||
}
|
||||
.dark-red {
|
||||
background-color: #aa0000 !important;
|
||||
}
|
||||
.orange {
|
||||
background-color: #ffa500 !important;
|
||||
}
|
||||
|
||||
.clickable:hover{
|
||||
cursor:pointer;
|
||||
|
||||
@@ -107,6 +107,14 @@
|
||||
:editChartId="'editChartId' + item.id"
|
||||
></chart-asset-info>
|
||||
|
||||
<chart-project-info v-if="item.type === 'projectInfo'" :ref="'editChart'+item.id" :key="'inner' + item.id"
|
||||
@on-drag-chart="editChartForDrag"
|
||||
:panel-id="filter.panelId"
|
||||
:chart-index="index"
|
||||
:chart-data="item"
|
||||
:editChartId="'editChartId' + item.id"
|
||||
></chart-project-info>
|
||||
|
||||
<chart-alert-list :ref="'editChart'+item.id"
|
||||
:panel-id="filter.panelId"
|
||||
:chart-index="index"
|
||||
@@ -134,6 +142,7 @@
|
||||
import chartUrl from './chart-url';
|
||||
import chartSingleStat from './chart-single-stat';
|
||||
import chartAssetInfo from './chart-asset-info'
|
||||
import chartProjectInfo from './chart-project-info'
|
||||
import draggable from 'vuedraggable'
|
||||
import chartDataFormat from "./chartDataFormat";
|
||||
import chartAlertList from './chart-alert-list'
|
||||
@@ -146,6 +155,7 @@
|
||||
components: {
|
||||
chartAlertList,
|
||||
chartAssetInfo,
|
||||
chartProjectInfo,
|
||||
lineChartBlock,
|
||||
chartTable,
|
||||
chartUrl,
|
||||
@@ -649,6 +659,10 @@
|
||||
this.getAssetInfoChartData(chartItem);
|
||||
return;
|
||||
}
|
||||
if(chartItem.type == 'projectInfo'){
|
||||
this.getProjectInfoChartData(chartItem);
|
||||
return;
|
||||
}
|
||||
if(chartItem.type === 'alertList'){
|
||||
this.getAlertListChartData(chartItem,filterType);
|
||||
return;
|
||||
@@ -1124,42 +1138,92 @@
|
||||
}]
|
||||
}
|
||||
}
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, response.data, this.filter.panelId, this.filter);
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, data, this.filter.panelId, this.filter);
|
||||
}else{
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, {}, this.filter.panelId, this.filter, response.msg);
|
||||
}
|
||||
})
|
||||
}else {
|
||||
let data = {Basic: {
|
||||
alert:0,
|
||||
assetType: "xxx",
|
||||
cabinet: "xxx",
|
||||
dataCenter: "xxx",
|
||||
endpoint: 1,
|
||||
host: "xxx.xxx.xxx.xxx",
|
||||
id: -1,
|
||||
model: "xxx",
|
||||
pingLastReply: new Date(),
|
||||
pingRtt: 0,
|
||||
pingStatus: 1,
|
||||
principal: "admin",
|
||||
purchaseDate: null,
|
||||
sn: "xxx",
|
||||
state: 1,
|
||||
tel: "xxxxxxxxxxx",
|
||||
vendor: "xxx"
|
||||
let data={
|
||||
Basic:{
|
||||
sn:'assetInfo Test',
|
||||
host:'192.168.40.42',
|
||||
host1:'192.168.40.42',
|
||||
host2:'192.168.40.42',
|
||||
host3:'192.168.40.42',
|
||||
host4:'192.168.40.42',
|
||||
host5:'192.168.40.42',
|
||||
host6:'192.168.40.42',
|
||||
host7:'192.168.40.42',
|
||||
host8:'192.168.40.42',
|
||||
host9:'192.168.40.42',
|
||||
host10:'192.168.40.42',
|
||||
pingStatus:1,
|
||||
pingRtt:80,
|
||||
cpuNum:'8',
|
||||
memery:'12GB',
|
||||
memery$_$free:'3GB'
|
||||
},
|
||||
Feature:{
|
||||
CPU:"xxx",
|
||||
CPU:"Intel E500",
|
||||
Memory:"256GB",
|
||||
NetworkInterface:["eth0", "eth1"],
|
||||
NetworkInterface:["eth0","eth1"],
|
||||
Disk:[{
|
||||
mount:"/",
|
||||
total:"256GB",
|
||||
free:"128GB",
|
||||
usageRate:"50%"
|
||||
}]
|
||||
}};
|
||||
}
|
||||
}
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, data, this.filter.panelId, this.filter);
|
||||
}
|
||||
},
|
||||
getProjectInfoChartData(chartInfo){
|
||||
if(!this.isModel){
|
||||
this.$refs['editChart'+chartInfo.id][0].showLoad(chartInfo);
|
||||
this.$get('/project/info?id='+this.additionalInfo.id).then(response=>{
|
||||
if(response.code == 200){
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, response.data, this.filter.panelId, this.filter);
|
||||
}else{
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, {}, this.filter.panelId, this.filter, response.msg);
|
||||
}
|
||||
})
|
||||
}else {
|
||||
let data={
|
||||
basic: {
|
||||
id: 1,
|
||||
name: "system",
|
||||
remark: "描述信息",
|
||||
alertStat: [1,2,3],
|
||||
},
|
||||
module: [
|
||||
{
|
||||
id: 1,
|
||||
name: "kafka",
|
||||
type: "http",
|
||||
remark: "描述信息",
|
||||
endpointStat: [3,23],
|
||||
alertStat: [2,3,4],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "kafkakafkakafkakafkakafkakafkakafka",
|
||||
type: "http",
|
||||
remark: "描述信息",
|
||||
endpointStat: [3,23],
|
||||
alertStat: [2,0,4],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "kafkakafka",
|
||||
type: "snmp",
|
||||
remark: "描述信息",
|
||||
endpointStat: [3,0],
|
||||
alertStat: [2,3,4],
|
||||
},
|
||||
]
|
||||
};
|
||||
this.$refs['editChart'+chartInfo.id][0].setData(chartInfo, data, this.filter.panelId, this.filter);
|
||||
}
|
||||
},
|
||||
|
||||
336
nezha-fronted/src/components/charts/chart-project-info.vue
Normal file
336
nezha-fronted/src/components/charts/chart-project-info.vue
Normal file
@@ -0,0 +1,336 @@
|
||||
<style lang="scss">
|
||||
@import './chart.scss';
|
||||
</style>
|
||||
<template>
|
||||
<div class="nz-chart-resize">
|
||||
<div class="resize-shadow" ref="resizeShadow"></div>
|
||||
<div class="resize-box resize-box-project" ref="resizeBox">
|
||||
<div class="chart-project-info" :id="'chartProjectInfoDiv'+chartIndex" v-show="divFirstShow" @mouseenter="caretShow=true" @mouseleave="caretShow=false">
|
||||
<loading :ref="'localLoading'+chartIndex"></loading>
|
||||
<div class="clearfix chartTitle" :class="{'dragTitle':dragTitleShow}" :id="'chartTitle'+chartIndex">
|
||||
<el-popover
|
||||
v-if="isError"
|
||||
:close-delay=10
|
||||
placement="top-start"
|
||||
trigger="hover"
|
||||
popper-class="chart-error-popper">
|
||||
<div>{{errorContent}}</div>
|
||||
<span slot="reference" class="panel-info-corner panel-info-corner--error">
|
||||
<i class="nz-icon nz-icon-warning fa"></i>
|
||||
<span class="panel-info-corner-inner"></span>
|
||||
</span>
|
||||
</el-popover>
|
||||
<span class="el-dropdown-link chart-title" @click="dropdownMenuShow=!dropdownMenuShow">
|
||||
<span class="chart-title-text">{{$t('asset.createAssetTab.assetInfo')}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-10 chart-info-container" v-cloak v-show="firstShow" >
|
||||
<div :id="'chartContainer'+chartIndex" ref="chartContainer" class="asset-info-content" >
|
||||
<el-scrollbar style="height: 100%;width:100%;" ref="scrollbar" class="el-scrollbar-normal">
|
||||
<div style="padding: 0 15px">
|
||||
<div class="basic-container">
|
||||
<div class="basic-title asset-info-content-title" @click="hideElement('basic')">
|
||||
<span><i :class="{'el-icon-caret-right':hidebasic,'el-icon-caret-bottom':!hidebasic}"></i></span>
|
||||
<span>{{$t('project.chart.basicTitle')}}</span>
|
||||
</div>
|
||||
<div class="basic-content" :class="{'shrink':hidebasic}">
|
||||
<template v-if="projectInfos.basic && Object.keys(projectInfos.basic).length>0">
|
||||
<div v-for="(item,index) in basicKey" :key="index" class="content-item">
|
||||
<div class="content-item-key item-tip" :id="'basicKey' + index">
|
||||
<span>{{item.label}}</span>
|
||||
<div class="item-tip-hide item-tip-key el-popover" :class="itemTip('basicKey', item.label, index, ready)">{{item.label}}</div>
|
||||
</div>
|
||||
<div class="content-item-value" v-if="item.prop == 'alertStat'">
|
||||
<div class="active-icon dark-red"></div>
|
||||
<span>{{projectInfos.basic.alertStat[0]}}</span>
|
||||
<div class="active-icon red"></div>
|
||||
<span>{{projectInfos.basic.alertStat[1]}}</span>
|
||||
<div class="active-icon orange"></div>
|
||||
<span>{{projectInfos.basic.alertStat[2]}}</span>
|
||||
</div>
|
||||
<div class="content-item-value item-tip" v-else :id="'basicValue' + index">
|
||||
<span>{{projectInfos.basic[item.prop] ? projectInfos.basic[item.prop] : " "}}</span>
|
||||
<div class="item-tip-hide item-tip-value el-popover" :class="itemTip('basicValue', projectInfos.basic[item.prop], index, ready)">{{projectInfos.basic[item.prop]}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature-container" v-for="(module, mi) in projectInfos.module" :key="mi">
|
||||
<div class="feature-title asset-info-content-title" @click="hideElement(module.id)" >
|
||||
<span><i :class="{'el-icon-caret-right':showModuleId != module.id,'el-icon-caret-bottom':showModuleId == module.id}"></i></span>
|
||||
<span>{{$t('project.module.module')}}:{{module.name}}</span>
|
||||
</div>
|
||||
<div class="feature-content" :class="{'shrink':showModuleId != module.id}">
|
||||
<div v-for="(item,index) in moduleKey" :key="index" class="content-item">
|
||||
<div class="content-item-key item-tip" :id="'featureKey' + module.id + '-' + index">
|
||||
<span>{{item.label}}</span>
|
||||
<div class="item-tip-hide item-tip-key el-popover" :class="itemTip('featureKey' + module.id + '-', item.label, index, ready)">{{item.label}}</div>
|
||||
</div>
|
||||
<div class="content-item-value" v-if="item.prop == 'endpointStat'">
|
||||
<img src='../../assets/img/up.png' width="20" style="vertical-align: middle">
|
||||
<span>{{projectInfos.basic.alertStat[0]}}</span>
|
||||
<img src='../../assets/img/down.png' width="20" style="vertical-align: middle">
|
||||
<span>{{projectInfos.basic.alertStat[1]}}</span>
|
||||
</div>
|
||||
<div class="content-item-value" v-else-if="item.prop == 'alertStat'">
|
||||
<div class="active-icon dark-red"></div>
|
||||
<span>{{module.alertStat[0]}}</span>
|
||||
<div class="active-icon red"></div>
|
||||
<span>{{module.alertStat[1]}}</span>
|
||||
<div class="active-icon orange"></div>
|
||||
<span>{{module.alertStat[2]}}</span>
|
||||
</div>
|
||||
<div v-else class="content-item-value item-tip" :id="'featureValue' + module.id + '-' + index">
|
||||
<span>{{module[item.prop] ? module[item.prop] : " "}}</span>
|
||||
<div class="item-tip-hide item-tip-value el-popover" :class="itemTip('featureValue' + module.id + '-', module[item.prop], index, ready)">{{module[item.prop]}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="vue-resizable-handle" @mousedown="startResize"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loading from "../common/loading";
|
||||
import timePicker from '../common/timePicker'
|
||||
|
||||
export default {
|
||||
name: 'chartProjectInfo',
|
||||
components: {
|
||||
'loading': loading,
|
||||
'time-picker':timePicker
|
||||
},
|
||||
props: {
|
||||
// 看板id
|
||||
panelId: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
editChartId: {
|
||||
type: String,
|
||||
default: 'editChartId',
|
||||
},
|
||||
chartIndex:{
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ready: false,
|
||||
data: {}, // 该图表信息,chartItem
|
||||
unit:{},
|
||||
isError:false,
|
||||
errorContent:'',
|
||||
projectInfos:{},
|
||||
loading:Object,
|
||||
panelIdInner: '', // 看板id=panelId,原写作chart,由set_data获取
|
||||
firstLoad: false, // 是否第一次加载
|
||||
screenModal: false,
|
||||
// 查询数据使用
|
||||
filter: {
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
},
|
||||
hidebasic:false,
|
||||
showModuleId: 0,
|
||||
firstShow: false, // 默认不显示操作按钮,
|
||||
caretShow:false,
|
||||
dragTitleShow:false,
|
||||
dropdownMenuShow:false,
|
||||
divFirstShow:false,
|
||||
searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()],//全屏显示的时间
|
||||
oldSearchTime: [],
|
||||
basicKey:[
|
||||
{
|
||||
label: "ID",
|
||||
prop: 'id',
|
||||
},
|
||||
{
|
||||
label: this.$t("overall.name"),
|
||||
prop: 'name',
|
||||
},
|
||||
{
|
||||
label: this.$t("overall.remark"),
|
||||
prop: 'remark',
|
||||
},
|
||||
{
|
||||
label: this.$t("project.chart.alertStat"),
|
||||
prop: 'alertStat',
|
||||
},
|
||||
],
|
||||
moduleKey: [
|
||||
{
|
||||
label: "ID",
|
||||
prop: 'id',
|
||||
},
|
||||
{
|
||||
label: this.$t("overall.name"),
|
||||
prop: 'name',
|
||||
},
|
||||
{
|
||||
label: this.$t("overall.type"),
|
||||
prop: 'type',
|
||||
},
|
||||
{
|
||||
label: this.$t("overall.remark"),
|
||||
prop: 'remark',
|
||||
},
|
||||
{
|
||||
label: this.$t("project.chart.endpointStat"),
|
||||
prop: 'endpointStat',
|
||||
},
|
||||
{
|
||||
label: this.$t("project.chart.alertStat"),
|
||||
prop: 'alertStat',
|
||||
},
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
itemTip() {
|
||||
return function(type, content, index, ready) {
|
||||
let className = "";
|
||||
if (ready) {
|
||||
let cellDom = document.querySelector(`#${type}${index}`);
|
||||
let spanDom = document.createElement("span");
|
||||
spanDom.style.display = "inline-block";
|
||||
spanDom.innerText = content;
|
||||
cellDom.appendChild(spanDom);
|
||||
if (cellDom.offsetWidth-16 < spanDom.offsetWidth) {
|
||||
className = "item-tip-show";
|
||||
}
|
||||
cellDom.removeChild(spanDom);
|
||||
}
|
||||
return className;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
startResize(e) {
|
||||
let vm = this;
|
||||
this.$chartResizeTool.start(vm, this.data, e);
|
||||
},
|
||||
setLabels:function(source){
|
||||
let labels=[];
|
||||
source.forEach(item=>{
|
||||
labels=labels.concat(Object.keys(item))
|
||||
})
|
||||
labels=Array.from(new Set(labels));
|
||||
|
||||
labels=labels.map(item=>{
|
||||
return{
|
||||
label:this.replaceSplit(item),
|
||||
prop:item,
|
||||
show:true,
|
||||
}
|
||||
})
|
||||
|
||||
return labels;
|
||||
},
|
||||
hideElement:function(type){
|
||||
if(type == 'basic'){
|
||||
this.hidebasic=!this.hidebasic;
|
||||
}else{
|
||||
if (this.showModuleId == type) {
|
||||
this.showModuleId = 0;
|
||||
} else {
|
||||
this.showModuleId = type;
|
||||
}
|
||||
}
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.scrollbar.update();
|
||||
})
|
||||
},
|
||||
replaceSplit(key){
|
||||
if(key){
|
||||
return key.replace(/\$_\$/g,' ')
|
||||
}
|
||||
},
|
||||
startLoading(area){
|
||||
this.$refs['localLoading'+this.chartIndex].startLoading();
|
||||
},
|
||||
endLoading(area){
|
||||
this.$refs['localLoading'+this.chartIndex].endLoading();
|
||||
},
|
||||
resize() {
|
||||
let container = document.querySelector('#chartProjectInfoDiv' + this.chartIndex + " .chart-info-container");
|
||||
container.style.height = `calc(100% - ${this.$chartResizeTool.titleHeight+this.$chartResizeTool.chartTableBlankHeight}px)`;
|
||||
},
|
||||
showLoad(chartItem) {
|
||||
this.$nextTick(() => {
|
||||
this.resize();
|
||||
});
|
||||
this.startLoading();
|
||||
this.divFirstShow = true;
|
||||
},
|
||||
// 重新请求数据 刷新操作-local
|
||||
refreshChart() {
|
||||
this.dropdownMenuShow=false;
|
||||
this.startLoading();
|
||||
this.firstShow = false;
|
||||
this.$emit('on-refresh-data', this.data.id);
|
||||
},
|
||||
// 编辑图表
|
||||
editChart() {
|
||||
this.dropdownMenuShow=false;
|
||||
this.$emit('on-edit-chart-block', this.data.id);
|
||||
},
|
||||
// 删除该图表
|
||||
removeChart() {
|
||||
this.dropdownMenuShow=false;
|
||||
this.$emit('on-remove-chart-block', this.data.id);
|
||||
},
|
||||
clickos() {
|
||||
this.dropdownMenuShow=false;
|
||||
},
|
||||
clearChart(){
|
||||
this.data = {};
|
||||
},
|
||||
|
||||
// 设置数据, filter区分
|
||||
setData(chartItem, projectInfos, panelId, filter,area,errorMsg) {
|
||||
this.resize(chartItem);
|
||||
if(errorMsg && errorMsg!==''){
|
||||
this.isError = true;
|
||||
this.errorContent = errorMsg;
|
||||
}else {
|
||||
this.isError = false;
|
||||
this.errorContent = '';
|
||||
}
|
||||
this.divFirstShow = true;
|
||||
|
||||
this.firstShow = true; // 展示操作按键
|
||||
|
||||
this.panelIdInner = panelId;
|
||||
this.data = chartItem;
|
||||
|
||||
this.projectInfos=projectInfos;
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.scrollbar.update();
|
||||
})
|
||||
this.endLoading();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.firstLoad = false;
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.scrollbar.update();
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.ready = true;
|
||||
}, 300);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.clearChart();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -197,7 +197,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.chart-asset-info {
|
||||
.chart-asset-info, .chart-project-info {
|
||||
.chart-info-container {
|
||||
padding-top: 6px;
|
||||
}
|
||||
@@ -329,7 +329,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.line-chart-block, .chart-table, .chart-single-stat, .chart-url, .chart-asset-info, .chart-alert-info {
|
||||
.line-chart-block, .chart-table, .chart-single-stat, .chart-url, .chart-asset-info, .chart-alert-info, .chart-project-info {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background-color: white;
|
||||
|
||||
@@ -430,9 +430,11 @@
|
||||
},
|
||||
obj: {
|
||||
immediate: true,
|
||||
handler(n) {
|
||||
handler(n, o) {
|
||||
setTimeout(() => {
|
||||
if (n && !o || n.id != o.id) {
|
||||
this.getTableData(n.id);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ const en = {
|
||||
search: 'Search', //'搜索'
|
||||
add: 'Create', //"新增"
|
||||
option: 'Operation', //"操作"
|
||||
remark: "Description",
|
||||
clear: 'Clear', //"清除"
|
||||
name: 'Name', //'名称'
|
||||
cover: 'Override', //'覆盖'
|
||||
@@ -793,6 +794,11 @@ const en = {
|
||||
}
|
||||
},
|
||||
project: {
|
||||
chart: {
|
||||
basicTitle: "Basic info",
|
||||
alertStat: "Alert state",
|
||||
endpointStat: "Endpoint state",
|
||||
},
|
||||
project: {
|
||||
project: 'Project',//"系统"
|
||||
projectName: 'Project name',//"系统名称"
|
||||
|
||||
Reference in New Issue
Block a user