CN-671 Dashboard - 多维度表格优化:network overview – app list 点击标题触发下钻;npm 类别评分表格点击触发下钻;

This commit is contained in:
hanyuxia
2022-08-30 16:45:13 +08:00
parent 72f058ff7e
commit 72f3877eb4
8 changed files with 210 additions and 15 deletions

View File

@@ -83,6 +83,7 @@
span { span {
font-size: 16px; font-size: 16px;
color: #046ECA; color: #046ECA;
cursor: pointer;
} }
i { i {
color: #38ACD2; color: #38ACD2;

View File

@@ -106,7 +106,7 @@
border-bottom: 2px solid $blue; border-bottom: 2px solid $blue;
color:$blue; color:$blue;
height: 33px; height: 33px;
margin:0 20px 0 0; margin:0 20px 7px 0;
padding:0px; padding:0px;
font-weight:400; font-weight:400;
} }

View File

@@ -101,6 +101,7 @@
font-size: 12px; font-size: 12px;
color: #353636; color: #353636;
font-weight: 400; font-weight: 400;
cursor: pointer;
} }
.data-score { .data-score {
border-radius: 10px; border-radius: 10px;

View File

@@ -707,6 +707,15 @@ export const dnsServerRole = {
FWDNS: 'FWDNS' FWDNS: 'FWDNS'
} }
export const npmCategoryToAppCategoryMap = {
'network.video': 'multimedia-streaming',
'network.fileSharing': 'social-networking',
'network.voip': 'file-sharing',
'network.gaming': 'gaming',
'network.email': 'email',
'network.socialNetwork': 'voip-video'
}
// npm页-应用评分-类别名称、icon、i18n映射 // npm页-应用评分-类别名称、icon、i18n映射
export const npmCategoryInfoMapping = [ export const npmCategoryInfoMapping = [
{ {

View File

@@ -86,7 +86,6 @@ export default {
this.panelName = this.$store.getters.getPanelName this.panelName = this.$store.getters.getPanelName
const curOperationType = this.$store.getters.getTabOperationType const curOperationType = this.$store.getters.getTabOperationType
if (this.panelName && this.$route.path === '/panel/networkAppPerformance' && curOperationType !== operationType.thirdMenu) { if (this.panelName && this.$route.path === '/panel/networkAppPerformance' && curOperationType !== operationType.thirdMenu) {
// let columnName = this.$store.getters.getBreadcrumbColumnName
const columnValue = this.$store.getters.getBreadcrumbColumnValue const columnValue = this.$store.getters.getBreadcrumbColumnValue
const queryParams = { const queryParams = {
startTime: getSecond(this.timeFilter.startTime), startTime: getSecond(this.timeFilter.startTime),

View File

@@ -20,7 +20,7 @@
<div class="app-card-title"> <div class="app-card-title">
<div class="app-card-title-name"> <div class="app-card-title-name">
<i class="cn-icon" :class="app.type === 'provider' ? 'cn-icon-entity' : 'cn-icon-app2'"></i> <i class="cn-icon" :class="app.type === 'provider' ? 'cn-icon-entity' : 'cn-icon-app2'"></i>
<span>{{app.name}}</span> <span @click="drillDownData(app.type,app.name)">{{app.name}}</span>
</div> </div>
<div class="app-card-title-more" v-ele-click-outside="clickOutSide"> <div class="app-card-title-more" v-ele-click-outside="clickOutSide">
<span><i class="cn-icon cn-icon-more-dark" @click="moreChange(app)"></i></span> <span><i class="cn-icon cn-icon-more-dark" @click="moreChange(app)"></i></span>
@@ -118,18 +118,18 @@
<script> <script>
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import {storageKey, unitTypes} from '@/utils/constants' import { storageKey, unitTypes, networkTable, operationType } from '@/utils/constants'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import {appListChartOption} from '@/views/charts2/charts/options/echartOption' import { appListChartOption } from '@/views/charts2/charts/options/echartOption'
import {shallowRef} from 'vue' import { shallowRef } from 'vue'
import {get, put} from '@/utils/http' import { get, put } from '@/utils/http'
import {api} from '@/utils/api' import { api } from '@/utils/api'
import _ from 'lodash' import _ from 'lodash'
import {getSecond} from '@/utils/date-util' import { getSecond } from '@/utils/date-util'
import {getChainRatio} from '@/utils/tools' import { getChainRatio } from '@/utils/tools'
import loading from '@/components/common/Loading' import loading from '@/components/common/Loading'
import ChartNoData from '@/views/charts/charts/ChartNoData' import ChartNoData from '@/views/charts/charts/ChartNoData'
import {appStackedLineTooltipFormatter} from '@/views/charts/charts/tools' import { appStackedLineTooltipFormatter } from '@/views/charts/charts/tools'
import chartMixin from '@/views/charts2/chart-mixin' import chartMixin from '@/views/charts2/chart-mixin'
export default { export default {
@@ -298,6 +298,83 @@ export default {
} }
this.init() this.init()
}, },
drillDownData (type, value) {
let tabType = ''
if (type === 'provider') {
tabType = 'network.providers'
} else if (type === 'app') {
tabType = 'network.applications'
}
if (tabType) {
const oldCurTab = this.$store.getters.getNetworkOverviewBeforeTab
const curTable = networkTable.networkOverview
const list = this.$store.getters.getNetworkOverviewTabList
const tabGroup = list.filter(item => item.label === tabType)
if (tabGroup && tabGroup.length > 0) {
this.$store.commit('setNetworkOverviewBeforeTab', tabGroup[0])
}
this.$store.commit('setTabOperationBeforeType', this.$store.getters.getTabOperationType)
this.$store.commit('setTabOperationType', operationType.fourthMenu)
const queryCondition = []
const searchProps = tabGroup[0].dillDownProp
searchProps.forEach(item => {
queryCondition.push(item + "='" + value + "'")
})
this.$store.commit('setQueryCondition', queryCondition.join(' OR '))
this.$store.getters.menuList.forEach(menu => {
if (this.$_.isEmpty(menu.children) && menu.route) {
if (this.$route.path === menu.route) {
menu.columnName = tabType
menu.columnValue = value
this.$store.commit('setPanelName', value)
this.$store.commit('setBreadcrumbColumnName', tabType)
this.$store.commit('setDimensionType', tabGroup[0] ? tabGroup[0].prop : '')
this.$store.commit('setBreadcrumbColumnValue', value)
}
} else if (!this.$_.isEmpty(menu.children)) {
menu.children.forEach(child => {
if (this.$route.path === child.route) {
child.columnName = tabType
child.columnValue = value
this.$store.commit('setPanelName', value)
this.$store.commit('setBreadcrumbColumnName', tabType)
this.$store.commit('setDimensionType', tabGroup[0] ? tabGroup[0].prop : '')
this.$store.commit('setBreadcrumbColumnValue', value)
}
})
}
})
let toPanel = null
list.forEach((item, index) => {
if (item.label === tabType) {
item.checked = false
toPanel = item.panelId
}
if (oldCurTab && (item.label === oldCurTab.label)) {
item.checked = true
}
})
this.$store.commit('setNetworkOverviewTabList', list)
const tabObjGroup = list.filter(item => item.checked)
if (tabObjGroup && tabObjGroup.length > 0) {
const curTab = tabObjGroup[0]
this.$store.commit('setNetworkOverviewCurrentTab', curTab)
}
this.$router.push({
name: 'panel',
path: this.$route.path,
query: {
t: +new Date()
},
params: {
thirdPanel: curTable.panelIdOfThirdMenu ? curTable.panelIdOfThirdMenu : '',
fourthPanel: toPanel || ''
}
})
}
},
initChart (obj) { initChart (obj) {
let chart = this.myChart.find(m => m.name === obj.name && m.type === obj.type) let chart = this.myChart.find(m => m.name === obj.name && m.type === obj.type)
if (!chart) { if (!chart) {

View File

@@ -382,6 +382,22 @@ export default {
if (!this.showTabs) { if (!this.showTabs) {
this.activeCustomize = 'metrics' this.activeCustomize = 'metrics'
} }
const tabList = this.list.filter(item => item.checked === true)
const defaultTab = tabList.length > 0 ? tabList[0] : {}
const columnName = this.$store.getters.getBreadcrumbColumnName
const columnValue = this.$store.getters.getBreadcrumbColumnValue
if (tabList.length === 1) {
defaultTab.disabled = true
} else if (tabList.length > 1) {
this.list.forEach(item => {
item.disabled = false
if (columnValue) {
if (item.label === columnName) {
item.disabled = true
}
}
})
}
}, },
getDefaultTab () { getDefaultTab () {
let tabObjGroup = this.list.filter(item => item.checked) let tabObjGroup = this.list.filter(item => item.checked)
@@ -409,7 +425,15 @@ export default {
}, },
initData () { initData () {
const curTab = this.getCurTab() const curTab = this.getCurTab()
// 针对network overview app list 点击标题触发下钻,相关内容处理
const columnName = this.$store.getters.getBreadcrumbColumnName const columnName = this.$store.getters.getBreadcrumbColumnName
if (columnName) {
this.list.forEach(item => {
if (item.label === columnName) {
item.checked = false
}
})
}
this.list.forEach(item => { this.list.forEach(item => {
const tabDom = document.getElementById('tab-' + item.label) const tabDom = document.getElementById('tab-' + item.label)
@@ -430,6 +454,7 @@ export default {
this.hideTabs(curTab) this.hideTabs(curTab)
this.customTableTitles[0].label = curTab.label this.customTableTitles[0].label = curTab.label
this.showTabs = false this.showTabs = false
this.showRecordNum = 10
} else if (curOperationType === operationType.fourthMenu) { // 点击的为第四级菜单 } else if (curOperationType === operationType.fourthMenu) { // 点击的为第四级菜单
const curTab = this.getDefaultTab() const curTab = this.getDefaultTab()
if (curTab) { if (curTab) {
@@ -670,11 +695,18 @@ export default {
const tabList = this.list.filter(item => item.checked === true) const tabList = this.list.filter(item => item.checked === true)
const defaultTab = tabList.length > 0 ? tabList[0] : {} const defaultTab = tabList.length > 0 ? tabList[0] : {}
// 当前操作之后只有1个tab被选中则这一个不允许取消选中 // 当前操作之后只有1个tab被选中则这一个不允许取消选中
const columnName = this.$store.getters.getBreadcrumbColumnName
const columnValue = this.$store.getters.getBreadcrumbColumnValue
if (tabList.length === 1) { if (tabList.length === 1) {
defaultTab.disabled = true defaultTab.disabled = true
} else if (tabList.length > 1) { } else if (tabList.length > 1) {
this.list.forEach(item => { this.list.forEach(item => {
item.disabled = false item.disabled = false
if (columnValue) {
if (item.label === columnName) {
item.disabled = true
}
}
}) })
} }
@@ -773,8 +805,6 @@ export default {
this.$store.commit('setNetworkOverviewCurrentTab', curTab) this.$store.commit('setNetworkOverviewCurrentTab', curTab)
} }
const tab = this.list.filter(item => item.checked)
// 如果面包屑的columnValue有值则不更新valueList // 如果面包屑的columnValue有值则不更新valueList
const valueList = [] const valueList = []
this.tableData.map(item => { this.tableData.map(item => {
@@ -1043,6 +1073,13 @@ export default {
} else { } else {
this.$store.commit('setNetworkOverviewTabList', this.list) this.$store.commit('setNetworkOverviewTabList', this.list)
} }
const tabList = this.list.filter(item => item.checked === true)
const columnName = this.$store.getters.getBreadcrumbColumnName
const columnValue = this.$store.getters.getBreadcrumbColumnValue
if (tabList.length === 0) { // 没有选中任何tab时默认选中第一个
this.list[0].checked = true
}
const curOperationType = this.$store.getters.getTabOperationType const curOperationType = this.$store.getters.getTabOperationType
if (curOperationType === operationType.thirdMenu) { // 点击的为第三级菜单 if (curOperationType === operationType.thirdMenu) { // 点击的为第三级菜单
const curTab = this.getCurTab() const curTab = this.getCurTab()

View File

@@ -31,7 +31,7 @@
<div class="data-total"> <div class="data-total">
<template v-if="item.prop === 'category'"> <template v-if="item.prop === 'category'">
<span class="data-total-category-icon"><i :class="scope.row.icon"></i></span> <span class="data-total-category-icon"><i :class="scope.row.icon"></i></span>
<span class="data-total-category-value">{{$t(scope.row.i18n)}}</span> <span class="data-total-category-value" @click="drillDownData(scope.row.i18n)">{{$t(scope.row.i18n)}}</span>
</template> </template>
<template v-else-if="item.prop === 'total'"> <template v-else-if="item.prop === 'total'">
{{unitConvert(scope.row.totalPacketsRate, unitTypes.bps).join('')}} {{unitConvert(scope.row.totalPacketsRate, unitTypes.bps).join('')}}
@@ -95,7 +95,7 @@
</template> </template>
<script> <script>
import { unitTypes, npmCategoryInfoMapping } from '@/utils/constants' import { unitTypes, npmCategoryInfoMapping, networkTable, operationType, npmCategoryToAppCategoryMap } from '@/utils/constants'
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import { api } from '@/utils/api' import { api } from '@/utils/api'
import { getSecond } from '@/utils/date-util' import { getSecond } from '@/utils/date-util'
@@ -204,6 +204,77 @@ export default {
}).finally(() => { }).finally(() => {
this.toggleLoading(false) this.toggleLoading(false)
}) })
},
drillDownData (key) {
const value = npmCategoryToAppCategoryMap[key]
const tabType = 'network.applicationCategories'
const oldCurTab = this.$store.getters.getNetworkOverviewBeforeTab
const curTable = networkTable.networkOverview
const list = this.$store.getters.getNetworkOverviewTabList
const tabGroup = list.filter(item => item.label === tabType)
if (tabGroup && tabGroup.length > 0) {
this.$store.commit('setNetworkOverviewBeforeTab', tabGroup[0])
}
this.$store.commit('setTabOperationBeforeType', this.$store.getters.getTabOperationType)
this.$store.commit('setTabOperationType', operationType.fourthMenu)
const queryCondition = []
const searchProps = tabGroup[0].dillDownProp
searchProps.forEach(item => {
queryCondition.push(item + "='" + value + "'")
})
this.$store.commit('setQueryCondition', queryCondition.join(' OR '))
this.$store.getters.menuList.forEach(menu => {
if (this.$_.isEmpty(menu.children) && menu.route) {
if (this.$route.path === menu.route) {
menu.columnName = tabType
menu.columnValue = value
this.$store.commit('setPanelName', value)
this.$store.commit('setBreadcrumbColumnName', tabType)
this.$store.commit('setDimensionType', tabGroup[0] ? tabGroup[0].prop : '')
this.$store.commit('setBreadcrumbColumnValue', value)
}
} else if (!this.$_.isEmpty(menu.children)) {
menu.children.forEach(child => {
if (this.$route.path === child.route) {
child.columnName = tabType
child.columnValue = value
this.$store.commit('setPanelName', value)
this.$store.commit('setBreadcrumbColumnName', tabType)
this.$store.commit('setDimensionType', tabGroup[0] ? tabGroup[0].prop : '')
this.$store.commit('setBreadcrumbColumnValue', value)
}
})
}
})
let toPanel = null
list.forEach((item, index) => {
if (item.label === tabType) {
item.checked = false
toPanel = item.panelId
}
if (oldCurTab && (item.label === oldCurTab.label)) {
item.checked = true
}
})
this.$store.commit('setNetworkOverviewTabList', list)
const tabObjGroup = list.filter(item => item.checked)
if (tabObjGroup && tabObjGroup.length > 0) {
const curTab = tabObjGroup[0]
this.$store.commit('setNetworkOverviewCurrentTab', curTab)
}
this.$router.push({
name: 'panel',
path: this.$route.path,
query: {
t: +new Date()
},
params: {
thirdPanel: curTable.panelIdOfThirdMenu ? curTable.panelIdOfThirdMenu : '',
fourthPanel: toPanel || ''
}
})
} }
}, },
mounted () { mounted () {