CN-983 feat: 基本信息图的基本样式
This commit is contained in:
@@ -1,3 +1,57 @@
|
||||
.entity-detail {
|
||||
.entity-tag {
|
||||
display: flex;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
border: 1px solid;
|
||||
border-radius: 2px;
|
||||
|
||||
&.entity-tag--small {
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
$normal-color: #778391;
|
||||
$normal-light-color: #F7F8F9;
|
||||
$negative-color: #E26154;
|
||||
$negative-light-color: #FEF6F5;
|
||||
$positive-color: #749F4D;
|
||||
$positive-light-color: #F7FAF5;
|
||||
&.entity-tag--level-one-normal {
|
||||
border-color: $normal-color;
|
||||
color: white;
|
||||
background-color: $normal-color;
|
||||
}
|
||||
&.entity-tag--level-one-negative {
|
||||
border-color: $negative-color;
|
||||
color: white;
|
||||
background-color: $negative-color;
|
||||
}
|
||||
&.entity-tag--level-one-positive {
|
||||
border-color: $positive-color;
|
||||
color: white;
|
||||
background-color: $positive-color;
|
||||
}
|
||||
&.entity-tag--level-two-normal {
|
||||
border-color: $normal-color;
|
||||
color: $normal-color;
|
||||
background-color: $normal-light-color;
|
||||
}
|
||||
&.entity-tag--level-two-negative {
|
||||
border-color: $negative-color;
|
||||
color: $negative-color;
|
||||
background-color: $negative-light-color;
|
||||
}
|
||||
&.entity-tag--level-two-positive {
|
||||
border-color: $positive-color;
|
||||
color: $positive-color;
|
||||
background-color: $positive-light-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
.entity-detail.cn-home {
|
||||
.panel-chart {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "cn-icon"; /* Project id 2614877 */
|
||||
src: url('iconfont.woff2?t=1683252401572') format('woff2'),
|
||||
url('iconfont.woff?t=1683252401572') format('woff'),
|
||||
url('iconfont.ttf?t=1683252401572') format('truetype');
|
||||
src: url('iconfont.woff2?t=1683361452726') format('woff2'),
|
||||
url('iconfont.woff?t=1683361452726') format('woff'),
|
||||
url('iconfont.ttf?t=1683361452726') format('truetype');
|
||||
}
|
||||
|
||||
.cn-icon {
|
||||
@@ -13,7 +13,27 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.cn-icon-Duration:before {
|
||||
.cn-icon-dns-insight:before {
|
||||
content: "\e7ef";
|
||||
}
|
||||
|
||||
.cn-icon-network-performance:before {
|
||||
content: "\e7f0";
|
||||
}
|
||||
|
||||
.cn-icon-network-overview:before {
|
||||
content: "\e7f1";
|
||||
}
|
||||
|
||||
.cn-icon-copy:before {
|
||||
content: "\e7ee";
|
||||
}
|
||||
|
||||
.cn-icon-analysis:before {
|
||||
content: "\e7ed";
|
||||
}
|
||||
|
||||
.cn-icon-duration:before {
|
||||
content: "\e7ec";
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1253,3 +1253,21 @@ export function getWidthByLanguage (language) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function selectElementText (el) {
|
||||
const range = document.createRange() // create new range object
|
||||
range.selectNodeContents(el) // set range to encompass desired element text
|
||||
const selection = window.getSelection() // get Selection object from currently user selected text
|
||||
selection.removeAllRanges() // unselect any user selected text (if any)
|
||||
selection.addRange(range) // add range to Selection object to select it
|
||||
}
|
||||
|
||||
export function copySelectionText () {
|
||||
let copySuccess // var to check whether execCommand successfully executed
|
||||
try {
|
||||
copySuccess = document.execCommand('copy') // run command to copy selected text to clipboard
|
||||
} catch (e) {
|
||||
copySuccess = false
|
||||
}
|
||||
return copySuccess
|
||||
}
|
||||
|
||||
@@ -1,12 +1,351 @@
|
||||
<template>
|
||||
<div style="border: 1px solid #ff5500; height: 100%;">{{entity}}</div>
|
||||
<div class="entity-detail-basic-info">
|
||||
<div class="entity-type">{{entityType[entity.entityType]}}</div>
|
||||
<div class="entity-basic-info">
|
||||
<div class="entity-basic-info__name">
|
||||
<span id="entityName">{{entity.entityName}}</span>
|
||||
<div @click="copyEntityName"><i class="cn-icon cn-icon-copy"></i></div>
|
||||
</div>
|
||||
<el-popover
|
||||
placement="bottom-end"
|
||||
:width="390"
|
||||
trigger="click"
|
||||
popper-class="analysis-popper"
|
||||
@show="analysisPopSwitch(true)"
|
||||
@hide="analysisPopSwitch(false)"
|
||||
>
|
||||
<template #reference>
|
||||
<div class="analysis-btn" :class="{'analysis-btn--active': analysisPopShow}"><i class="cn-icon cn-icon-analysis"></i>{{$t('overall.analysis')}}</div>
|
||||
</template>
|
||||
<div class="analysis-entry">
|
||||
<div class="analysis-entry__header">{{$t('entities.fastEntry')}}</div>
|
||||
<div class="analysis-entry__body">
|
||||
<div class="analysis-entry-item" v-for="item in analysisItems" :key="item.label" @click="jump(item.url)">
|
||||
<div>
|
||||
<i :class="item.icon"></i>
|
||||
</div>
|
||||
<span>{{item.label}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="entity-tags">
|
||||
<div v-for="tag in levelTwoTags" :key="tag.value" class="entity-tag" :class="`entity-tag--level-two-${tag.type}`">{{tag.value}}</div>
|
||||
</div>
|
||||
<!-- 分割线-->
|
||||
<div class="dividing-line"></div>
|
||||
<div class="entity-detail-info">
|
||||
<div class="detail-card" v-for="card in detailCards" :key="card.name">
|
||||
<i :class="card.icon"></i>
|
||||
<div class="detail-card__text">
|
||||
<div class="detail-card__label">{{card.label}}:</div>
|
||||
<div class="detail-card__value">{{card.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.theme-light .el-popper.analysis-popper {
|
||||
top: -5px !important;
|
||||
padding: 0;
|
||||
border: 1px solid #C5C5C5;
|
||||
border-radius: 4px;
|
||||
box-shadow: -1px 1px 10px -1px rgba(205,205,205,0.85);
|
||||
|
||||
.el-popper__arrow {
|
||||
display: none;
|
||||
}
|
||||
.analysis-entry {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.analysis-entry__header {
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
background-color: #F7F7F7;
|
||||
padding-left: 20px;
|
||||
color: #353636;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.analysis-entry__body {
|
||||
display: flex;
|
||||
height: 134px;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.analysis-entry-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
div i, span {
|
||||
color: #046ECA;
|
||||
}
|
||||
}
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 9px;
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
border-radius: 50%;
|
||||
background-color: #F5F6F8;
|
||||
|
||||
i {
|
||||
color: #353636;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
span {
|
||||
font-size: 12px;
|
||||
color: #353636;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.entity-detail-basic-info {
|
||||
position: relative;
|
||||
padding: 35px 30px 0 30px;
|
||||
height: 100%;
|
||||
border: 1px solid #E2E5EC;
|
||||
border-radius: 4px;
|
||||
|
||||
.dividing-line {
|
||||
position: absolute;
|
||||
top: 169px;
|
||||
left: 30px;
|
||||
height: 1px;
|
||||
width: calc(100% - 60px);
|
||||
background-color: #EFF2F5;
|
||||
}
|
||||
.entity-type {
|
||||
color: #717171;
|
||||
}
|
||||
.entity-basic-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.entity-basic-info__name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
padding-right: 12px;
|
||||
font-family: Helvetica-Bold;
|
||||
font-size: 32px;
|
||||
color: #353636;
|
||||
font-weight: bold;
|
||||
}
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
background-color: #EFF1F4;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
color: #717171;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.analysis-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 24px;
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
color: #046ECA;
|
||||
cursor: pointer;
|
||||
background-color: #FFF;
|
||||
transition: background-color linear .2s;
|
||||
|
||||
&.analysis-btn--active {
|
||||
background-color: #EBF7FA;
|
||||
border-radius: 2px;
|
||||
}
|
||||
i {
|
||||
padding-right: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.entity-tags {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 70px;
|
||||
|
||||
.entity-tag {
|
||||
margin-right: 10px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.entity-detail-info {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-content: space-around;
|
||||
margin-top: 5px;
|
||||
height: calc(100% - 135px);
|
||||
|
||||
.detail-card {
|
||||
display: flex;
|
||||
padding: 0 12px;
|
||||
width: 298px;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 22px;
|
||||
color: #353636;
|
||||
margin-right: 14px;
|
||||
}
|
||||
.detail-card__text {
|
||||
.detail-card__label {
|
||||
margin-bottom: 6px;
|
||||
font-size: 12px;
|
||||
color: #717171;
|
||||
}
|
||||
.detail-card__value {
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import chartMixin from '@/views/charts2/chart-mixin'
|
||||
import { drillDownPanelTypeMapping, entityType } from '@/utils/constants'
|
||||
import { selectElementText, copySelectionText } from '@/utils/tools'
|
||||
import { ref } from 'vue'
|
||||
import i18n from '@/i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'EntityDetailBasicInfo',
|
||||
mixins: [chartMixin]
|
||||
mixins: [chartMixin],
|
||||
mounted () {
|
||||
this.toggleLoading(false)
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// type: positive 正面的,绿色;normal 灰色;negative 负面的,红色
|
||||
levelTwoTags: [{ value: '安全', type: 'positive' }, { value: '工具', type: 'normal' }, { value: '恶意IP', type: 'negative' }],
|
||||
analysisPopShow: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyEntityName () {
|
||||
selectElementText(document.getElementById('entityName'))
|
||||
if (copySelectionText()) {
|
||||
this.$message.success(this.$t('tip.copySuccess'))
|
||||
} else {
|
||||
this.$message.error('Unknown error')
|
||||
}
|
||||
},
|
||||
analysisPopSwitch (show) {
|
||||
this.analysisPopShow = show
|
||||
},
|
||||
jump (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const analysisItems = ref([])
|
||||
|
||||
// 生成url
|
||||
const resolvePath = (router) => {
|
||||
const { href } = useRouter().resolve(router)
|
||||
return href
|
||||
}
|
||||
// 右上角analysis按钮
|
||||
switch (props.entity.entityType) {
|
||||
default: {
|
||||
analysisItems.value.push({
|
||||
icon: 'cn-icon cn-icon-overview',
|
||||
label: i18n.global.t('networkOverview.networkOverview'),
|
||||
url: resolvePath({
|
||||
path: '/panel/networkOverview',
|
||||
query: {
|
||||
queryCondition: `common_client_ip='${props.entity.entityName}' OR common_server_ip='${props.entity.entityName}'`,
|
||||
panelName: props.entity.entityName,
|
||||
thirdMenu: 'network.ips',
|
||||
dimensionType: 'ip',
|
||||
fourthMenu: props.entity.entityName,
|
||||
thirdPanel: drillDownPanelTypeMapping.networkOverview,
|
||||
fourthPanel: drillDownPanelTypeMapping.networkOverview
|
||||
}
|
||||
})
|
||||
})
|
||||
analysisItems.value.push({
|
||||
icon: 'cn-icon cn-icon-network-performance',
|
||||
label: i18n.global.t('entities.networkPerformance'),
|
||||
url: resolvePath({
|
||||
path: '/panel/networkAppPerformance',
|
||||
query: {
|
||||
queryCondition: `common_client_ip='${props.entity.entityName}' OR common_server_ip='${props.entity.entityName}'`,
|
||||
panelName: props.entity.entityName,
|
||||
thirdMenu: 'network.ips',
|
||||
dimensionType: 'ip',
|
||||
fourthMenu: props.entity.entityName,
|
||||
thirdPanel: drillDownPanelTypeMapping.npmThirdMenu,
|
||||
fourthPanel: drillDownPanelTypeMapping.npmOverviewIp
|
||||
}
|
||||
})
|
||||
})
|
||||
analysisItems.value.push({
|
||||
icon: 'cn-icon cn-icon-dns-insight',
|
||||
label: i18n.global.t('dns.dnsInsights'),
|
||||
url: resolvePath({
|
||||
path: '/panel/dnsServiceInsights',
|
||||
query: {
|
||||
queryCondition: `common_client_ip='${props.entity.entityName}' OR common_server_ip='${props.entity.entityName}'`,
|
||||
panelName: props.entity.entityName,
|
||||
thirdMenu: 'dns.dnsServer',
|
||||
dimensionType: 'dnsServer',
|
||||
fourthMenu: props.entity.entityName,
|
||||
thirdPanel: drillDownPanelTypeMapping.dnsThirdMenu,
|
||||
fourthPanel: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
// 底部各属性
|
||||
const detailCards = ref([])
|
||||
switch (props.entity.entityType) {
|
||||
case 'ip': {
|
||||
detailCards.value = _.concat(detailCards.value,
|
||||
{ icon: 'cn-icon cn-icon-as', name: 'asNumber', label: i18n.global.t('entities.asNumber'), value: 'aaaaaaaaaaaa' },
|
||||
{ icon: 'cn-icon cn-icon-registration-agency', name: 'asOrg', label: i18n.global.t('entities.asOrg'), value: 'this is agency a that word indispensable' },
|
||||
{ icon: 'cn-icon cn-icon-as-subnet', name: 'asSubnet', label: i18n.global.t('entities.asSubnet'), value: 'bbbaee' },
|
||||
{ icon: 'cn-icon cn-icon-operator', name: 'isp', label: 'ISP', value: 'aerae343331' },
|
||||
{ icon: 'cn-icon cn-icon-geo-location', name: 'location', label: i18n.global.t('entities.geographicLocation'), value: '你好啊' },
|
||||
{ icon: 'cn-icon cn-icon-dns-ptr', name: 'dnsPtr', label: 'DNS PTR', value: '-' }
|
||||
)
|
||||
}
|
||||
}
|
||||
return {
|
||||
entityType,
|
||||
analysisItems,
|
||||
detailCards
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user