feat: entity详情(未完成)、修复一些问题
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<div class="cn-chart cn-chart__map">
|
<div class="cn-chart cn-chart__map">
|
||||||
<div class="cn-chart__header chart-header-position" >
|
<div class="cn-chart__header chart-header-position" >
|
||||||
<slot name="chartErrorInfo"></slot>
|
<slot name="chartErrorInfo"></slot>
|
||||||
<div class="header__title chart-title-width" >
|
<div class="header__title" >
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="header__operations">
|
<div class="header__operations">
|
||||||
|
|||||||
@@ -23,11 +23,8 @@
|
|||||||
max-width: 280px !important;
|
max-width: 280px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-title-width{
|
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
.chart-header-position{
|
.chart-header-position{
|
||||||
position:relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-error-popper.el-popper.is-light {
|
.chart-error-popper.el-popper.is-light {
|
||||||
@@ -105,6 +102,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
|
z-index: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,14 +131,14 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
padding: 10px 20px 10px 18px;
|
padding: 10px 20px 10px 18px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
font-size: 16px;
|
|
||||||
color: #333333;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
|
.cn-chart__title {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
.header__operations {
|
.header__operations {
|
||||||
.cn-icon-more-light {
|
color: #999;
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cn-chart__body {
|
.cn-chart__body {
|
||||||
@@ -517,6 +515,77 @@
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cn-entity-detail {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
.entity-detail__header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
height: 70px;
|
||||||
|
padding-right: 20px;
|
||||||
|
background-color: #F7F9FB;
|
||||||
|
& > .el-tabs > .el-tabs__header { // header背景色
|
||||||
|
margin: 0;
|
||||||
|
& > .el-tabs__nav-wrap > .el-tabs__nav-scroll > .el-tabs__nav {
|
||||||
|
& > .el-tabs__item.is-active { // 激活的tab上边框和背景色
|
||||||
|
background-color: white;
|
||||||
|
border-top: 2px solid #0091ff;
|
||||||
|
}
|
||||||
|
& > .el-tabs__active-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
& > div:last-of-type {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
& > div:nth-of-type(2) {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .el-tabs > .el-tabs__header > .el-tabs__nav-wrap::after { // 去掉tabs下方边框
|
||||||
|
height: 0 !important;
|
||||||
|
}
|
||||||
|
&>.el-tabs { // 底部对齐
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.entity-detail__body {
|
||||||
|
height: calc(100% - 90px);
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
&>div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(30, 1fr);
|
||||||
|
grid-auto-flow: row;
|
||||||
|
grid-auto-rows: var(--chart-height-unit);
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
.cn-panel {
|
||||||
|
padding: 20px;
|
||||||
|
grid-gap: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-overlay {
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
.entity-detail__dialog {
|
||||||
|
height: 90vh;
|
||||||
|
overflow: hidden;
|
||||||
|
.el-dialog__header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.el-dialog__body {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
.panel__time {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.option-popper {
|
.option-popper {
|
||||||
.el-select-dropdown__item {
|
.el-select-dropdown__item {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
@@ -524,6 +593,10 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.header__operation-btn {
|
||||||
|
margin-left: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
//.cn-chart-select{
|
//.cn-chart-select{
|
||||||
// display: flex;
|
// display: flex;
|
||||||
// align-items: center;
|
// align-items: center;
|
||||||
|
|||||||
60
src/components/entities/EntityDetail.vue
Normal file
60
src/components/entities/EntityDetail.vue
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="show"
|
||||||
|
:top="top"
|
||||||
|
:modal="modal"
|
||||||
|
:custom-class="customClass"
|
||||||
|
:show-close="showClose"
|
||||||
|
:width="width"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<cn-panel :entity="entity" :is-entity-detail="true"></cn-panel>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Panel from '@/views/charts/Panel'
|
||||||
|
export default {
|
||||||
|
name: 'EntityDetail',
|
||||||
|
components: {
|
||||||
|
'cn-panel': Panel
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
showDetail: Boolean,
|
||||||
|
top: {
|
||||||
|
type: String,
|
||||||
|
default: '5vh'
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
customClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'entity-detail__dialog'
|
||||||
|
},
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
width: { // 高度需要通过customClass自行定义
|
||||||
|
type: [String, Number],
|
||||||
|
default: '90vw'
|
||||||
|
},
|
||||||
|
entity: Object // 实体,{ type: 'ip|domain|app', name: name, icon: icon-class }
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
showDetail (n, o) {
|
||||||
|
this.show = n
|
||||||
|
},
|
||||||
|
show (n, o) {
|
||||||
|
this.$emit('update:show-detail', n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<div class="body__row-value" :title="d.asn">{{d.asn || '-'}}</div>
|
<div class="body__row-value" :title="d.asn">{{d.asn || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="body__detail"
|
<div class="body__detail"
|
||||||
@click="entityDetail({ip: d.ip}, [{key: 'clientIP', label: $t('overall.clientIp')}, {key: 'serverIP', label: $t('overall.serverIp')}])">{{$t('overall.detail')}}></div>
|
@click="entityDetail({name: d.ip, type: 4})">{{$t('overall.detail')}}></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="from === 'domain'">
|
<template v-else-if="from === 'domain'">
|
||||||
<div class="body__row">
|
<div class="body__row">
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> {{$t('entities.credit')}}:</span>
|
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> {{$t('entities.credit')}}:</span>
|
||||||
<div class="body__row-value" :title="d.reputationScore">{{d.reputationScore || '-'}}</div>
|
<div class="body__row-value" :title="d.reputationScore">{{d.reputationScore || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="body__detail" @click="entityDetail({domain: d.domainName})">{{$t('overall.detail')}}></div>
|
<div class="body__detail" @click="entityDetail({name: d.domainName, type: 5})">{{$t('overall.detail')}}></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="from === 'app'">
|
<template v-else-if="from === 'app'">
|
||||||
<div class="body__row">
|
<div class="body__row">
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> {{$t('entities.subcategory')}}:</span>
|
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> {{$t('entities.subcategory')}}:</span>
|
||||||
<div class="body__row-value" :title="d.appSubategory">{{d.appSubategory || '-'}}</div>
|
<div class="body__row-value" :title="d.appSubategory">{{d.appSubategory || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="body__detail" @click="entityDetail({appId: d.appId})">{{$t('overall.detail')}}></div>
|
<div class="body__detail" @click="entityDetail({name: d.appId, type: 6})">{{$t('overall.detail')}}></div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,8 +162,8 @@ export default {
|
|||||||
wraps.scrollTop = 0
|
wraps.scrollTop = 0
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
entityDetail (params, tabs = []) {
|
entityDetail (params) {
|
||||||
this.$emit('showDetail', params, tabs)
|
this.$emit('showDetail', { ...params, icon: this.iconClass })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cn-header">
|
<div class="cn-header">
|
||||||
<!-- <div class="left-menu--pin" :class="false ? 'left-menu--pin-normal' : 'left-menu--pin-reverse'" @click="shrink"><i :class="{'icon-reverse': false}" class="el-icon-s-fold"></i></div>-->
|
|
||||||
<!--导航面包屑-->
|
<!--导航面包屑-->
|
||||||
<div class="header__left">
|
<div class="header__left">
|
||||||
<span @click="shrink" class="shrink-button" :class="{'shrink-button--collapse': isShrink}"><i class="cn-icon cn-icon-expand"></i></span>
|
<span @click="shrink" class="shrink-button" :class="{'shrink-button--collapse': isShrink}"><i class="cn-icon cn-icon-expand"></i></span>
|
||||||
@@ -47,7 +46,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<!-- <change-password :cur-user="username" :show-dialog="showChangePin" @click="showPinDialog" @dialogClosed="dialogClosed"></change-password>-->
|
|
||||||
<el-dialog v-model="showChangePin"
|
<el-dialog v-model="showChangePin"
|
||||||
width="30%"
|
width="30%"
|
||||||
:before-close="handleClose">
|
:before-close="handleClose">
|
||||||
@@ -84,6 +82,7 @@
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { get, put } from '@/utils/http'
|
import { get, put } from '@/utils/http'
|
||||||
import { entityType, storageKey } from '@/utils/constants'
|
import { entityType, storageKey } from '@/utils/constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
data () {
|
data () {
|
||||||
@@ -151,11 +150,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
breadcrumb () {
|
breadcrumb () {
|
||||||
const breadcrumb = this.breadcrumbMap.find(b => this.path === b.path)
|
const breadcrumb = this.breadcrumbMap.find(b => this.path === b.path)
|
||||||
const breadcrumbArray = breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : []
|
return breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : []
|
||||||
if (breadcrumbArray.length > 0 && breadcrumb.childName) {
|
|
||||||
breadcrumbArray.push(breadcrumb.childName)
|
|
||||||
}
|
|
||||||
return breadcrumbArray
|
|
||||||
},
|
},
|
||||||
path () {
|
path () {
|
||||||
const { path } = useRoute()
|
const { path } = useRoute()
|
||||||
@@ -167,9 +162,6 @@ export default {
|
|||||||
isShrink () {
|
isShrink () {
|
||||||
return this.$store.getters.getIsShrink
|
return this.$store.getters.getIsShrink
|
||||||
},
|
},
|
||||||
entityName () {
|
|
||||||
return this.$store.getters.entityName
|
|
||||||
},
|
|
||||||
storeFrom () {
|
storeFrom () {
|
||||||
return this.$store.getters.from
|
return this.$store.getters.from
|
||||||
}
|
}
|
||||||
@@ -182,10 +174,6 @@ export default {
|
|||||||
if (this.from !== n) {
|
if (this.from !== n) {
|
||||||
this.from = n
|
this.from = n
|
||||||
}
|
}
|
||||||
},
|
|
||||||
entityName (n) {
|
|
||||||
const breadcrumb = this.breadcrumbMap.find(b => b.path === '/entityExplorer')
|
|
||||||
breadcrumb.childName = n
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -203,7 +191,6 @@ export default {
|
|||||||
changeLocal (lang) {
|
changeLocal (lang) {
|
||||||
if (lang !== localStorage.getItem('cn-language')) {
|
if (lang !== localStorage.getItem('cn-language')) {
|
||||||
localStorage.setItem('cn-language', lang)
|
localStorage.setItem('cn-language', lang)
|
||||||
// this.$i18n.locale = lang
|
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ const store = createStore({
|
|||||||
i18n: false,
|
i18n: false,
|
||||||
|
|
||||||
showEntityTypeSelector: false, // 在entity explore页面时,控制header显示实体类型选择框
|
showEntityTypeSelector: false, // 在entity explore页面时,控制header显示实体类型选择框
|
||||||
from: '', // entity type
|
from: '' // entity type
|
||||||
entityName: '' // entity名称,用于header顶部面包屑展示
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
@@ -44,9 +43,6 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
showEntityTypeSelector (state, show) {
|
showEntityTypeSelector (state, show) {
|
||||||
state.showEntityTypeSelector = show
|
state.showEntityTypeSelector = show
|
||||||
},
|
|
||||||
setEntityName (state, entityName) {
|
|
||||||
state.entityName = entityName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,15 +33,14 @@ export const fromRoute = {
|
|||||||
galaxyProxy: 'galaxyProxy'
|
galaxyProxy: 'galaxyProxy'
|
||||||
}
|
}
|
||||||
|
|
||||||
/* panel类别和路由之间的映射 */
|
/* panel类别和名称之间的映射 */
|
||||||
export const panelTypeAndRouteMapping = {
|
export const panelTypeAndRouteMapping = {
|
||||||
trafficSummary: 1,
|
trafficSummary: 1,
|
||||||
networkAppPerformance: 2,
|
networkAppPerformance: 2,
|
||||||
dnsServiceInsights: 3,
|
dnsServiceInsights: 3,
|
||||||
ipEntityDetail: 4, // 此为clientIP
|
ipEntityDetail: 4,
|
||||||
domainEntityDetail: 5,
|
domainEntityDetail: 5,
|
||||||
appEntityDetail: 6,
|
appEntityDetail: 6
|
||||||
serverIpEntityDetail: 7
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const position = {
|
export const position = {
|
||||||
|
|||||||
@@ -39,8 +39,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
||||||
<template #operations>
|
<template #operations>
|
||||||
<!-- <i class="cn-icon cn-icon-more-light"></i>-->
|
<el-popover trigger="hover" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
|
||||||
<!-- <i class="cn-icon cn-icon-refresh" @click="loadMap"></i>-->
|
<template #reference>
|
||||||
|
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||||
@@ -78,7 +82,12 @@
|
|||||||
<el-option v-for="item in chartPieTableTopOptions" :key="item.value" :value="item.value"> {{item.name}}</el-option>
|
<el-option v-for="item in chartPieTableTopOptions" :key="item.value" :value="item.value"> {{item.name}}</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<!-- <i class="cn-icon cn-icon-more-light margin-l-10"></i>-->
|
<el-popover trigger="hover" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
|
||||||
|
<template #reference>
|
||||||
|
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||||
@@ -135,9 +144,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
||||||
<template #operations>
|
<template #operations>
|
||||||
<!-- <div class="header__operation header__operation--table">
|
<el-popover trigger="hover" placement="top" :content="chartInfo.remark" v-if="chartInfo.remark">
|
||||||
<span class="option__button"><i class="cn-icon cn-icon-download"></i></span>
|
<template #reference>
|
||||||
</div>-->
|
<span class="header__operation-btn"><i class="cn-icon el-icon-info"></i></span>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
|
||||||
<div class="header__operation header__operation--table">
|
<div class="header__operation header__operation--table">
|
||||||
<el-select
|
<el-select
|
||||||
size="mini"
|
size="mini"
|
||||||
@@ -578,7 +590,7 @@ export default {
|
|||||||
polygonTemplate.nonScalingStroke = true
|
polygonTemplate.nonScalingStroke = true
|
||||||
polygonTemplate.strokeWidth = 0.5
|
polygonTemplate.strokeWidth = 0.5
|
||||||
}
|
}
|
||||||
} else if (response.code != 200) {
|
} else if (response.code !== 200) {
|
||||||
this.isError = true
|
this.isError = true
|
||||||
this.noData = true
|
this.noData = true
|
||||||
this.errorInfo = response.msg || response.message || 'Unknown'
|
this.errorInfo = response.msg || response.message || 'Unknown'
|
||||||
@@ -593,6 +605,9 @@ export default {
|
|||||||
getTargetPageData (pageNum, pageSize, tableData) {
|
getTargetPageData (pageNum, pageSize, tableData) {
|
||||||
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
|
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
|
||||||
},
|
},
|
||||||
|
refresh () {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
getTableTitle (data) {
|
getTableTitle (data) {
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
const dataColumns = Object.keys(data[0]) // 返回数据的字段
|
const dataColumns = Object.keys(data[0]) // 返回数据的字段
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="padding: 10px 0 20px 20px;">
|
<div style="padding: 10px 0 20px 20px;" v-if="!isEntityDetail">
|
||||||
<div v-if="typeName" class="entity-detail-tool">
|
<div class="cn-panel" id="cn-panel">
|
||||||
<div>
|
|
||||||
<span @click="goBack" style="cursor: pointer;"><i class="cn-icon cn-icon-arrow-left-circle"></i></span>
|
|
||||||
<span style="padding-left: 15px; color: #333;">{{tabTitle}}</span>
|
|
||||||
</div>
|
|
||||||
<el-radio-group v-model="tab" size="mini" @change="changeTab">
|
|
||||||
<el-radio-button v-for="tabTmp in tabs" :key="tabTmp.key" :label="tabTmp.key" >{{tabTmp.label}}</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div class="cn-panel" id="cn-panel" :style="{height: typeName ? 'calc(100% - 80px)' : ''}">
|
|
||||||
<div class="panel__time">
|
<div class="panel__time">
|
||||||
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||||
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
||||||
@@ -35,6 +26,30 @@
|
|||||||
</grid-layout>-->
|
</grid-layout>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cn-entity-detail" id="cn-entity-detail" v-else>
|
||||||
|
<div class="panel__time">
|
||||||
|
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||||
|
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
||||||
|
</div>
|
||||||
|
<div class="entity-detail__header">
|
||||||
|
<el-tabs v-model="currentTab">
|
||||||
|
<el-tab-pane
|
||||||
|
v-for="(tab, index) in detailTabs"
|
||||||
|
:label="tab.i18n ? $t(tab.i18n) : tab.name"
|
||||||
|
:name="`${tab.id}`"
|
||||||
|
:key="tab.id"
|
||||||
|
:ref="`chart-${tab.id}`"
|
||||||
|
@tab-click="changeTab(index)"
|
||||||
|
>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
<div class="entity-detail__body">
|
||||||
|
<div class="cn-panel">
|
||||||
|
<chart v-for="chart in detailChartList" :key="chart.id" :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`" :entity="entity"></chart>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -46,14 +61,12 @@ import { getNowTime } from '@/utils/date-util'
|
|||||||
import Chart from './Chart'
|
import Chart from './Chart'
|
||||||
import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
|
import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
|
||||||
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
|
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Panel',
|
name: 'Panel',
|
||||||
props: {
|
props: {
|
||||||
typeName: String,
|
|
||||||
entity: Object,
|
entity: Object,
|
||||||
tabs: Array
|
isEntityDetail: Boolean
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Chart,
|
Chart,
|
||||||
@@ -62,42 +75,18 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
chartList: []
|
chartList: [], // 普通panel的chart
|
||||||
}
|
// entity详情的chart
|
||||||
},
|
detailTabs: [],
|
||||||
computed: {
|
detailChartList: [],
|
||||||
tabTitle () {
|
currentTab: ''
|
||||||
let title
|
|
||||||
switch (this.typeName) {
|
|
||||||
case 'ipEntityDetail': { // client IP
|
|
||||||
title = this.$t('entities.ipDetail')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'serverIpEntityDetail': {
|
|
||||||
title = this.$t('entities.ipDetail')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domainEntityDetail': {
|
|
||||||
title = this.$t('entities.domainDetail')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'appEntityDetail': {
|
|
||||||
title = this.$t('entities.appDetail')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
return title
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted () {
|
async mounted () {
|
||||||
await this.init()
|
await this.init()
|
||||||
|
this.currentTab = this.detailTabs[0].id
|
||||||
},
|
},
|
||||||
setup (props, ctx) {
|
setup (props, ctx) {
|
||||||
let tab = ''
|
|
||||||
if (!_.isEmpty(props.tabs)) {
|
|
||||||
tab = ref(props.tabs[0].key)
|
|
||||||
}
|
|
||||||
// data
|
// data
|
||||||
const dateRangeValue = 60
|
const dateRangeValue = 60
|
||||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||||
@@ -105,42 +94,44 @@ export default {
|
|||||||
const panel = ref({})
|
const panel = ref({})
|
||||||
let panelType = 1 // 取得panel的type
|
let panelType = 1 // 取得panel的type
|
||||||
const { params } = useRoute()
|
const { params } = useRoute()
|
||||||
panelType = props.typeName ? panelTypeAndRouteMapping[props.typeName] : panelTypeAndRouteMapping[params.typeName]
|
panelType = props.entity ? props.entity.type : panelTypeAndRouteMapping[params.typeName]
|
||||||
return {
|
return {
|
||||||
panelType,
|
panelType,
|
||||||
panel,
|
panel,
|
||||||
timeFilter,
|
timeFilter,
|
||||||
api,
|
api
|
||||||
tab
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
goBack () {
|
|
||||||
this.$emit('goBack')
|
|
||||||
},
|
|
||||||
async changeTab (label) {
|
|
||||||
let routePath
|
|
||||||
if (label == 'clientIP') {
|
|
||||||
routePath = 'ipEntityDetail'
|
|
||||||
} else if (label == 'serverIP') {
|
|
||||||
routePath = 'serverIpEntityDetail'
|
|
||||||
}
|
|
||||||
this.panelType = panelTypeAndRouteMapping[routePath]
|
|
||||||
await this.init()
|
|
||||||
},
|
|
||||||
async init () {
|
async init () {
|
||||||
const panels = await getPanelList({ type: this.panelType })
|
const panels = await getPanelList({ type: this.panelType })
|
||||||
if (panels && panels.length > 0) {
|
if (panels && panels.length > 0) {
|
||||||
this.panel = panels[0]
|
this.panel = panels[0]
|
||||||
}
|
}
|
||||||
if (this.panel.id) {
|
if (this.panel.id) {
|
||||||
this.chartList = (await getChartList({ panelId: this.panel.id, pageSize: -1 })).map(chart => {
|
const allCharts = (await getChartList({ panelId: this.panel.id, pageSize: -1 })).map(chart => {
|
||||||
chart.i = chart.id
|
chart.i = chart.id
|
||||||
this.recursionParamsConvert(chart)
|
this.recursionParamsConvert(chart)
|
||||||
return chart
|
return chart
|
||||||
})
|
})
|
||||||
|
if (this.isEntityDetail) {
|
||||||
|
if (!this.$_.isEmpty(allCharts)) {
|
||||||
|
const rootChart = allCharts[0]
|
||||||
|
this.detailTabs = rootChart.children
|
||||||
|
if (!this.$_.isEmpty(this.detailTabs)) {
|
||||||
|
this.detailChartList = this.detailTabs[0].children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.chartList = allCharts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
changeTab (i) {
|
||||||
|
this.currentTab = this.detailTabs[i].id
|
||||||
|
this.detailChartList = this.detailTabs[i].children
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
recursionParamsConvert (chart) {
|
recursionParamsConvert (chart) {
|
||||||
chart.params = chart.params ? JSON.parse(chart.params) : null
|
chart.params = chart.params ? JSON.parse(chart.params) : null
|
||||||
if (!this.$_.isEmpty(chart.children)) {
|
if (!this.$_.isEmpty(chart.children)) {
|
||||||
@@ -180,9 +171,6 @@ export default {
|
|||||||
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
|
||||||
beforeUnmount () {
|
|
||||||
this.$store.commit('setEntityName', '')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="outer-box" v-show="!showDetail">
|
<div class="outer-box">
|
||||||
<div class="cn-entities">
|
<div class="cn-entities">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchContentTemp"
|
v-model="searchContentTemp"
|
||||||
@@ -30,7 +30,11 @@
|
|||||||
></entity-list>
|
></entity-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<cn-panel v-if="showDetail" :entity="currentEntity" :type-name="typeName" :tabs="panelTabs" @goBack="showDetail = false"></cn-panel>
|
<entity-detail
|
||||||
|
v-model:show-detail="showDetail"
|
||||||
|
top="5vh"
|
||||||
|
:show-close="false"
|
||||||
|
:entity="currentEntity"></entity-detail>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -38,8 +42,8 @@ import { entityType, entityFilterType } from '@/utils/constants'
|
|||||||
import LeftFilter from '@/components/entities/LeftFilter'
|
import LeftFilter from '@/components/entities/LeftFilter'
|
||||||
import EntityList from '@/components/entities/EntityList'
|
import EntityList from '@/components/entities/EntityList'
|
||||||
import { getEntityFilter, getEntityList, getEntityCount } from '@/utils/api'
|
import { getEntityFilter, getEntityList, getEntityCount } from '@/utils/api'
|
||||||
import Panel from '@/views/charts/Panel'
|
|
||||||
import { doubleQuotationToSingle } from '@/utils/tools'
|
import { doubleQuotationToSingle } from '@/utils/tools'
|
||||||
|
import EntityDetail from '@/components/entities/EntityDetail'
|
||||||
export default {
|
export default {
|
||||||
name: 'EntityExplorer',
|
name: 'EntityExplorer',
|
||||||
data () {
|
data () {
|
||||||
@@ -67,15 +71,13 @@ export default {
|
|||||||
total: 0
|
total: 0
|
||||||
},
|
},
|
||||||
showDetail: false,
|
showDetail: false,
|
||||||
typeName: '',
|
currentEntity: {}
|
||||||
currentEntity: {},
|
|
||||||
panelTabs: []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
EntityDetail,
|
||||||
LeftFilter,
|
LeftFilter,
|
||||||
EntityList,
|
EntityList
|
||||||
'cn-panel': Panel
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
enter () {
|
enter () {
|
||||||
@@ -315,10 +317,8 @@ export default {
|
|||||||
},
|
},
|
||||||
entityDetail (entity, tabs) {
|
entityDetail (entity, tabs) {
|
||||||
const entityName = entity.domain || entity.ip || entity.appId
|
const entityName = entity.domain || entity.ip || entity.appId
|
||||||
this.$store.commit('setEntityName', entityName)
|
|
||||||
this.typeName = `${this.from.toLowerCase()}EntityDetail`
|
this.typeName = `${this.from.toLowerCase()}EntityDetail`
|
||||||
this.currentEntity = entity
|
this.currentEntity = entity
|
||||||
this.panelTabs = tabs
|
|
||||||
this.showDetail = true
|
this.showDetail = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -446,9 +446,6 @@ export default {
|
|||||||
this.search()
|
this.search()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
showDetail (n) {
|
|
||||||
this.$store.commit('showEntityTypeSelector', !n)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
Reference in New Issue
Block a user