Merge branch 'dev-3.4' of git.mesalab.cn:nezha/nezha-fronted into dev-3.4

This commit is contained in:
zyh
2022-07-21 10:50:51 +08:00
20 changed files with 512 additions and 95 deletions

View File

@@ -221,7 +221,7 @@
align-items: center;
justify-content: center;
height: 70px;
box-shadow: -3px 0 8px -3px rgba(205,205,205,0.77);
box-shadow: $--right-box-shadow;
}
.footer__btn {
margin: 0 15px;

View File

@@ -59,6 +59,10 @@
width: calc(100% - 120px);
display: flex;
align-items: center;
div.active-icon.green-bg{
width: 8px !important;
margin-top: 0 !important;
}
>div{
width: calc(100% - 30px);
}

View File

@@ -4,17 +4,22 @@
}
.right-box-project-endpoint,.right-box-project-asset {
padding-right: 10px;
padding-left: 10px;
}
.right-box-project-alert {
width: 850px;
padding-right: 10px;
padding-left: 10px;
}
.right-box-title {
font-weight: bold;
padding-left: 20px;
padding-top: 20px;
position: absolute;
z-index: 1;
display: flex;
align-items: center;
}
.mc {

View File

@@ -1,20 +1,30 @@
.about {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
padding: 20px 20px 10px 20px;
background-color: $--background-color-empty;
//border: 10px solid $--background-color-base;
box-sizing: border-box;
.app{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 140px;
background-color: $--background-color-2;
}
.about-label {
color: $--color-text-secondary;
}
.app-header {
display: flex;
min-width: 360px;
justify-content: center;
align-items: center;
border-right: 2px solid $--border-color-light;
padding-right: 20px;
margin-right: 20px;
// min-width: 360px;
.header-logo {
font-size: 0;
@@ -22,19 +32,20 @@
}
.header-title {
padding-left: 20px;
padding-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
justify-content: center;
.app-name {
font-weight: bold;
line-height: 50px;
line-height: 30px;
font-size: 20px;
color: $--color-text-primary;
}
.app-version {
padding-left: 1px;
font-size: 14px;
color: $--color-text-primary;
font-weight: 400;
@@ -43,28 +54,107 @@
}
.app-component {
width: 360px;
margin-top: 35px;
.component-title {
color: $--color-text-secondary;
height: 30px;
font-size: 14px;
line-height: 30px;
border-bottom: 1px solid $--color-text-secondary;
}
display: flex;
justify-content: space-between;
align-items: center;
.component-content {
padding-top: 8px;
}
.app-component-row {
line-height: 28px;
display: flex;
color: $--color-text-primary;
font-size: 16px;
font-weight: 400;
justify-content: space-between;
// padding-top: 8px;
.app-component-row {
line-height: 28px;
display: flex;
color: $--color-text-primary;
font-size: 14px;
font-weight: 400;
justify-content: space-between;
}
.component-name{
color: $--color-text-regular;
margin-right: 20px;
}
}
}
.time-line{
width: 100%;
height: calc(100% - 160px);
.time-line-title{
margin-top: 20px;
width: 100%;
padding-bottom: 10px;
color: $--color-text-regular;
font-size: 14px;
font-weight: 700;
}
.time-line-body{
width: 100%;
height: 96%;
padding: 30px 30px 0 35px;
border: 1px solid $--border-color-light;
box-sizing: border-box;
overflow-y: auto;
.el-timeline-item{
padding-bottom: 0;
}
.about-summary{
display: flex;
justify-content: start;
align-items: center;
padding-top: 6px;
line-height: 21px;
.dot{
width: 6px;
height: 6px;
border-radius: 50%;
background-color: $--color-info;
margin-right: 5px;
}
.about-summary-text{
font-size: 14px;
color: $--color-text-regular;
}
}
}
}
.el-timeline-item__node.el-timeline-item__node--normal.el-timeline-item__node--{
position: relative;
box-sizing: border-box;
width: 18px;
height: 18px;
border: 1px solid $--color-primary;
background-color: $--background-color-empty;
z-index: 3;
}
.el-timeline-item__node.el-timeline-item__node--normal.el-timeline-item__node--::before{
content: "";
width: 12px;
height: 12px;
border-radius: 50%;
background-color: $--color-primary;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
z-index: 3;
}
.el-timeline-item__tail{
border-left: 1px solid rgba(250,144,28,0.12);
left: 8px;
}
.el-timeline-item__wrapper{
top:-21px;
padding-left: 38px;
.el-timeline-item__timestamp.is-top{
font-size: 16px;
color: $--color-text-primary;
margin-bottom: 5px;
}
}
}

View File

@@ -139,3 +139,27 @@
.el-collapse-item__header {
border-bottom: 1px solid $--border-color-light;
}
.main-list--project.main-list{
.project.projectTopo{
.project-box.list-page{
.mc{
.right-box{
td{
.cell{
padding-right: 11px !important;
}
}
.cell{
padding: 0 10px !important;
.el-checkbox__inner{
box-sizing: border-box;
width: 15px;
height: 15px;
}
}
}
}
}
}
}

View File

@@ -176,7 +176,8 @@ export default {
scrollTop: 0,
scrollTopTimer: null,
// 变量比较结果 图表是否显示/隐藏
showHidden: {}
showHidden: {},
tempList: []
}
},
methods: {
@@ -440,6 +441,7 @@ export default {
},
// 比较变量 图表是否显示/隐藏
compareVariables () {
console.log(123123123123)
if (!this.panelLock) {
return false
}
@@ -507,6 +509,24 @@ export default {
})
}
})
// this.copyDataList.forEach((item, index) => {
// if (!this.showHidden[item.id] && item.id !== -2) {
// delete this.copyDataList[index]
// }
// })
for (let i = 0; i < this.copyDataList.length; i++) {
const item = this.copyDataList[i]
if ((this.showHidden[item.id] && this.showHidden[item.id] === 'hidden') && item.id !== -2) {
this.copyDataList.splice(i, 1)
i--
}
}
this.tempList.forEach(item => {
if ((!this.showHidden[item.id] || this.showHidden[item.id] === 'show') && item.id !== -2 && !this.copyDataList.find(chart => chart.id === item.id)) {
this.copyDataList.push(item)
}
})
this.onScroll(this.scrollTop)
}
},
created () {
@@ -549,6 +569,12 @@ export default {
handler (flag) {
if (!flag) {
this.showHidden = {}
this.tempList.forEach(item => {
if (!this.copyDataList.find(chart => chart.id === item.id)) {
this.copyDataList.push(item)
}
})
this.onScroll(this.scrollTop)
} else {
// 比较变量 图表是否显示/隐藏
this.compareVariables()
@@ -618,6 +644,7 @@ export default {
})
}
this.$nextTick(() => {
this.tempList = JSON.parse(JSON.stringify(tempList))
this.copyDataList = JSON.parse(JSON.stringify(tempList))
// 比较变量 图表是否显示/隐藏
this.compareVariables()

View File

@@ -546,12 +546,23 @@ export default {
},
variablesReplace (expression) {
let str = expression
let confirmReg = ''
let confirmRegItem = ''
this.variablesArr.forEach(item => {
const reg = new RegExp('\\$' + item.name, 'g') // 后续需要考虑 item,name 使用特殊字符的问题
if (reg.test(expression)) {
str = str.replace(reg, item.checked.map(label => label.replace(/\"/g, '\\"').replace(/\'/g, "\\'")).join('|'))
const reg = '$' + item.name // 后续需要考虑 item,name 使用特殊字符的问题
const index = expression.indexOf(reg)
if (index !== -1) {
if (reg.length > confirmReg.length) {
confirmReg = reg
confirmRegItem = item
}
}
})
if (confirmReg) {
const index = expression.indexOf(confirmReg)
const replaceStr = confirmRegItem.checked.map(label => label.replace(/\"/g, '\\"').replace(/\'/g, "\\'")).join('|')
str = str.substring(0, index) + replaceStr + str.substring(index + confirmReg.length)
}
return str
},
getHexagonFigureData () {

View File

@@ -823,9 +823,11 @@ const Topology = /** @class */ (function () {
this.setupMouseEvent()
// Wait for parent dom load
setTimeout(function () {
if (!_this.divLayer) return
_this.canvasPos = _this.divLayer.canvas.getBoundingClientRect()
}, 500)
setTimeout(function () {
if (!_this.divLayer) return
_this.canvasPos = _this.divLayer.canvas.getBoundingClientRect()
}, 1000)
this.cache()
@@ -1300,6 +1302,9 @@ const Topology = /** @class */ (function () {
return this
}
this.rendering = true
if (!this.offscreen ) {
return
}
// 获取 ctx 对象
const ctx = this.offscreen.canvas.getContext('2d')
ctx.clearRect(0, 0, this.offscreen.canvas.width, this.offscreen.canvas.height)
@@ -2510,6 +2515,7 @@ const Topology = /** @class */ (function () {
}
this.cacheTimer = setTimeout(function () {
let _a
if (!this.animateLayer) return
_this.animateLayer.readyPlay(undefined, true)
_this.animateLayer.animate();
(_a = _this.cache) === null || _a === void 0 ? void 0 : _a.call(_this)

View File

@@ -1,5 +1,5 @@
<template>
<div :class="calcHeight(that.position,that)" :style="calcPosition(that.position,that)" class="alert-label__border" ref="alertLabels"
<div style="padding:15px" :class="calcHeight(that.position,that)" :style="calcPosition(that.position,that)" class="alert-label__border" ref="alertLabels"
@mouseenter="tooltipHover(true)"
@mouseleave="tooltipHover(false)">
<slot name="default"/>

View File

@@ -201,7 +201,7 @@ export default {
const reg = new RegExp(item.regex)
if (!reg.test(meta.value)) {
meta.value = ''
this.$message.error(this.$t(item.tip))
this.$message.error(this.$t('FILTER_PROJECT_IS_NULL'))
break
}
}

View File

@@ -1,18 +1,18 @@
<template>
<el-skeleton style="height: 100%;width: 100%" :loading="loading || faLoading" animated>
<template slot="template">
<div class="search-item-box">
<div class="search-item-box" style="padding-top:70px;padding-left:75px;padding-right:45px">
<div class="search-item-title-icon">
<el-skeleton-item
variant="image"
style="width: 60px; height: 60px;"
style="width: 40px; height: 40px;"
/>
</div>
<el-skeleton-item class="search-item-path" search-item-path variant="h3" style="width: 50%;" />
<el-skeleton-item class="search-item-name" search-item-path variant="h3" style="width: 30%" />
<el-skeleton-item class="search-item-path" search-item-path variant="h3" style="width: 30%;height: 21px;margin-top: 16px;margin-bottom: 16px" />
<el-skeleton-item class="search-item-name" search-item-path variant="h3" style="width: 50%;height: 30px;margin-bottom: 30px" />
<div v-for="item in skeletonArr" :key="item" class="search-item-info">
<el-skeleton-item class="search-item-key"/>
<el-skeleton-item class="search-item-value-box" style="margin-left: 20px;height: 13px"/>
<el-skeleton-item class="search-item-key" style="height: 21px"/>
<el-skeleton-item class="search-item-value-box" style="width: 57%;margin-left: 20px;height: 21px;margin-top: 13px;margin-bottom: 13px"/>
</div>
</div>
</template>

View File

@@ -252,7 +252,7 @@ export default {
this.$refs.emailForm.clearValidate()
}
if (type == 'monitor') {
localStorage.setItem('nz-prometheus-federation-enabled', this.monitor.prometheus_federation_enabled)
}
this[type + 'Copy'] = Object.assign({}, this[type])
}

View File

@@ -368,16 +368,19 @@ export default {
})
item.checked = item.checkAll ? allValue : []
item.isIndeterminate = false
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
if (!item.multi) {
this.close()
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
}
},
checkedChange (item, value) {
const checkedCount = value.length
item.checkAll = checkedCount === this.labelValue[item.name].length
item.isIndeterminate = checkedCount > 0 && checkedCount < this.labelValue[item.name].length
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
},
selectLabelValue (item, value) {
item.checked = [value.value]
this.close()
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
},
triggerVisible (item) {
@@ -387,6 +390,9 @@ export default {
},
close () {
this.labelArr.forEach((item) => {
if (item.visible && item.multi) {
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
}
item.visible = false
})
}

View File

@@ -95,7 +95,8 @@
<el-col class="legend-title">
<span class="legend-title__span">{{$t('dashboard.panel.chartForm.legend')}}&nbsp;</span>
<el-popover placement="top" trigger="hover" width="211" popper-class="prevent-clickoutside">
<div :style="{'word-break':language!=='cn'?'keep-all':'break-all'}">{{$t('dashboard.panel.chartForm.legendTip')}}</div>
<div style="word-break:break-all; white-space: normal">{{$t('dashboard.panel.chartForm.legendTip')}}</div>
<!-- <div :style="{'word-break':language!=='cn'?'keep-all':'break-all'}">{{$t('dashboard.panel.chartForm.legendTip')}}</div> -->
<i @mouseover="rz" class="nz-icon nz-icon-info-normal" slot="reference" style="font-size: 14px; -webkit-transform:scale(0.75);display:inline-block;"></i>
</el-popover>
</el-col>
@@ -691,26 +692,21 @@
</div>
<el-form-item :prop="'param.valueMapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" :placeholder="$t('placeholder.chart.display')" size="small" @change="change('valueMapping', index)" class="mapping-display-input">
<el-popover
slot="prefix"
placement="top-start"
trigger="manual"
popper-class="mapping-iconPop no-style-class"
v-clickoutside="()=>{closeChoose(index)}"
v-model="isChoose[index]"
>
<ul class="mapping-iconList">
<li class="mapping-iconItem" :class="{active:item.icon===subItem.value}" v-for="subItem in mappingIconList" @click="iconActive(item,subItem,index)" :key="subItem.value">
<i :class="subItem.value"></i>
</li>
</ul>
<div slot="reference" @click="chooseIcon(isChoose[index],index)">
<el-dropdown trigger="click" slot="prefix" placement="top-start">
<div class="el-dropdown-link">
<i v-if="item.icon" class="mapping-icon" :class="item.icon" :style="{ color: item.color.icon }"></i>
<div v-else class="mapping-iconSelect" :title="$t('tip.add')">
<i class="nz-icon nz-icon-create-square"></i>
</div>
</div>
</el-popover>
<el-dropdown-menu slot="dropdown" class="mapping-iconPop">
<ul class="mapping-iconList">
<li class="mapping-iconItem" :class="{active:item.icon===subItem.value}" v-for="subItem in mappingIconList" @click="iconActive(item,subItem,index)" :key="subItem.value">
<i :class="subItem.value"></i>
</li>
</ul>
</el-dropdown-menu>
</el-dropdown>
</el-input>
</el-form-item>
<nezhaColor
@@ -730,7 +726,7 @@
</div>
<!-- visibility -->
<div>
<div v-if="params.type === 'group'">
<div class="form__sub-title">
<span>{{$t('dashboard.panel.showHidden')}}</span>
<el-switch
@@ -819,8 +815,12 @@
size="small"
@change="change"
>
<el-option label="Show" value="show"></el-option>
<el-option label="Hidden" value="hidden"></el-option>
<el-option
v-for="item in showHidden"
:key="item.id"
:label="item.name"
:value="item.id">{{item.name}}</el-option>
<!-- <el-option value="hidden">{{$t('overall.hidden')}}</el-option> -->
</el-select>
</el-form-item>
</div>
@@ -873,6 +873,15 @@ export default {
oldType: '',
tag: '',
promqlType: 'log',
showHidden: [
{
id: 'show',
name: this.$t('overall.show')
}, {
id: 'hidden',
name: this.$t('overall.hidden')
}
],
chartTypeList: [
{
id: 'line',

View File

@@ -600,6 +600,12 @@ export default {
handler (n) {
if (n === 'group') {
this.editChart.groupId = ''
} else {
this.editChart.param.enable.visibility = false
this.editChart.param.visibility.varName = ''
this.editChart.param.visibility.operator = ''
this.editChart.param.visibility.varValue = ''
this.editChart.param.visibility.result = ''
}
}
},

View File

@@ -239,8 +239,8 @@
size="small"
@change="change"
>
<el-option label="Show" value="show"></el-option>
<el-option label="Hidden" value="hidden"></el-option>
<el-option :label="$t('overall.show')" value="show">{{$t('overall.show')}}</el-option>
<el-option :label="$t('overall.hidden')" value="hidden">{{$t('overall.hidden')}}</el-option>
</el-select>
</el-form-item>
</div>

View File

@@ -645,26 +645,21 @@
</div>
<el-form-item :prop="'param.valueMapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" :placeholder="$t('placeholder.chart.display')" size="small" @change="change('valueMapping', index)" class="mapping-display-input">
<el-popover
slot="prefix"
placement="top-start"
trigger="manual"
popper-class="mapping-iconPop no-style-class"
v-clickoutside="()=>{closeChoose(index)}"
v-model="isChoose[index]"
>
<ul class="mapping-iconList">
<li class="mapping-iconItem" :class="{active:item.icon===subItem.value}" v-for="subItem in mappingIconList" @click="iconActive(item,subItem,index)" :key="subItem.value">
<i :class="subItem.value"></i>
</li>
</ul>
<div slot="reference" @click="chooseIcon(isChoose[index],index)">
<el-dropdown trigger="click" slot="prefix" placement="top-start">
<div class="el-dropdown-link">
<i v-if="item.icon" class="mapping-icon" :class="item.icon" :style="{ color: item.color.icon }"></i>
<div v-else class="mapping-iconSelect" :title="$t('tip.add')">
<i class="nz-icon nz-icon-create-square"></i>
</div>
</div>
</el-popover>
<el-dropdown-menu slot="dropdown" class="mapping-iconPop">
<ul class="mapping-iconList">
<li class="mapping-iconItem" :class="{active:item.icon===subItem.value}" v-for="subItem in mappingIconList" @click="iconActive(item,subItem,index)" :key="subItem.value">
<i :class="subItem.value"></i>
</li>
</ul>
</el-dropdown-menu>
</el-dropdown>
</el-input>
</el-form-item>
<nezhaColor
@@ -774,8 +769,8 @@
size="small"
@change="change"
>
<el-option label="Show" value="show"></el-option>
<el-option label="Hidden" value="hidden"></el-option>
<el-option :label="$t('overall.show')" value="show">{{$t('overall.show')}}</el-option>
<el-option :label="$t('overall.hidden')" value="hidden">{{$t('overall.hidden')}}</el-option>
</el-select>
</el-form-item>
</div>

View File

@@ -33,7 +33,7 @@
<el-form-item :label='$t("config.mib.credential.writeCommunity")' prop="writeCommunity" v-if="editCredential.type ===1 || editCredential.type === 2">
<el-input placeholder="" autocomplete="new-password" maxlength="64" show-word-limit v-model="editCredential.config.writeCommunity" size="small" id="credential-box-input-writeCommunity" type="password" show-password></el-input>
</el-form-item>
<el-form-item :label='$t("profile.username")' prop="username" v-if="editCredential.type === 3">
<el-form-item :label='$t("profile.username")' prop="config.username" v-if="editCredential.type === 3">
<el-input placeholder="" maxlength="64" show-word-limit v-model="editCredential.config.username" size="small" id="credential-box-input-username"></el-input>
</el-form-item>
<el-form-item :label='$t("config.mib.credential.contextName")' prop="contextname" v-if="editCredential.type === 3">
@@ -50,7 +50,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item :label='$t("login.pin")' prop="authPin" v-if="editCredential.type === 3">
<el-form-item :label='$t("login.pin")' prop="authPin" v-if="editCredential.type === 3" :rules="[ { required: editCredential.config.authProtocol, message: this.$t('validate.required'), trigger: 'blur' }]">
<el-input placeholder="" autocomplete="new-password" v-model="editCredential.config.authPin" size="small" id="credential-box-input-authPin" type="password" show-password></el-input>
</el-form-item>
@@ -64,7 +64,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item :label='$t("login.pin")' prop="privPin" v-if="editCredential.type === 3">
<el-form-item :label='$t("login.pin")' prop="privPin" v-if="editCredential.type === 3" :rules="[ { required: editCredential.config.privProtocol, message: this.$t('validate.required'), trigger: 'blur' }]">
<el-input placeholder="" autocomplete="new-password" v-model="editCredential.config.privPin" size="small" id="credential-box-input-privPin" :disabled="!editCredential.config.authProtocol || editCredential.config.authProtocol === ''" type="password" show-password></el-input>
</el-form-item>
</el-form>
@@ -102,6 +102,9 @@ export default {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
'config.username': [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
remark: [
// { required: true, message: this.$t('validate.required'), trigger: 'blur' }
],

View File

@@ -1,14 +1,14 @@
<template>
<div class="about">
<div class="app-header">
<div class="header-logo"><img width="88" height="88" src="../../../assets/img/logo1-2.png"></div>
<div class="app">
<div class="app-header">
<div class="header-logo"><img width="60" height="60" src="../../../assets/img/logo1-2.png"></div>
<div class="header-title">
<div class="app-name">{{version.nezha.name}}</div>
<div class="app-version"><span class="about-label">{{$t("overall.version")}}&nbsp;&nbsp;&nbsp;</span><span>{{version.nezha.version}}</span></div>
</div>
</div>
<div class="app-component">
<div class="component-title">{{$t("overall.components")}}</div>
<div class="component-content">
<div class="app-component-row" v-for="(item, index) in version.components" :key="index">
<div class="component-name">{{item.name}}</div>
@@ -16,6 +16,25 @@
</div>
</div>
</div>
</div>
<div class="time-line">
<div class="time-line-title">{{$t('about.releaseNotes')}}</div>
<div class="time-line-body">
<el-timeline>
<el-timeline-item
v-for="(item) in activities"
:key="item.id"
:timestamp="item.timestamp ? item.timestamp : ''"
placement="top"
>
<div class="about-summary" v-for="(val) in item.content" :key="val.id">
<span class="dot"></span>
<div class="about-summary-text">{{language === "en" ? val.english :val.chinese}}</div>
</div>
</el-timeline-item>
</el-timeline>
</div>
</div>
</div>
</template>
<script>
@@ -23,10 +42,205 @@ export default {
name: 'about',
data () {
return {
noData: false,
timeLineData: [],
version: {
nezha: { name: '', version: '' },
components: [{ name: '', version: '' }]
}
},
activities: [{
timestamp: 'Release 22.08 - Aug 2022',
content: [{
id: 1,
chinese: '[FEATURE] 仪表盘增加快照导出功能',
english: '[FEATURE] Add snapshot export to dashboards'
}, {
id: 2,
chinese: '[FEATURE] 仪表盘支持定义变量变量可以在chart表达式中使用',
english: '[FEATURE] Dashboards support defining variables, which can be used in chart expressions'
}, {
id: 3,
chinese: '[FEATURE] 仪表盘支持定时生成报告并通过邮件发送给接收人',
english: '[FEATURE] Dashboards support scheduled generation of reports, which will be sent to receivers via email'
}, {
id: 4,
chinese: '[FEATURE] 列表文字支持快捷复制到剪切板',
english: '[FEATURE] Texts on the list can be copied to clipboard using shortcuts'
}, {
id: 5,
chinese: '[ENHANCEMENT] 图表表达式增加是否启用配置项',
english: '[ENHANCEMENT] Add whether to enable the configuration item for chart expressions'
}, {
id: 6,
chinese: '[ENHANCEMENT] 增加新增资产、新增业务系统等完成后的使用提示',
english: '[ENHANCEMENT] Add a prompt that appears after an asset or a project is created'
}]
}, {
timestamp: 'Release 22.05 - May 2022',
content: [{
id: 7,
chinese: '[FEATURE] Endpoint支持批量修改标签是否启用采集',
english: '[FEATURE] Endpoints support batch modification of label and whether to enable data gathering'
}, {
id: 8,
chinese: '[FEATURE] 仪表盘增加查看模式切换',
english: '[FEATURE] Add view mode switch to dashboards'
}, {
id: 9,
chinese: '[FEATURE] 仪表盘增加用户收藏功能 ',
english: '[FEATURE] Add user favorites to dashboards'
}, {
id: 10,
chinese: '[FEATURE] 分布式Pingtraceroute功能',
english: '[FEATURE] Support distributed Ping and Traceroute'
}, {
id: 11,
chinese: '[ENHANCEMENT] 丰富告警消息详情页面显示内容',
english: '[ENHANCEMENT] Enrich the content displayed in the alert details page'
}]
}, {
timestamp: 'Release 22.02 - Feb 2022',
content: [{
id: 12,
chinese: '[FEATURE] 新增 密码策略 配置,支持密码长度,复杂度,有效性,重试次数等配置项',
english: '[FEATURE] Add Password Policy configuration and support the configuration items including password length, complexity, effectiveness and retry times'
}, {
id: 13,
chinese: '[FEATURE] 丰富图表类型新增hexgon, treemap, topology 等图表',
english: '[FEATURE] Increase chart types, such as hexgon, treemap, and topology'
}, {
id: 14,
chinese: '[FEATURE] 支持自定义日期显示格式',
english: '[FEATURE] Support custom date display format'
}, {
id: 15,
chinese: '[FEATURE] 新增license管理功能',
english: '[FEATURE] Add license management'
}, {
id: 16,
chinese: '[FEATURE] 新增IP地址管理功能',
english: '[FEATURE] Add IP address management'
}, {
id: 17,
chinese: '[FEATURE] 新增全局搜索功能',
english: '[FEATURE] Add global search'
}, {
id: 18,
chinese: '[ENHANCEMENT] 优化表格图表类型配置及显示,支持多个表达式结果关联显示在同一个表格中',
english: '[ENHANCEMENT] Improve the configuration and display for tables and support multiple expression results being associated and displayed in a same table'
}, {
id: 19,
chinese: '[ENHANCEMENT] 优化折线图,面积图图表类型显示,支持是否启用堆叠',
english: '[ENHANCEMENT] Optimize the display of line charts and area charts, and support whether to enable stacking'
}]
}, {
timestamp: 'Release 21.11 - Nov 2021',
content: [{
id: 20,
chinese: '[FEATURE] 资产、告警规则、模块等增加详细视图',
english: '[FEATURE] Add detailed views to assets, alert rules and modules'
}, {
id: 21,
chinese: '[FEATURE] 增加个人中心,支持查看本人操作记录等信息',
english: '[FEATURE] Add personal center and allow for viewing ones own operational record, etc.'
}, {
id: 22,
chinese: '[ENHANCEMENT] 重构告警规则实现统一指标、日志和SNMP trap告警规则定义',
english: '[ENHANCEMENT] Reconstruct alert rule implementation and unify the alert rule definition of metrics, logs and SNMP trap'
}, {
id: 23,
chinese: '[ENHANCEMENT] 资产支持批量修改标签,密码等',
english: '[ENHANCEMENT] Assets support batch modification of tags and passwords'
}]
}, {
timestamp: 'Release 21.09 - Sep 2021',
content: [{
id: 24,
chinese: '[FEATURE] 集中的日志数据观测',
english: '[FEATURE] Centralized observation of log data'
}, {
id: 25,
chinese: '[FEATURE] 资产支持父子数据关联',
english: '[FEATURE] Assets support parent-child data association'
}, {
id: 26,
chinese: '[[FEATURE] 双因素认证',
english: '[FEATURE] Two-factor Authentication'
}, {
id: 27,
chinese: '[FEATURE] 支持创建图表模板',
english: '[FEATURE] Support creating chart templates'
}, {
id: 28,
chinese: '[ENHANCEMENT] 优化折线图表类型显示效果',
english: '[ENHANCEMENT] Improve the display of line charts'
}, {
id: 29,
chinese: '[ENHANCEMENT] 优化图表排列方式',
english: '[ENHANCEMENT] Optimize chart layout'
}]
}, {
timestamp: 'Release 21.07 - Jul 2022',
content: [{
id: 30,
chinese: '[FEATURE] 系统初始化配置功能,方便用户首次部署配置',
english: '[FEATURE] Initialize system configuration to make users first deployment configuration easier'
}, {
id: 31,
chinese: '[FEATURE] 使用向导功能',
english: '[FEATURE] Add usage wizard'
}, {
id: 32,
chinese: '[FEATURE] NZ-AGENT组件实现一键部署',
english: '[FEATURE] Allow for one-touch deployment of NZ-AGENT'
}, {
id: 33,
chinese: '[ENHANCEMENT] UI界面优化',
english: '[ENHANCEMENT] Enhance UI'
}]
}, {
timestamp: 'Release 21.04 - Apr 2021',
content: [{
id: 34,
chinese: '[FEATURE] UI界面重构',
english: '[FEATURE] Reconstruct UI'
}, {
id: 35,
chinese: '[FEATURE] 系统拓扑图功能',
english: '[FEATURE] Add the system topology map'
}, {
id: 36,
chinese: '[FEATURE] 堡垒机操作录像及回放功能',
english: '[FEATURE] Support the recording and playback of bastion hosts operations'
}, {
id: 37,
chinese: '[ENHANCEMENT] 优化堡垒机命令解析方式,使命令解析结果更准确',
english: '[ENHANCEMENT] Optimize the parsing method of bastion hosts commands for the parsed results to be more accurate'
}]
}, {
timestamp: 'Release 2.0 - Jul 2020',
content: [{
id: 38,
chinese: '[FEATURE] 系统概览功能',
english: '[FEATURE] Add system overview'
}, {
id: 39,
chinese: '[FEATURE] 告警规则查看详情',
english: '[FEATURE] Add a detail view to alert rules'
}, {
id: 40,
chinese: '[FEATURE] 列表数据批量导入导出功能',
english: '[FEATURE] The lists can be imported and exported in batch'
}, {
id: 41,
chinese: '[ENHANCEMENT] 列表字段支持排序',
english: '[ENHANCEMENT] Support field ranking list'
}, {
id: 42,
chinese: '[ENHANCEMENT] 图表实现调整位置和大小',
english: '[ENHANCEMENT] The position and size of charts can be adjusted'
}]
}]
}
},
methods: {
@@ -38,6 +252,9 @@ export default {
},
mounted () {
this.getVersion()
},
computed: {
language () { return this.$store.getters.getLanguage }
}
}
</script>

View File

@@ -86,15 +86,24 @@
<div ref="detailScrollbar" class="mib-browser-detail">
<div class="mib-browser-detail-row">
<div>Name</div>
<div>{{currentWalk.name}}</div>
<div class="document-copy-block" >
<div class="document-copy-text">{{currentWalk.name}}</div>
<i v-if="currentWalk.name" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(currentWalk.name)" :title="$t('overall.copyText')"></i>
</div>
</div>
<div class="mib-browser-detail-row">
<div>OID</div>
<div>{{currentWalk.objectID}}</div>
<div class="document-copy-block">
<div class="document-copy-text">{{currentWalk.objectID}}</div>
<i v-if="currentWalk.objectID" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(currentWalk.objectID)" :title="$t('overall.copyText')"></i>
</div>
</div>
<div class="mib-browser-detail-row">
<div>MIB</div>
<div>{{mibName(currentWalk.objectID)}}</div>
<div class="document-copy-block">
<div class="document-copy-text">{{mibName(currentWalk.objectID)}}</div>
<i v-if="mibName(currentWalk.objectID)" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(mibName(currentWalk.objectID))" :title="$t('overall.copyText')"></i>
</div>
</div>
<div class="mib-browser-detail-row">
<div>Syntax</div>
@@ -140,7 +149,12 @@
</div>
</pl-table-column>
<pl-table-column v-slot="{row}" label="Value">
<template><div @click="searchParam.oid = row.oid">{{row.value}}</div></template>
<div class="document-copy-block">
<div class="document-copy-text">
<div @click="searchParam.oid = row.oid">{{row.value}}</div>
</div>
<i v-if="row.value" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(row.value)" :title="$t('overall.copyText')"></i>
</div>
</pl-table-column>
<pl-table-column v-slot="{row}" label="Type">
<template><div @click="searchParam.oid = row.oid">{{row.type}}</div></template>