CN-784: Detection列表样式按新版UI图修改

This commit is contained in:
刘洪洪
2022-11-07 15:25:00 +08:00
parent 32a2359e0d
commit ec98178d45
8 changed files with 263 additions and 68 deletions

View File

@@ -2,12 +2,12 @@
display: flex;
.cn-detection__collapse {
margin-bottom: 1px;
padding-top: 18px;
width: 24px;
display: flex;
justify-content: center;
align-items: flex-start;
margin-bottom: 1px;
padding-top: 33px;
background-color: #F3F7FA;
span {

View File

@@ -28,7 +28,7 @@
.explorer-top-tools {
display: flex;
justify-content: flex-end;
justify-content: space-between;
align-items: center;
padding-bottom: 18px;

View File

@@ -20,7 +20,8 @@ export default {
entityDetectionStyle () {
const route = this.$route.name !== undefined ? this.$route.name : this.$route
if (listScrollPath.indexOf(route.path) > -1) {
return 'overflow:auto;background-color: #EFF2F5;'
const style = route.path === listScrollPath[0] ? 'overflow:auto;background-color: #EFF2F5;' : 'overflow:auto;'
return style
} else {
return ''
}

View File

@@ -37,7 +37,7 @@
</div>
<div class="cn-header__nav">
<i class="cn-icon cn-icon-a-NetworkAnalytics"></i>
<el-breadcrumb class="header__left-breadcrumb" separator=">">
<el-breadcrumb class="header__left-breadcrumb" :separator="route.indexOf('detection') === -1 ? '>' : ''">
<el-breadcrumb-item class="header__left-breadcrumb-item" :id="`breadcrumb${item}`" :title="item" v-for="(item,index) in breadcrumb" :key="item">
<template v-if="index===3">
<div class="header__left-breadcrumb-item-select">
@@ -96,30 +96,30 @@
</template>
<template v-else-if="index===1">
<span class="route-menu" @click="jump(route,'','',2)" v-if="route.indexOf('detection') === -1">{{item}}</span>
<div class="header__left-breadcrumb-item-select" v-if="route.indexOf('detection') > -1">
<el-popover placement="bottom-start"
v-if="route.indexOf('detection') > -1"
ref="breadcrumbPopover"
:show-arrow="false"
:append-to-body="false"
:hide-after="0"
:show-after="0"
popper-class="breadcrumb__popper"
trigger="click">
<template #reference>
<div class="breadcrumb-button" id="breadcrumbButton2" :class="showBackground?'breadcrumb-button__active':''" v-if="route.indexOf('detection') > -1">
<span id="breadcrumbValue2"> {{item}}</span><i class="cn-icon-xiala cn-icon"></i>
</div>
</template>
<el-row type="flex" justify="center" style="width: fit-content;flex-direction: column;">
<ul class="select-dropdown" id="breadcrumbSelectDropdown2">
<li v-for="item in detectionMenuList" title='' :key="item.name" :id="item.name" class="select-dropdown__item" @click="jump(item.path,'','',2)">
<span>{{$t(item.i18n)}}</span>
</li>
</ul>
</el-row>
</el-popover>
</div>
<!-- <div class="header__left-breadcrumb-item-select" v-if="route.indexOf('detection') > -1">-->
<!-- <el-popover placement="bottom-start"-->
<!-- v-if="route.indexOf('detection') > -1"-->
<!-- ref="breadcrumbPopover"-->
<!-- :show-arrow="false"-->
<!-- :append-to-body="false"-->
<!-- :hide-after="0"-->
<!-- :show-after="0"-->
<!-- popper-class="breadcrumb__popper"-->
<!-- trigger="click">-->
<!-- <template #reference>-->
<!-- <div class="breadcrumb-button" id="breadcrumbButton2" :class="showBackground?'breadcrumb-button__active':''" v-if="route.indexOf('detection') > -1">-->
<!-- <span id="breadcrumbValue2"> {{item}}</span><i class="cn-icon-xiala cn-icon"></i>-->
<!-- </div>-->
<!-- </template>-->
<!-- <el-row type="flex" justify="center" style="width: fit-content;flex-direction: column;">-->
<!-- <ul class="select-dropdown" id="breadcrumbSelectDropdown2">-->
<!-- <li v-for="item in detectionMenuList" title='' :key="item.name" :id="item.name" class="select-dropdown__item" @click="jump(item.path,'','',2)">-->
<!-- <span>{{$t(item.i18n)}}</span>-->
<!-- </li>-->
<!-- </ul>-->
<!-- </el-row>-->
<!-- </el-popover>-->
<!-- </div>-->
</template>
<template v-else>
<span>{{item}}</span>

View File

@@ -6,6 +6,8 @@
<div class="no-data" v-if="noData">No data</div>
<div v-if="!isCollapse" @click="collapse" class="cn-detection__shadow"></div>
<detection-row
style="margin-bottom: 10px"
class="detection-border"
v-for="(data, index) in listData"
:detection="data"
:page-type="pageType"

View File

@@ -2,12 +2,19 @@
<div class="cn-detection--list" :style="{zIndex: !isCollapse ? 1 : 'unset'}">
<!-- 左侧下拉按钮 -->
<div class="cn-detection__collapse">
<span @click="switchCollapse" :class="{'reg-down': !isCollapse}"><i class="cn-icon cn-icon-arrow-right"></i></span>
<span @click="switchCollapse" :class="{'reg-down': !isCollapse}">
<i class="cn-icon cn-icon-arrow-right"></i>
</span>
</div>
<div class="cn-detection__case">
<div class="cn-detection__icon" :style="`background-color: ${eventSeverityColor[detection.eventSecurity]}`"></div>
<div class="cn-detection__row">
<div class="cn-detection__header" v-if="pageType === detectionPageType.securityEvent">
<span
class="detection-event-severity-color-block"
:style="`background-color: ${eventSeverityColor[detection.eventSeverity]}`">
</span>
<span class="detection-event-severity-block">{{ detection.securityType || '-' }}</span>
<i class="cn-icon cn-icon-attacker" ></i>{{detection.offenderIp || '-'}}
<div v-if="detection.domain" class="domain">{{detection.domain}}</div>
<span class="line">-------</span>
@@ -31,11 +38,6 @@
<span>{{$t('detections.eventSeverity')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.eventSeverity || '-'}}</span>
</div>
<div class="basic-info__item" v-if="detection.securityType">
<i class="cn-icon cn-icon-event-type"></i>
<span>{{$t('detection.list.securityType')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.securityType || '-'}}</span>
</div>
<div class="basic-info__item" v-if="detection.eventType">
<i class="cn-icon cn-icon-event-type"></i>
<span>{{$t('detections.eventType')}}&nbsp;:&nbsp;&nbsp;</span>
@@ -176,3 +178,25 @@ export default {
}
}
</script>
<style>
.detection-event-severity-color-block {
width: 5px;
height: 20px;
border-radius: 2.5px;
margin-left: -16px;
margin-right: 12px;
}
.detection-event-severity-block {
font-family: NotoSansHans-Medium;
font-size: 12px;
color: #046EC9;
font-weight: 500;
padding: 2px 10px;
background: rgba(56,172,210,0.10);
border: 1px solid #ADC7DB;
box-shadow: 0 2px 0.28571rem 0 rgb(51 51 51 / 2%);
border-radius: 3px;
margin-right: 10px;
}
</style>

View File

@@ -0,0 +1,94 @@
<template>
<div class="npm-tabs">
12345678
<div class="npm-tabs__active-bar"></div>
<el-tabs v-model="currentTab" ref="elTabs" type="border-card" @tab-click="jumpPage">
<el-tab-pane
v-for="(tab,index) in tabs"
:key="tab.i18n"
:name="index"
:disabled="tab.disable">
<template #label>
<div class="npm-tab__label">
<i :class="tab.icon"></i>
<span>{{ $t(tab.i18n) }}</span>
</div>
</template>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import chartMixin from '@/views/charts2/chart-mixin'
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
import { useRoute } from 'vue-router'
import { ref } from 'vue'
export default {
name: 'DetectionTabs',
data () {
return {
leftOffset: 27
}
},
mixins: [chartMixin],
setup (props) {
const tabs = ref([])
if (props.chart) {
tabs.value = [...props.chart]
tabs.value.forEach(item => {
item.disable = false
})
}
const { query } = useRoute()
const tabIndexParam = query.tabIndex
const currentTab = ref(tabIndexParam ? parseInt(tabIndexParam) : 0)
return {
currentTab,
tabs
}
},
watch: {
currentTab (n) {
const { query } = this.$route
const newUrl = urlParamsHandler(window.location.href, query, {
tabIndex: n
})
overwriteUrl(newUrl)
this.$nextTick(() => {
this.handleActiveBar(n)
})
}
},
methods: {
handleActiveBar (index) {
const tabDom = document.getElementById('tab-' + index)
if (tabDom) {
const offsetLeft = tabDom.offsetLeft
const clientWidth = tabDom.clientWidth
const clientLeft = tabDom.clientLeft
const activeBar = document.querySelector('.npm-tabs .npm-tabs__active-bar')
activeBar.style.cssText += `width: ${clientWidth + 2}px; left: ${offsetLeft + this.leftOffset + clientLeft - 1}px;`
}
},
jumpPage (item) {
this.$router.push({
path: this.tabs[item.index].path,
query: {
t: +new Date(),
tabIndex: this.currentTab
}
})
}
},
mounted () {
// setTimeout(() => {
this.$nextTick(() => {
this.handleActiveBar(this.currentTab)
})
// }, 120)
}
}
</script>

View File

@@ -1,37 +1,57 @@
<template>
<div
class="entity-explorer entity-explorer--show-list"
>
<div class="entity-explorer entity-explorer--show-list">
<!-- 顶部工具栏在列表页显示 -->
<div class="explorer-top-tools">
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" :date-range="timeFilter.dateRangeValue" ref="dateTimeRange" @change="reload"/>
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
<div class="explorer-top-tools-title">{{$t('overall.detections')}}</div>
<div style="display: flex">
<div class="explorer-top-tools-block">
<i class="cn-icon cn-icon-setting detection-icon-setting"></i>
<span>Configure Policies</span>
</div>
<DateTimeRange
class="date-time-range"
:start-time="timeFilter.startTime"
:end-time="timeFilter.endTime"
:date-range="timeFilter.dateRangeValue"
ref="dateTimeRange"
@change="reload"/>
<TimeRefresh
class="date-time-range"
@change="timeRefreshChange"
:end-time="timeFilter.endTime"/>
</div>
</div>
<div style="width: 100%;padding-bottom: 26px;">
<detection-tabs :time-filter="timeFilter" :chart="tabsData" />
</div>
<!-- 搜索组件 -->
<detection-search
class="detection-border"
ref="search"
:page-type="pageType"
@search="search"
></detection-search>
<!-- 内容区 -->
<div class="explorer-container" style="height: calc(100% - 20px); flex-direction: column">
<div class="explorer-container" style="height: calc(100% - 20px);flex-direction: column">
<loading :loading="loading"></loading>
<template v-if="isEventSeverityNoData">
<div class="no-data detection__event-severity-bar" >No data</div>
</template>
<template v-if="!isEventSeverityNoData">
<div class="detection__event-severity-bar" :id="`eventSeverityTrendBar${pageType}`">
<div class="detection__event-severity-bar detection-border" :id="`eventSeverityTrendBar${pageType}`">
</div>
</template>
<div style="display: flex; flex-grow: 1; height: 100%;">
<detection-filter
class="detection-border"
:filter-data="filterData[pageType]"
:q="q"
:time-filter="timeFilter"
></detection-filter>
<div class="detection__list">
<div class="detection__list-statistics">
<div class="detection__list-statistics detection-border">
<div class="statistics__severity">
<div class="chart-header">
<div class="chart-header__title">{{$t('detection.severity')}}</div>
@@ -81,15 +101,14 @@
></detection-list>
<div class="entity__pagination" >
<Pagination
ref="pagination"
:page-obj="pageObj"
@pageNo='pageNo'
@pageSize='pageSize'
@size-change="pageSize"
@prev-click="prev"
@next-click="next"
>
</Pagination>
ref="pagination"
:page-obj="pageObj"
@pageNo='pageNo'
@pageSize='pageSize'
@size-change="pageSize"
@prev-click="prev"
@next-click="next"
></Pagination>
</div>
</div>
</div>
@@ -108,12 +127,13 @@ import { defaultPageSize, detectionPageType } from '@/utils/constants'
import { getNowTime, getSecond, rTime } from '@/utils/date-util'
import { ref, shallowRef } from 'vue'
import * as echarts from 'echarts'
import { multipleBarOption, pieForSeverity, activeAttackBar, getAttackColor, getSeverityColor, getSeriesIndex } from '@/views/detections/options/detectionOptions'
import { multipleBarOption, pieForSeverity, activeAttackBar, getAttackColor, getSeverityColor } from '@/views/detections/options/detectionOptions'
import { api, getData } from '@/utils/api'
import { reverseSortBy, sortBy, extensionEchartY } from '@/utils/tools'
import { reverseSortBy, extensionEchartY } from '@/utils/tools'
import { useRoute } from 'vue-router'
import DetectionNoData from '@/views/detections/DetectionNoData'
// import DetectionNoData from '@/views/detections/DetectionNoData'
import Loading from '@/components/common/Loading'
import DetectionTabs from '@/views/detections/DetectionTabs'
export default {
name: 'Index',
@@ -125,10 +145,32 @@ export default {
DetectionFilter,
DetectionList,
Pagination,
DetectionNoData
// DetectionNoData,
DetectionTabs
},
data () {
return {
tabsData: [
// todo icon名称可能不一致后续改
{
name: 'SecurityEvents',
i18n: 'entities.securityEvents',
path: '/detection/securityEvent',
icon: 'cn-icon cn-icon-SecurityEvent'
},
{
name: 'Regulatory Risk Event',
i18n: 'entities.regulatoryRiskEvents',
path: '/detection/securityEvent',
icon: 'cn-icon cn-icon-RegulatoryRiskEvent'
},
{
name: 'PerformanceEvents',
i18n: 'overall.performanceEvents',
path: '/detection/performanceEvent',
icon: 'cn-icon cn-icon-PerformanceEvent'
}
],
chartInit: [],
pageObj: {
pageNo: 1,
@@ -231,7 +273,6 @@ export default {
isStatisticsCategoryNoData: false,
isStatisticsActiveAttackNoData: false,
loading: false,
oldActiveEntitySearchValue: ''
}
},
@@ -270,8 +311,10 @@ export default {
const seriesData = []
xData.forEach(item => {
if (dataMap.has(serie.name)) {
// todo 下面这行注释可解决eslint报红线的问题暂不知道原因后续解决
// eslint-disable-next-line array-callback-return
const hasX = dataMap.get(serie.name).some(function (v) {
if (item == v[0]) {
if (item === v[0]) {
seriesData.push(Number(v[1]))
return true
}
@@ -296,7 +339,7 @@ export default {
// this.isEventSeverityNoData = true
}
}).catch(error => {
console.log(error)
}).finally(() => {
this.$nextTick(() => {
this.loading = false
@@ -329,7 +372,7 @@ export default {
})
}
}).catch(error => {
console.log(error)
})
},
initEventTypeData (params) {
@@ -357,7 +400,7 @@ export default {
})
}
}).catch(error => {
console.log(error)
})
},
initSecurityTypeData (params) {
@@ -385,7 +428,7 @@ export default {
})
}
}).catch(error => {
console.log(error)
})
},
initOffenderIpData (params) {
@@ -419,7 +462,7 @@ export default {
})
}
}).catch(error => {
console.log(error)
})
},
@@ -430,7 +473,7 @@ export default {
this.filterData[this.pageType][2].showMore = showMore
this.filterData[this.pageType][2].showIndex = showIndex
}).catch(error => {
console.log(error)
})
},
initVictimLocationData (params) {
@@ -440,7 +483,7 @@ export default {
this.filterData[this.pageType][3].showMore = showMore
this.filterData[this.pageType][3].showIndex = showIndex
}).catch(error => {
console.log(error)
})
},
initOffenderLocationData (params) {
@@ -450,7 +493,7 @@ export default {
this.filterData[this.pageType][5].showMore = showMore
this.filterData[this.pageType][5].showIndex = showIndex
}).catch(error => {
console.log(error)
})
},
initActiveEntity (params) {
@@ -510,6 +553,7 @@ export default {
})
}
}).catch(error => {
console.log(error)
})
},
triggerFilterDataValue (array, value) {
@@ -539,12 +583,12 @@ export default {
getData(api.detection[this.pageType].listBasic, params).then(data => {
this.listData = data
}).catch(error => {
console.log(error)
})
getData(api.detection[this.pageType].listCount, params).then(data => {
this.pageObj.total = data
}).catch(error => {
console.log(error)
})
},
timeRefreshChange () {
@@ -789,3 +833,33 @@ export default {
}
}
</script>
<style>
.explorer-top-tools-title {
font-size: 24px;
line-height: 24px;
font-weight: 900;
color: #353636;
}
.explorer-top-tools-block {
font-family: NotoSansHans-Medium;
height: 28px;
line-height: 28px;
font-size: 14px;
color: #353636;
font-weight: 500;
padding: 0 10px;
margin-right: 10px;
border: 1px solid #E0E0E0;
border-radius: 2px;
cursor: pointer;
}
.detection-icon-setting {
margin-right: 10px;
font-size: 14px;
}
.detection-border {
border: 1px solid #E0E0E0;
border-radius: 4px;
}
</style>