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

This commit is contained in:
@changcode
2021-04-29 10:57:05 +08:00
60 changed files with 1926 additions and 674 deletions

View File

@@ -8,5 +8,32 @@
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"utils": {
"presets": [
[
"env",
{
"loose": true,
"modules": "commonjs",
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}
],
],
"plugins": [
["module-resolver", {
"root": ["element-ui"],
"alias": {
"element-ui/src": "element-ui/lib"
}
}]
]
},
"test": {
"plugins": ["istanbul"]
}
}
}

View File

@@ -8,8 +8,6 @@ function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
@@ -25,8 +23,8 @@ module.exports = {
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
vue$: 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
@@ -37,9 +35,22 @@ module.exports = {
options: vueLoaderConfig
},
{
test: /\.js$/,
test: /\.(js)$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client'), resolve('node_modules/element-ui/packages/scrollbar')],
exclude: '/node_modules/',
options: {
presets: [
['env', {
modules: false,
targets: {
browsers: ['> 1%', 'last 2 versions', 'not ie <= 8']
}
}],
'stage-2'
],
plugins: ['transform-vue-jsx', 'transform-runtime']
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,

View File

@@ -48,7 +48,7 @@
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-core": "^6.26.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",

View File

@@ -85,3 +85,35 @@
.orange-bg {
background-color: var(--theme-color) !important;
}
.timezone-area{
display: inline-block;
vertical-align: middle;
width: auto;
font-size: 14px;
float: left;
margin-left: 10px;
font-family: PingFangSC-Regular;
color: #333333;
line-height: 20px;
font-weight: 400;
margin-top: 3px;
}
.timezone-offset{
display: inline-block;
vertical-align: middle;
width: auto;
font-size: 14px;
margin-right: 10px;
font-family: PingFangSC-Regular;
color: #333333;
line-height: 20px;
font-weight: 400;
}
.active-icon{
margin-top:0px;
width:10px;
height:10px;
border-radius:50%;
display: inline-block;
margin-right: 5px;
}

View File

@@ -96,6 +96,8 @@
}
.top-tool-btn--dropdown {
position: relative;
width: auto;
min-width: 36px;
}
}
.top-tools--sub {

View File

@@ -43,7 +43,11 @@ $--warning-color: var(--theme-color); //全局警告橙色
$--suspended-color: #9e9c98; //全局停用色灰色
:export {
themeColor: $--theme-color
themeColor: $--theme-color;
dangerColor: $--danger-color;
successColor: $--success-color;
warningColor: var(--theme-color);
suspendedColor: $--suspended-color;
}
/* element-ui变量覆盖 */
/*$--color-primary: red; // 覆盖element-ui的主题色

View File

@@ -1690,7 +1690,7 @@ li{
}
/*列表中状态字段 的小圆点*/
.active-icon{
margin-top:15px;
margin-top:0px;
width:8px;
height:8px;
border-radius:50%;

View File

@@ -60,7 +60,7 @@
<!-- <time-picker ref="calendarPanel" class="nz-dashboard-picker" style="margin-top: -12px;" @change="dateChange" v-if="chart.type !='text'"></time-picker>-->
<pick-time :refresh-data-func="dateChange" v-model="searchTime" :use-chart-unit="false" ref="pickTime" style="height: 28px;" id="chart-preview"></pick-time>
<!--
<el-date-picker ref="calendar" prefix-icon=" " size="mini" class="nz-preview-picker"
<my-date-picker ref="calendar" prefix-icon=" " size="mini" class="nz-preview-picker"
format="yyyy/MM/dd HH:mm"
@change="dateChange"
v-model="searchTime"
@@ -70,7 +70,7 @@
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')"
align="right">
</el-date-picker>-->
</my-date-picker>-->
</div>
</div>

View File

@@ -360,7 +360,7 @@ export default {
},
customConnect: {
host: '',
port: '',
port: 22,
authType: 1,
authUsername: '',
authPin: '',
@@ -377,19 +377,19 @@ export default {
{
title: 'Type',
data: (row) => {
return row.type.name
return row.type ? row.type.name : ''
}
},
{
title: 'Model',
data: (row) => {
return row.model.name
return row.model ? row.model.name : ''
}
},
{
title: 'Datacenter',
data: (row) => {
return row.dc.name
return row.dc ? row.dc.name : ''
}
}
],
@@ -878,9 +878,10 @@ export default {
if (this.customConnect.authProtocol === 1) {
this.customConnect.authUserTip = ''
this.customConnect.authPinTip = ''
this.customConnect.port = 22
} else {
this.customConnect.authPriKey = ''
this.customConnect.authPriKey = 1
this.customConnect.port = 23
}
},
authTypeChange () {

View File

@@ -3,125 +3,117 @@
<div class="alert-label-info" v-if="type==='asset'" v-loading="loading">
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.id:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.id ? alertLabelData.id : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">SN</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.sn:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.sn ? alertLabelData.sn:'--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Host</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.host:'--'}}</div>
<div class="alert-label-title">IP</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.manageIp ? alertLabelData.manageIp : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">State</div>
<div class="alert-label-value">{{alertLabelData?(alertStateStr(alertLabelData.state)):'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.state && alertLabelData.state.name ? alertLabelData.state.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Ping</div>
<div class="alert-label-value">
<div v-if="alertLabelData" :class="{'active-icon green':alertLabelData.pingStatus == 1,'active-icon red':alertLabelData.pingStatus == 0}"></div>
<span v-if="alertLabelData">{{alertLabelData.pingRtt?alertLabelData.pingRtt+'ms':'--'}}</span>
<div v-if="alertLabelData" :class="{'green-bg': alertLabelData && alertLabelData.pingInfo && alertLabelData.pingInfo.status === 1,'red-bg': alertLabelData && alertLabelData.pingInfo && alertLabelData.pingInfo.status === 0}" class="active-icon"></div>
<span v-if="alertLabelData">{{alertLabelData && alertLabelData.pingInfo && alertLabelData.pingInfo.rtt ? alertLabelData.pingInfo.rtt + 'ms':'--'}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Asset Type</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.assetType:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.type && alertLabelData.type.name ? alertLabelData.type.name:'--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Vendor</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.vendor:'--'}}</div>
<div class="alert-label-title">Brand</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.brand && alertLabelData.brand.name ? alertLabelData.brand.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Model</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.model:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.model && alertLabelData.model.name ? alertLabelData.model.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">PingLastReply</div>
<div class="alert-label-value">{{(alertLabelData&&alertLabelData.pingLastReply)?alertLabelData.pingLastReply:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.pingInfo && alertLabelData.pingInfo.lastUpdate ? alertLabelData.pingInfo.lastUpdate : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Alert</div>
<div class="alert-label-value">
<span v-if="alertLabelData" :class="{danger:alertLabelData.alert>0,success:alertLabelData.alert<=0}">{{alertLabelData.alert + alertActiveStr()}}</span>
<span v-if="alertLabelData" :class="alertLabelData && alertLabelData.alertNum > 0 ? 'danger' : 'success'">{{alertLabelData && alertLabelData.alertNum ? alertLabelData.alertNum : 0 + ' ' + alertActiveStr()}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">DC</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.dataCenter:'--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Endpoint</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.endpoint:'--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Administrator</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.principal:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.dc && alertLabelData.dc.name ? alertLabelData.dc.name : '--'}}</div>
</div>
</div>
<div class="alert-label-info" v-if="type==='module'" v-loading="loading">
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.id:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.id ? alertLabelData.id : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Name</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.name:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.name ? alertLabelData.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Project</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.project.name:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.project && alertLabelData.project.name ?alertLabelData.project.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Description</div>
<div class="alert-label-value">{{alertLabelData?(alertLabelData.remark?alertLabelData.remark:'-'):'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.remark ? alertLabelData.remark : '-'}}</div>
</div>
</div>
<div class="alert-label-info" v-if="type==='project'" v-loading="loading">
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.id:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData ? alertLabelData.id : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Name</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.name:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData ? alertLabelData.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Description</div>
<div class="alert-label-value">{{alertLabelData?(alertLabelData.remark?alertLabelData.remark:'-'):'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.remark ? alertLabelData.remark : '--'}}</div>
</div>
</div>
<div class="alert-label-info" v-if="type==='endpoint'" v-loading="loading">
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.id:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.id ? alertLabelData.id : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Project</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.project.name:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.project && alertLabelData.project.name ? alertLabelData.project.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Module</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.module.name:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.module && alertLabelData.module.name ? alertLabelData.module.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Labels</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.labels:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.labels ? alertLabelData.labels : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Host</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.host:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.host ? alertLabelData.host : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Port</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.port:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.port ? alertLabelData.port : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Path</div>
<div class="alert-label-value">{{alertLabelData?alertLabelData.path:'--'}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.path ? alertLabelData.path : '--'}}</div>
</div>
</div>
</div>
@@ -240,40 +232,40 @@ export default {
init () {
this.loading = true
if (this.type === 'asset') {
this.$get('/asset/info?id=' + this.id).then((res) => {
this.$get('asset/asset/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data.Basic
this.alertLabelData = res.data
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'project') {
this.$get('/project?id=' + this.id).then((res) => {
this.$get('monitor/project/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data.list[0]
this.alertLabelData = res.data
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'module') {
this.$get('/module?id=' + this.id).then((res) => {
this.$get('monitor/module/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data.list[0]
this.alertLabelData = res.data
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'endpoint') {
this.$get('/endpoint?id=' + this.id).then((res) => {
this.$get('monitor/endpoint/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data.list[0]
this.alertLabelData = res.data
} else {
this.$message.error(res.msg)
}
@@ -392,13 +384,13 @@ export default {
word-break: break-all;
}
.danger{
background-color: #d64f40;
background-color: $--danger-color;
color: white;
padding: 2px 5px;
border-radius: 4px;
}
.success{
background-color: #50d050;
background-color: $--success-color;
color: white;
padding: 2px 5px;
border-radius: 4px;

View File

@@ -19,7 +19,7 @@
</el-input>
</div>
<div class="margin-r-20 nz-btn-group nz-btn-group-size-small nz-btn-group-light">
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" id="endpoint-query-changetime"><i class="el-icon-d-arrow-left"></i></button><el-date-picker
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" id="endpoint-query-changetime"><i class="el-icon-d-arrow-left"></i></button><my-date-picker
v-model="formatTime"
type="datetime"
size="mini"
@@ -29,7 +29,7 @@
placeholder="Moment"
value-format="yyyy-MM-dd HH:mm:ss"
>
</el-date-picker><button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append"><i class="el-icon-d-arrow-right"></i></button>
</my-date-picker><button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append"><i class="el-icon-d-arrow-right"></i></button>
</div>
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light" style="height: 24px;">
<button class="nz-btn nz-btn-size-normal nz-btn-style-light" @click="viewGraph">

View File

@@ -32,7 +32,7 @@
</el-input>
</div>
<div class="margin-r-20 nz-btn-group nz-btn-group-size-small nz-btn-group-light">
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" id="endpoint-query-changetime"><i class="el-icon-d-arrow-left"></i></button><el-date-picker
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" id="endpoint-query-changetime"><i class="el-icon-d-arrow-left"></i></button><my-date-picker
v-model="formatTime"
type="datetime"
size="mini"
@@ -43,7 +43,7 @@
value-format="yyyy-MM-dd HH:mm:ss"
@change="pickTime"
>
</el-date-picker><button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append"><i class="el-icon-d-arrow-right"></i></button>
</my-date-picker><button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append"><i class="el-icon-d-arrow-right"></i></button>
</div>
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light" style="height: 24px;">
<button class="nz-btn nz-btn-size-normal nz-btn-style-light" @click="viewGraph">

View File

@@ -54,13 +54,6 @@ export default {
created () {
const localStorageTitle = JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.tableId))
if (localStorageTitle) {
for (const title of this.originalTableTitle) {
for (const lsTitle of localStorageTitle) {
if (lsTitle.prop === title.prop) {
lsTitle.label = title.label
}
}
}
localStorage.setItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.tableId, JSON.stringify(localStorageTitle))
}
},

View File

@@ -1149,7 +1149,7 @@ const cn = {
alerts: 'Alerts',
privpin: '隐私密码',
asset: 'Asset',
editEndpoint: '编辑 endpoint',
editEndpoint: '编辑 Endpoint',
createEndpoint: '新增Endpoint',
batchEndpoint: '批量 Endpoint',
endpointName: 'Endpoint name'

View File

@@ -1178,7 +1178,7 @@ const en = {
privpin: 'Priv password',
alerts: 'Alerts',
asset: 'Asset',
editEndpoint: 'edit endpoint',
editEndpoint: 'Edit endpoint',
createEndpoint: 'Created endpoint',
batchEndpoint: 'Batch Endpoint',
endpointName: 'Endpoint name',

View File

@@ -50,6 +50,7 @@
<script>
import { mapActions } from 'vuex'
import moment from 'moment-timezone'
export default {
name: 'login',
data () {

View File

@@ -116,11 +116,11 @@
<!-- name="multiple-time-datepicker"-->
<transition>
<div v-show="showDropdown" id="panel-calender" class="calendar">
<el-date-picker prefix-icon=" " size="mini" ref="calendar"
<my-date-picker prefix-icon=" " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" class="panel-time-picker-hidden" @change="dateChange" v-model="startTime" type="datetime"
popper-class="panel-time-picker-popper"
align="right">
</el-date-picker>
</my-date-picker>
<!--
<button type="button" style="border-radius: 1px 1px 1px 1px" @click="right()" v-show="isCustom"
class="nz-btn nz-btn-size-normal nz-btn-style-light time-picker-button time-picker-right-button" >
@@ -373,6 +373,7 @@ export default {
} else {
this.isCustom = true
this.$refs.calendar.focus()
this.$refs.calendar.pickerVisible = true
}
} else {
this.isCustom = false

View File

@@ -1,7 +1,14 @@
import DatePicker from './src/picker/date-picker'
import localeEn from 'element-ui/lib/locale/lang/en'
import localeCn from 'element-ui/lib/locale/lang/zh-CN'
import { use } from 'element-ui/src/locale/'
/* istanbul ignore next */
DatePicker.install = function install (Vue) {
if (localStorage.getItem('nz-language') === 'cn') {
use(localeCn)
} else {
use(localeEn)
}
Vue.component(DatePicker.name, DatePicker)
}

View File

@@ -32,6 +32,7 @@
</template>
<script>
import bus from '@/libs/bus'
import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, prevDate, nextDate, isDate, clearTime as _clearTime } from 'element-ui/src/utils/date-util'
import Locale from 'element-ui/src/mixins/locale'
import { arrayFindIndex, arrayFind, coerceTruthyValueToArray } from 'element-ui/src/utils/util'
@@ -54,11 +55,14 @@ const removeFromArray = function (arr, pred) {
const idx = typeof pred === 'function' ? arrayFindIndex(arr, pred) : arr.indexOf(pred)
return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr
}
export default {
mixins: [Locale],
props: {
timezone: {
type: String,
default: localStorage.getItem('nz-sys-timezone') // 没有传则使用本地的时区
},
firstDayOfWeek: {
default: 7,
type: Number,
@@ -144,7 +148,9 @@ export default {
const disabledDate = this.disabledDate
const cellClassName = this.cellClassName
const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : []
const now = getDateTimestamp(new Date())
const now = getDateTimestamp(
new Date(bus.computeTimezoneTime(new Date()))
)
for (let i = 0; i < 6; i++) {
const row = rows[i]

View File

@@ -111,6 +111,7 @@
<div>{{ leftLabel }}</div>
</div>
<date-table
:timezone="timezone"
selection-mode="range"
:date="leftDate"
:default-value="defaultValue"
@@ -151,6 +152,7 @@
<div>{{ rightLabel }}</div>
</div>
<date-table
:timezone="timezone"
selection-mode="range"
:date="rightDate"
:default-value="defaultValue"
@@ -167,13 +169,15 @@
</div>
</div>
<div class="el-picker-panel__footer" v-if="showTime">
<el-button
size="mini"
type="text"
class="el-picker-panel__link-btn"
@click="handleClear">
{{ t('el.datepicker.clear') }}
</el-button>
<span class="timezone-area">{{timezone}}</span>
<span class="timezone-offset">{{timezoneOffset}}</span>
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- class="el-picker-panel__link-btn"-->
<!-- @click="handleClear">-->
<!-- {{ t('el.datepicker.clear') }}-->
<!-- </el-button>-->
<el-button
plain
size="mini"

View File

@@ -89,6 +89,7 @@
<div class="el-picker-panel__content">
<date-table
:timezone="timezone"
v-show="currentView === 'date'"
@pick="handleDatePick"
:selection-mode="selectionMode"
@@ -122,6 +123,8 @@
<div
class="el-picker-panel__footer"
v-show="footerVisible && currentView === 'date'">
<span class="timezone-area">{{timezone}}</span>
<span class="timezone-offset">{{timezoneOffset}}</span>
<el-button
size="mini"
type="text"
@@ -170,7 +173,7 @@ import TimePicker from './time'
import YearTable from '../basic/year-table'
import MonthTable from '../basic/month-table'
import DateTable from '../basic/date-table'
import bus from '@/libs/bus'
export default {
mixins: [Locale],
@@ -370,7 +373,7 @@ export default {
// NOTE: not a permanent solution
// consider disable "now" button in the future
if ((!this.disabledDate || !this.disabledDate(new Date())) && this.checkDateWithinRange(new Date())) {
this.date = new Date()
this.date = new Date(bus.computeTimezoneTime(new Date()))
this.emit(this.date)
}
},

View File

@@ -72,6 +72,10 @@
</month-table>
</div>
</div>
<div class="el-picker-panel__footer" v-if="showTime">
<span class="timezone-area">{{timezone}}</span>
<span class="timezone-offset">{{timezoneOffset}}</span>
</div>
</div>
</div>
</transition>

View File

@@ -41,6 +41,8 @@
</div>
</div>
<div class="el-time-panel__footer">
<span class="timezone-area">{{timezone}}</span>
<span class="timezone-offset">{{timezoneOffset}}</span>
<button
type="button"
class="el-time-panel__btn cancel"

View File

@@ -16,6 +16,8 @@
</time-spinner>
</div>
<div class="el-time-panel__footer">
<!-- <span class="timezone-area">{{timezone}}</span>-->
<!-- <span class="timezone-offset">{{timezoneOffset}}</span>-->
<button
type="button"
class="el-time-panel__btn cancel"

View File

@@ -91,7 +91,7 @@ import Popper from 'element-ui/src/utils/vue-popper'
import Emitter from 'element-ui/src/mixins/emitter'
import ElInput from 'element-ui/packages/input'
import merge from 'element-ui/src/utils/merge'
import moment from 'moment-timezone'
const NewPopper = {
props: {
appendToBody: Popper.props.appendToBody,
@@ -343,6 +343,10 @@ export default {
},
props: {
timezone: {
type: String,
default: localStorage.getItem('nz-sys-timezone') // 没有传则使用本地的时区
},
size: String,
format: String,
valueFormat: String,
@@ -821,6 +825,14 @@ export default {
},
mountPicker () {
const tempFun = this.panel.data
this.panel.data = () => {
return {
timezone: localStorage.getItem('nz-sys-timezone'), // add timezone to panel component
timezoneOffset: localStorage.getItem('timezoneOffset'),
...tempFun()
}
}
this.picker = new Vue(this.panel).$mount()
this.picker.defaultValue = this.defaultValue
this.picker.defaultTime = this.defaultTime

View File

@@ -15,7 +15,7 @@ const getPanel = function (type) {
export default {
mixins: [Picker],
name: 'ElDatePicker',
name: 'myDatePicker',
props: {
type: {

View File

@@ -252,7 +252,7 @@ export default {
clearTimeout(this.timer)
}
this.assetData.id = data
const boxWidth = document.getElementsByClassName('content-right')[0].offsetWidth
const boxWidth = document.getElementsByClassName('list-page')[0].offsetWidth
this.boxWidth = boxWidth
// this.assetData.rate=window.screen.height/1297;
this.$nextTick(() => {

View File

@@ -9,7 +9,7 @@
<span class="nz-btn nz-btn-text" ><slot name="added-text"></slot></span>
</button>
<button id="browser-go" class="top-tool-btn top-tool-btn--dropdown" @mouseenter="dropdownHandler(true)" @mouseleave="dropdownHandler(false)">
<span class="select-refresh-time" v-if="interval !== -1">{{interLabel}}</span>
<span class="select-refresh-time-label" v-if="interval !== -1">{{interLabel}}</span>
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px;"></i>
<transition name="el-zoom-in-top">
<ul v-show="dropdownShow" class="el-dropdown-menu el-popper el-dropdown-menu--mini nz-dropdown">
@@ -98,7 +98,7 @@ export default {
selectInterval (val) {
this.visible = false
this.interval = val.value
this.interLabel = val.value
this.interLabel = val.label
console.info(this.interval, val)
if (!this.showTimePicker && val && val.value != -1) {
this.intervalTimer = setInterval(() => {
@@ -170,4 +170,7 @@ export default {
.interval-refresh {
display: flex;
}
.select-refresh-time-label{
margin-left: 5px;
}
</style>

View File

@@ -54,6 +54,7 @@
:styleType="2"
:metricOptionsParent="metricOptions"
@change="expressionChange"
:from-father-data="true"
@removeExpression="removeExpression"
></promql-input>
<el-row>
@@ -1128,7 +1129,7 @@ export default {
})
},
mounted () {
this.queryMetrics()
// this.queryMetrics()
// this.topologyData.data.grid= !!dataOption.grid;
// this.topologyData.data.rule= !!dataOption.rule;
// this.topologyData.data.projectInfo= !!dataOption.projectInfo;

View File

@@ -180,7 +180,7 @@ export const imageTemp = {
width: 100,
height: 100
},
imageRatio: false,
imageRatio: true,
lineWidth: 0,
rotate: 0,
offsetRotate: 0,

View File

@@ -1549,7 +1549,6 @@ export default {
upload () {
const form = new FormData()
form.append('file', this.file)
console.log(this.file)
if (this.uploadPic.name) {
form.append('name', this.uploadPic.name)
} else {
@@ -1562,7 +1561,7 @@ export default {
if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.uploadPicShow = false
this.dealImg(`monitor/project/topo/icon/${res.data.id}/1`).then((data) => {
this.dealImg(`monitor/project/topo/icon/${res.data.id}/1`).then((data,header) => {
const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
if (group) {
group.children.push({
@@ -1621,7 +1620,7 @@ export default {
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}/1`))
imgArr.push({ ...item })
})
Promise.all(promiseArr).then((res2) => {
Promise.all(promiseArr).then((res2,header) => {
this.iconArray = [...res.data.list]
this.iconArray.forEach((item, index) => {
item.image = res2[index]
@@ -1688,15 +1687,14 @@ export default {
if (url) {
return new Promise((resolve, reject) => {
this.$axios
.get(url, {
responseType: 'arraybuffer'
})
.then(res => {
console.log(res.data)
return ('data:image/jpeg;base64,' + btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), '')))
.get(url)
.then((res) => {
return {
data: ('data:image/jpeg;base64,' + res.data),
}
})
.then(data => {
resolve(data)
resolve(data.data, data.header)
// changeImage(data,(img)=>{
// resolve(img)
// })

View File

@@ -313,7 +313,7 @@
</button>
<button @click="imgUpload" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new"
v-has="'project_topo_save'" :disabled="prevent_opt.save"
v-has="'topo_icon_save'" :disabled="prevent_opt.save"
:class="{'nz-btn-disabled':prevent_opt.save}"
style="margin-right: 20px">
{{$t('project.topology.save')}}
@@ -477,6 +477,8 @@ export default {
penToolTipScale: 1,
oldScale: 1,
uploadPicShow: false,
imgWidth: 0,
imgHeight: 0,
uploadPic: {
name: '',
unit: ''
@@ -1484,22 +1486,24 @@ export default {
beforeAvatarUpload (file, fileList) {
const this_ = this
const isJPG = (file.raw.type === 'image/jpeg' || file.raw.type === 'image/png')
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error(this_.$t('project.topology.imgFormat'))
return false
}
// if (!isLt2M) {
// this.$message.error( this_.$t('project.topology.imgSize'));
// return false;
// }
if (!isLt2M) {
this.$message.error(this_.$t('project.topology.imgSize'))
return false
}
const isSize = new Promise(function (resolve, reject) {
const width = 100
const height = 100
const width = 0
const height = 0
const _URL = window.URL || window.webkitURL
const img = new Image()
img.onload = function () {
const valid = img.width > width && img.height > height
this_.imgWidth = img.width
this_.imgHeight = img.height
valid ? resolve() : reject()
}
img.src = _URL.createObjectURL(file.raw)
@@ -1551,11 +1555,13 @@ export default {
form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.')))
}
form.append('unit', this.uploadPic.unit)
form.append('width', this.imgWidth)
form.append('height', this.imgHeight)
this.$post('monitor/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => {
if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.uploadPicShow = false
this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => {
this.dealImg(`monitor/project/topo/icon/${res.data.id}/1`).then((data, header) => {
const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
if (group) {
group.children.push({
@@ -1611,10 +1617,10 @@ export default {
res.data.list.forEach((item, index) => {
item.imageName = item.name
delete item.name
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`))
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}/1`))
imgArr.push({ ...item })
})
Promise.all(promiseArr).then((res2) => {
Promise.all(promiseArr).then((res2, header) => {
this.iconArray = [...res.data.list]
this.iconArray.forEach((item, index) => {
item.image = res2[index]
@@ -1655,7 +1661,7 @@ export default {
const promiseArr = []
imgidList.forEach((item, index) => {
if (item.data.imageId) {
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`))
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}/1`))
} else {
promiseArr.push('')
}
@@ -1681,14 +1687,14 @@ export default {
if (url) {
return new Promise((resolve, reject) => {
this.$axios
.get(url, {
responseType: 'arraybuffer'
})
.then(res => {
return ('data:image/jpeg;base64,' + btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), '')))
.get(url)
.then((res) => {
return {
data: ('data:image/jpeg;base64,' + res.data)
}
})
.then(data => {
resolve(data)
resolve(data.data, data.header)
// changeImage(data,(img)=>{
// resolve(img)
// })

View File

@@ -35,29 +35,27 @@
<div class="datepicker">
<div class="datepicker-box">
<span class="datepicker-title">start time</span>
<el-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
<my-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" @change="(val)=>{dateChange(val,'startAt')}" v-model="editAlertSilence.startAt"
:picker-options="optionsStartAt"
type="datetime"
:clearable="false"
popper-class="panel-time-picker-popper"
:placeholder="$t('dashboard.panel.startTime')"
align="right"
>
</el-date-picker>
</my-date-picker>
</div>
<div class="datepicker-box">
<span class="datepicker-title">end time</span>
<el-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
<my-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" @change="(val)=>{dateChange(val,'endAt')}" v-model="editAlertSilence.endAt"
:picker-options="optionsEndAt"
type="datetime"
:clearable="false"
popper-class="panel-time-picker-popper"
:placeholder="$t('dashboard.panel.startTime')"
align="right"
>
</el-date-picker>
</my-date-picker>
</div>
<!--( :range-separator="")-->
</div>

View File

@@ -125,17 +125,17 @@
</template>
<template v-else>
<template v-if="label.interval">
<el-date-picker
<my-date-picker
id="asset-box-input-purchase-date"
v-model="label.value[0]"
:type="JSON.parse(label.param).subType === assetConstants.labelSubTypeData.date ? 'dateRange' : 'datetimerange'"
placeholder=""
size="small"
style="width: 100%">
</el-date-picker>
</my-date-picker>
</template>
<template v-else>
<el-date-picker
<my-date-picker
id="asset-box-input-parchase-date"
v-model="label.value[0]"
:type="JSON.parse(label.param).subType"
@@ -143,7 +143,7 @@
size="small"
style="width: 100%"
value-format="yyyy-MM-dd">
</el-date-picker>
</my-date-picker>
</template>
</template>
</template>

View File

@@ -62,7 +62,7 @@
<el-input v-else v-model="lockLocationInputValue" disabled size="small"></el-input>
</el-form-item>
<el-form-item :label="$t('asset.purchaseDate')" prop="purchaseDate">
<el-date-picker
<my-date-picker
id="asset-box-input-parchase-date"
v-model="editAsset.purchaseDate"
placeholder=""
@@ -70,7 +70,7 @@
style="width: 100%"
type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</my-date-picker>
</el-form-item>
<!-- labels -->
<div class="form__sub-title">{{$t('overall.labels')}}</div>
@@ -128,17 +128,17 @@
</template>
<template v-else>
<template v-if="label.interval">
<el-date-picker
<my-date-picker
id="asset-box-input-purchase-date"
v-model="label.value[0]"
:type="JSON.parse(label.param).subType === assetConstants.labelSubTypeData.date ? 'dateRange' : 'datetimerange'"
placeholder=""
size="small"
style="width: 100%">
</el-date-picker>
</my-date-picker>
</template>
<template v-else>
<el-date-picker
<my-date-picker
id="asset-box-input-parchase-date"
v-model="label.value[0]"
:type="JSON.parse(label.param).subType"
@@ -146,7 +146,7 @@
size="small"
style="width: 100%"
value-format="yyyy-MM-dd">
</el-date-picker>
</my-date-picker>
</template>
</template>
</template>

View File

@@ -66,7 +66,7 @@
</el-form-item>
<el-form-item :label="$t('asset.purchaseDate')">
<div class="select-style">
<el-date-picker
<my-date-picker
id="asset-box-input-parchase-date"
size="small"
v-model="editAsset.purchaseDate"
@@ -74,7 +74,7 @@
type="date"
style="width: 100%"
placeholder="">
</el-date-picker>
</my-date-picker>
</div>
</el-form-item>
<el-form-item :label="$t('asset.location')" class="required-marker" prop="locationInfo" :rules="[{validator:locationValidator, trigger:'blur'}]">

View File

@@ -4,7 +4,7 @@
<!-- begin--标题-->
<div class="right-box-title">
<span v-if="optionType === 'edit'">
{{ $t("project.module.editEndpoint")}}
{{ $t("project.module.editEndpoint")}} {{editEndpoint.id}}
</span>
<span v-if="optionType === 'batch'">
{{ $t("project.module.batchEndpoint")}}

View File

@@ -162,7 +162,7 @@
</ul>
</div>
</div>
<el-date-picker
<my-date-picker
v-model="timeFrame"
type="datetimerange"
range-separator="To"
@@ -172,7 +172,7 @@
:class="dataBackG?'':'dataBackG'"
v-if="ind==sreach_num&&val.id==7"
>
</el-date-picker>
</my-date-picker>
</li>
<!-- 最开始的input框-->
<li class="select_input" v-if="change_sreach_show">

View File

@@ -36,7 +36,7 @@
<transition name="el-zoom-in-top">
<element-set
v-if="tools.showCustomTableTitle"
:tableId="tableId"
:tableId="$parent.tableId"
ref="customTableTitle"
:custom-table-title="customTableTitle"
:original-table-title="tableTitle"
@@ -88,10 +88,6 @@ export default {
searchMsg: {
type: Object
},
tableId: {
type: String,
default: ''
},
hasSearch: {
type: Boolean,
default: false

View File

@@ -42,7 +42,7 @@
<span v-else-if="item.prop === 'status'">
<el-popover :content="$t('asset.assetStatPre')+(scope.row.checkTime?utcTimeToTimezoneStr(scope.row.checkTime):$t('asset.assetStatDown'))" placement="right" trigger="hover" width="200">
<div slot="reference" style="width: 20px">
<div :class="{'active-icon green':scope.row[item.prop] == '1','active-icon red':scope.row[item.prop] == '0' || scope.row[item.prop] == '-1' || scope.row[item.prop] == '-2'}"></div>
<div :class="{'active-icon green-bg':scope.row[item.prop] == '1','active-icon red-bg':scope.row[item.prop] == '0' || scope.row[item.prop] == '-1' || scope.row[item.prop] == '-2'}"></div>
</div>
</el-popover>
</span>

View File

@@ -72,13 +72,13 @@
</div>
<div slot="reference" style="width: 100px">
<div v-if="scope.row[item.prop]===0">
<div class="active-icon red inline-block"></div> down
<div class="active-icon red-bg inline-block"></div> down
</div>
<div v-else-if="scope.row[item.prop]===1">
<div class="active-icon green inline-block"></div> up
<div class="active-icon green-bg inline-block"></div> up
</div>
<div v-else-if="scope.row[item.prop]">
<div class="active-icon gray inline-block"></div> suspended
<div class="active-icon gray-bg inline-block"></div> suspended
</div>
</div>
</el-popover>
@@ -183,16 +183,16 @@ export default {
let str = ''
arr.forEach((item, index) => {
if (index === 0) {
str += `<div>DC <div class="active-icon inline-block ${item == '0' ? 'red' : 'green'}"></div></div>`
str += `<div>DC <div class="active-icon inline-block ${item == '0' ? 'red-bg' : 'green-bg'}"></div></div>`
}
if (index === 1) {
str += `<div>ASSET <div class="active-icon inline-block ${item == '0' ? 'red' : 'green'}"></div></div>`
str += `<div>ASSET <div class="active-icon inline-block ${item == '0' ? 'red-bg' : 'green-bg'}"></div></div>`
}
if (index === 2) {
str += `<div>ENDPOINT <div class="active-icon inline-block ${item == '0' ? 'red' : 'green'}"></div></div>`
str += `<div>ENDPOINT <div class="active-icon inline-block ${item == '0' ? 'red-bg' : 'green-bg'}"></div></div>`
}
if (index === 3) {
str += `<div>PROMETHEUS <div class="active-icon inline-block ${item == '0' ? 'red' : 'green'}"></div></div>`
str += `<div>PROMETHEUS <div class="active-icon inline-block ${item == '0' ? 'red-bg' : 'green-bg'}"></div></div>`
}
})
return str

View File

@@ -88,13 +88,13 @@
</style>
<template>
<div id="panel-calender" :class="{'calendar--small': size === 'small'}" class="calendar">
<el-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
<my-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" @change="dateChange" v-model="searchTime" type="datetimerange"
popper-class="panel-time-picker-popper"
:range-separator="$t('dashboard.panel.to')"
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')" align="right">
</el-date-picker>
</my-date-picker>
<!--
<button type="button" style="border-radius: 1px 1px 1px 1px" @click="right()" v-show="isCustom"
class="nz-btn nz-btn-size-normal nz-btn-style-light time-picker-button time-picker-right-button" >
@@ -335,6 +335,8 @@ export default {
} else {
this.isCustom = true
this.$refs.calendar.focus()
this.$refs.calendar.pickerVisible = true
console.log(this.$refs.calendar)
}
} else {
this.isCustom = false

View File

@@ -5,25 +5,21 @@
</el-breadcrumb>
<div class="header-menu">
<el-dropdown>
<div class="header-menu&#45;&#45;item"><i class="nz-icon nz-icon-more-app"></i></div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, index) in linkData" :key="index" :index="'0-' + index">
<span class="link-title"><a :href='item.url' :title="item.name" rel="noopener norefferrer" target="_blank">{{item.name}}</a></span>
</el-dropdown-item>
</el-dropdown-menu>
<div class="header-menu__item"><i class="nz-icon nz-icon-more-app"></i></div>
<el-dropdown-menu></el-dropdown-menu>
</el-dropdown>
<el-dropdown>
<el-dropdown-menu slot="dropdown"></el-dropdown-menu>
<el-dropdown-menu></el-dropdown-menu>
<div id="header-open-cli" @click="cli">
<div class="header-menu&#45;&#45;item"><i class="nz-icon nz-icon-terminal"></i></div>
<div class="header-menu__item"><i class="nz-icon nz-icon-terminal"></i></div>
<span v-show="$store.state.consoleCount>0" class="right-tip">{{$store.state.consoleCount<=10?$store.state.consoleCount:'10+'}}</span>
</div>
</el-dropdown>
<el-dropdown>
<div class="header-menu&#45;&#45;item"><i class="nz-icon nz-icon-create-square"></i></div>
<div class="header-menu__item"><i class="nz-icon nz-icon-create-square"></i></div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, createIndex) in createMenu" :key="createIndex" v-has="item.permission" :index="`${createIndex}`">
<div :id="'create-box-'+createIndex" @click="createBox(item)">
<div :id="'create-box-'+createIndex">
<span>{{item.label}}</span>
</div>
</el-dropdown-item>
@@ -38,10 +34,10 @@
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<div id="header-to-english" :style="language=='en'?'color:#f90':''" @click="changeLocal('en')"><i class="nz-icon nz-icon-lang-en"></i>English</div>
<div id="header-to-english" :style="language === 'en'?'color:#f90':''" @click="changeLocal('en')"><i class="nz-icon nz-icon-lang-en"></i>English</div>
</el-dropdown-item>
<el-dropdown-item>
<div id="header-to-chinese" :style="language=='cn'?'color:#f90':''" @click="changeLocal('cn')"><i class="nz-icon nz-icon-lang-zh"></i>中文</div>
<div id="header-to-chinese" :style="language === 'cn'?'color:#f90':''" @click="changeLocal('cn')"><i class="nz-icon nz-icon-lang-zh"></i>中文</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -57,38 +53,18 @@
</el-dropdown-menu>
</el-dropdown>
</div>
<transition name="right-box">
<project-box v-if="rightBox.project.show" ref="projectBox" :project="editProject" @close="closeProjectRightBox"></project-box>
</transition>
<transition name="right-box">
<module-box v-if="rightBox.module.show" ref="moduleBox" :currentProject="currentProject" :module="editModule" @close="closeModuleRightBox"></module-box>
</transition>
<transition name="right-box">
<add-endpoint-box v-if="rightBox.endpoint.show" ref="addEndpointBox" :currentModule="currentModule" :currentProject="currentProject" @close="closeEndpointRightBox"></add-endpoint-box>
</transition>
<transition name="right-box">
<asset-box v-if="rightBox.asset.show" ref="assetAddUnit" :asset="editAsset" @close="closeAssetRightBox"></asset-box>
</transition>
<transition name="right-box">
<alert-config-box v-if="rightBox.alertRule.show" ref="alertConfigBox" :alert-rule="editAlertRule" @close="closeAlertRuleRightBox"></alert-config-box>
</transition>
<transition name="right-box">
<dc-box v-if="rightBox.dc.show" :dc="dc" :user-data="userData" @close="closeDcBox" @reload="getAssetData"></dc-box>
</transition>
<change-password :cur-user="username" :show-dialog="showChangePin" @click="showPinDialog" @dialogClosed="dialogClosed"></change-password>
</div>
</template>
<script>
import bus from '../../libs/bus'
import dcBox from '../common/rightBox/dcBox' // dc弹框
import { mapActions } from 'vuex'
import changePin from '../page/config/changePin'
export default {
name: 'Header',
components: {
'change-password': changePin,
'dc-box': dcBox
},
data () {
return {
@@ -96,81 +72,6 @@ export default {
language: localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en',
// 顶部菜单相关
/* activeIndex: '', */
activeItemIndex: '',
activeItemIndexes: [],
hoverItemIndex: '',
dc: {
id: '',
name: '',
location: '',
tel: '',
principal: '',
area: {
id: 0,
name: ''
}
},
userData: [],
assetData: [], // 顶部菜单asset的下拉内容
// add侧滑相关
rightBox: {
project: { show: false },
module: { show: false },
endpoint: { show: false },
asset: { show: false },
alertRule: { show: false },
dc: { show: false }
},
projectData: [], // 顶部菜单project列表中的数据
editProject: { id: '', name: '', remark: '' }, // 新增/编辑的project
currentProject: { id: '', name: '', remark: '' }, // module/endpoint弹框用来回显project
editModule: { type: 'http', name: '', project: {}, port: 9100, path: '', param: '', paramObj: [], labelModule: [], labels: '' }, // 新增/编辑的module
currentModule: { id: '', name: '', project: {}, port: '', path: '', param: '', paramObj: [], labels: '', labelModule: [] }, // endpoint弹框用来回显module此处固定为空对象
editEndpoint: { // 新增/编辑的endpoint
id: '',
host: '',
port: '',
param: '',
path: '',
asset: { id: '', name: '', host: '' },
project: { id: '', name: '' },
module: { id: '', name: '', param: '', paramObj: {}, projectId: '', labelModule: [], labels: '' },
moduleId: '',
assetId: '',
labelModule: []
},
editAsset: {
id: '',
sn: '',
host: '',
state: 1,
purchaseDate: '',
idcId: '',
cabinetId: '',
modelId: '',
model: { type: { code: '' } },
assetType: '',
impi: {
host: '',
port: ''
},
tags: [],
accounts: []
},
editAlertRule: {
id: '',
alertName: '',
linkObject: { id: '', name: '' },
expr: '',
unit: 2,
operator: '>',
last: 60,
severity: 'P2',
summary: '',
description: ''
},
createMenu: [ // 新增按钮内容
{
label: this.$t('project.project.project'),
@@ -217,9 +118,6 @@ export default {
* @param parentMenu 菜单大类
* */
jumpTo (route) {
if (route != 'asset') {
this.activeItemIndexes = []
}
this.$router.push({
path: route,
query: {
@@ -227,88 +125,6 @@ export default {
}
})
},
getLinkData () {
/* this.$get('link').then(response => {
this.$store.commit('setLinkData', response.data)
}) */
},
createBox (item) {
if (item.type == 1) {
this.rightBox.project.show = true
this.editProject = { id: '', name: '', remark: '' }
} else if (item.type == 2) {
this.rightBox.module.show = true
this.editModule = {
name: '',
project: {},
port: 9100,
path: '',
param: '',
labels: '',
type: 'http',
paramObj: [],
snmpParam: '',
labelModule: [],
// snmp setting 下划线命名是因为业务需求
walk: [],
version: 2, // 2/3
max_repetitions: 25,
retries: 3,
timeout: 10, // s
community: 'public',
username: '',
security_level: 'noAuthNoPriv', // noAuthNoPriv/authNoPriv/authPriv
pin: '',
auth_protocol: 'MD5', // MD5/SHA
priv_protocol: 'DES', // DES/AES
priv_pin: '',
context_name: ''
}
} else if (item.type == 3) {
this.rightBox.endpoint.show = true
} else if (item.type == 4) {
this.rightBox.asset.show = true
} else if (item.type == 5) {
this.rightBox.alertRule.show = true
} else if (item.type == 6) {
this.rightBox.dc.show = true
}
},
jumpToAsset (dc) {
if (dc) {
this.activeItemIndex = dc.id
this.$store.commit('setCurrentDc', dc.id)
bus.$emit('header-dc-change', dc.id) // 发送给leftMenu顶部dc条件改变了
} else {
this.activeItemIndex = ''
this.$store.commit('setCurrentDc', '')
bus.$emit('clear-asset-filter') // 清除leftMenu左侧菜单过滤条件
}
this.jumpTo('/asset')
},
jumpToProject (p) {
if (!this.hasButton('project_view')) {
return
}
this.currentProject = p
if (p.id !== this.$store.state.currentProject.id) {
bus.$emit('project-page-type', 'project')
}
this.$store.commit('currentProjectChange', p)
this.activeItemIndex = p.id
this.jumpTo('/project')
},
getAssetData () {
this.$get('idc', { pageSize: -1 }).then(response => {
if (response.code == 200) {
this.assetData = response.data.list
this.assetData.forEach(item => {
this.$set(item, item.name, false)
})
this.$store.commit('setIdcArr', this.assetData)
}
})
},
changeLocal (lang) {
if (lang != localStorage.getItem('nz-language')) {
localStorage.setItem('nz-language', lang)
@@ -316,85 +132,11 @@ export default {
window.location.reload()
}
},
getProjectList () {
this.$get('monitor/project', { pageSize: -1 }).then(response => {
if (response.code == 200) {
this.projectData = response.data.list
let flag = false
// 如果currentProject不在新取到的数据里说明它被删了
for (let i = 0; i < this.projectData.length; i++) {
if (this.projectData[i].id == this.currentProject.id) {
flag = true
break
}
}
if (!flag && this.projectData.length > 0) {
this.currentProject = this.projectData[0]
this.activeItemIndex = this.currentProject.id
this.$store.commit('currentProjectChange', this.currentProject)
}
}
})
},
getUserData () {
return new Promise(resolve => {
this.$get('sys/user', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) {
this.userData = response.data.list
}
resolve()
})
})
},
closeProjectRightBox (refresh) {
this.rightBox.project.show = false
if (refresh) {
this.getProjectList()
bus.$emit('project-list-change')
}
},
closeModuleRightBox (refresh) {
this.rightBox.module.show = false
if (refresh) {
bus.$emit('module-list-change')
}
},
closeEndpointRightBox (refresh) {
this.rightBox.endpoint.show = false
if (refresh) {
bus.$emit('endpoint-list-change')
}
},
closeAssetRightBox (refresh) {
this.rightBox.asset.show = false
if (refresh) {
bus.$emit('asset-list-change')
}
},
closeAlertRuleRightBox (refresh) {
this.rightBox.alertRule.show = false
if (refresh) {
bus.$emit('alert-rule-list-change')
}
},
closeDcBox (refresh) {
this.rightBox.dc.show = false
if (refresh) {
this.getAssetData()
bus.$emit('dc-list-change')
}
},
toEditProject (p) {
this.editProject = Object.assign({}, p)
this.rightBox.project.show = true
},
logout () {
this.$get('logout').then(() => {
this.logoutSuccess()
document.location.href = '/'
})
// this.jumpTo('/login');
},
refreshLang () {
this.language = localStorage.getItem('nz-language')
@@ -418,13 +160,6 @@ export default {
this.username = sessionStorage.getItem('nz-username')
this.refreshLang()
})
bus.$on('dc-list-change', () => { // dc.vue增删改dc时刷新顶部菜单dc列表
this.getAssetData()
})
bus.$on('current-project-change', project => {
this.currentProject = project
this.activeItemIndex = project.id
})
if (window.history && window.history.pushState) {
history.pushState(null, null, document.URL)
window.addEventListener('popstate', this.cancel, false)
@@ -435,45 +170,12 @@ export default {
this.$i18n.locale = this.language
if (sessionStorage.getItem('nz-token')) {
this.initEvent()
this.getAssetData()
this.getUserData()
this.getProjectList()
this.getLinkData()
}
// 刷新后有高亮
/* let activePath = this.$route.path.slice(1);
this.activeIndex = activePath; */
},
computed: {
linkData () {
return this.$store.getters.getLinkData
},
route () {
return this.$route.path
},
overViewProject () {
return this.$store.getters.getOverViewProject
},
menuIsActive () {
return function (menu, isParent) {
if (isParent) {
const isCurrent = menu.children.some(sub => {
return sub.route == this.route
})
if (isCurrent) {
return 'menu-active'
} else {
return ''
}
} else {
if (menu.route == this.route) {
return 'menu-item-active'
} else {
return ''
}
}
}
},
breadcrumb () {
const vm = this
const menuList = this.$store.getters.menuList
@@ -495,17 +197,8 @@ export default {
return breadcrumb
}
},
watch: {
overViewProject (n) {
if (n) {
this.jumpToProject(n)
}
}
},
beforeDestroy () {
bus.$off('login')
bus.$off('dc-list-change')
bus.$off('current-project-change')
},
destroyed () {
window.removeEventListener('popstate', this.cancel, false)

View File

@@ -4,7 +4,6 @@
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.asset"
:has-search="true"
:layout="['searchInput', 'elementSet', 'clickSearch']"
:search-msg="searchMsg">

View File

@@ -46,7 +46,7 @@
</div>
<div v-else-if="type==='datetime'">
<div v-if="param.subType==='date'">
<el-date-picker
<my-date-picker
size="small"
:type="param.interval?'daterange':'date'"
:range-separator="$t('dashboard.panel.to')"
@@ -54,7 +54,7 @@
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')"
>
</el-date-picker>
</my-date-picker>
</div>
<div v-if="param.subType==='time'">
<el-time-picker
@@ -68,14 +68,14 @@
</el-time-picker>
</div>
<div v-if="param.subType==='datetime'">
<el-date-picker
<my-date-picker
size="small"
:type="param.interval?'datetimerange':'datetime'"
:range-separator="$t('dashboard.panel.to')"
:placeholder="$t('alert.silence.selectTime')"
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')">
</el-date-picker>
</my-date-picker>
</div>
</div>
<div v-else-if="type==='email'" :class="emailError?'emailError':''">

View File

@@ -1,7 +1,7 @@
<template>
<div class="about">
<div class="app-header">
<div class="header-logo"><img width="70" height="70" src="../../../assets/img/logo1-2.png"></div>
<div class="header-logo"><img width="88" height="88" 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>
@@ -49,6 +49,8 @@ export default {
justify-content: center;
height: 100%;
background-color: white;
border: 10px solid #eee;
box-sizing: border-box;
.about-label {
color: #999;
@@ -56,7 +58,7 @@ export default {
.app-header {
display: flex;
min-width: 325px;
min-width: 360px;
.header-logo {
font-size: 0;
@@ -72,24 +74,30 @@ export default {
.app-name {
font-weight: bold;
font-size: 18px;
line-height: 50px;
font-family: Roboto-Bold;
font-size: 20px;
color: #333333;
font-weight: 700;
}
.app-version {
font-size: 12px;
font-family: Roboto-Regular;
font-size: 14px;
color: #333333;
font-weight: 400;
}
}
}
.app-component {
width: 325px;
width: 360px;
margin-top: 35px;
.component-title {
color: #999;
height: 30px;
font-size: 12px;
font-size: 14px;
line-height: 30px;
border-bottom: 1px solid #999;
}
@@ -103,6 +111,9 @@ export default {
display: flex;
color: #333;
font-size: 14px;
font-family: Roboto-Regular;
font-size: 16px;
font-weight: 400;
justify-content: space-between;
}
}

View File

@@ -1,12 +1,34 @@
<template>
<div class="setup">
<div class="logo-header">
<img height="100px" src="../../../assets/img/logo-big.png">
<img height="30px" style="vertical-align: bottom; margin-top: 10px" src="../../../assets/img/logo1-2.png"/>
<span class="logo-header-text">One-stop monitoring system</span>
<div class="language-select">
<el-dropdown :hide-on-click="false" >
<span class="el-dropdown-link">
<i class="nz-icon nz-icon-language-change" style="color: #e6eaed; font-size: 14px"></i>
</span>
<el-dropdown-menu slot="dropdown" >
<el-dropdown-item>
<div :style="language == 'en' ? 'color:#f90' : ''" @click="changeLocal('en')" id="header-to-english">
<i class="nz-icon nz-icon-lang-en"></i>
English
</div>
<div style="display: flex">
</el-dropdown-item>
<el-dropdown-item>
<div :style="language == 'cn' ? 'color:#f90' : ''" @click="changeLocal('cn')" id="header-to-chinese">
<i class="nz-icon nz-icon-lang-zh"></i>
中文
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div style="display: flex" class="flex-box">
<div class="step-box">
<div class="step-inner">
<el-steps direction="vertical" :active="step" finish-status="success">
<el-steps direction="vertical" space=0 :active="step" finish-status="success">
<el-step :title="$t('setup.step0')" ></el-step>
<el-step :title="$t('setup.step1')" ></el-step>
<el-step :title="$t('setup.step2')"></el-step>
@@ -15,108 +37,124 @@
</div>
</div>
<div class="setup-box">
<div style="position: relative; height: 50px">
<el-menu mode="horizontal" class="language-select">
<el-submenu index="1">
<template slot="title">{{$t('setup.language')}}</template>
<el-menu-item index="1">
<div :style="language=='en'?'color:#f90':''" @click="changeLocal('en')" id="header-to-english">English</div>
</el-menu-item>
<el-menu-item index="2">
<div :style="language=='cn'?'color:#f90':''" @click="changeLocal('cn')" id="header-to-chinese">中文</div>
</el-menu-item>
</el-submenu>
</el-menu>
</div>
<div class="setup-inner">
<div class="setup-inner" >
<template v-if="activeStep == 0">
<div class="welcome">
<div class="wel-header">
<!--Welcome to Nezha setup wizard!-->
{{$t('setup.welcome.header')}}
{{ $t("setup.welcome.header") }}
</div>
<div class="content-divider"/>
<div class="content-divider" />
<div class="wel-wizard">
<div class="wizard-header"><!--What will the wizard do for you?-->{{$t('setup.welcome.guid')}}</div>
<div class="wizard-header">
<!--What will the wizard do for you?-->{{
$t("setup.welcome.guid")
}}
</div>
<ul>
<li><!--Create a basic, single site configuration-->{{$t('setup.welcome.guid_1')}}</li>
<li><!--Tries to find problems within your Database and Redis setup-->{{$t('setup.welcome.guid_2')}}</li>
<li>
<!--Create a basic, single site configuration-->{{
$t("setup.welcome.guid_1")
}}
</li>
<li>
<!--Tries to find problems within your Database and Redis setup-->{{
$t("setup.welcome.guid_2")
}}
</li>
</ul>
</div>
<div class="content-divider"/>
<div class="content-divider" />
<div class="wel-continue">
<div class="wizard-header"><!--To continue-->{{$t('setup.welcome.toContinue')}}:</div>
<div>
<!--For security reasons you need to authenticate for the installation by creating the file-->{{$t('setup.welcome.creatFile')}} '/opt/nezha/nz-web/tmp/nezha.auth'.<br/><!--This can be done by executing the following command-->{{$t('setup.welcome.createFileTip')}}:
<div class="wizard-header">
<!--To continue-->{{ $t("setup.welcome.toContinue") }}:
</div>
<div>
<!--For security reasons you need to authenticate for the installation by creating the file-->{{
$t("setup.welcome.creatFile")
}}
'/opt/nezha/nz-web/tmp/nezha.auth'.<br /><!--This can be done by executing the following command-->{{
$t("setup.welcome.createFileTip")
}}:
</div>
<pre>echo -n {{ validateCode }} > /opt/nezha/nz-web/tmp/nezha.auth</pre>
<div>
<!--Click the 'Next' button when you've finished.-->{{
$t("setup.welcome.next")
}}
</div>
<pre>echo -n {{validateCode}} > /opt/nezha/nz-web/tmp/nezha.auth</pre>
<div><!--Click the 'Next' button when you've finished.-->{{$t('setup.welcome.next')}}</div>
</div>
</div>
</template>
<template v-if="activeStep == 1">
<div class="setup-config">
<el-form ref="db-form" :model="database" label-width="80px" :rules="dbRules" label-position="top" size="small" style="width: 600px" :validate-on-rule-change="false">
<el-form-item :label="$t('setup.host')" prop="host" key="dbhost">
<el-form ref="db-form" :model="database" label-width="80px" :rules="dbRules" label-position="top" size="small" style="width: 600px" :validate-on-rule-change="false" >
<el-form-item :label="$t('setup.host')" prop="host" key="dbhost" >
<el-input v-model="database.host"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.port')" prop="port" key="dbport">
<el-form-item :label="$t('setup.port')" prop="port" key="dbport" >
<el-input v-model="database.port"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.name')" prop="name" key="dbname">
<el-form-item :label="$t('setup.name')" prop="name" key="dbname" >
<el-input v-model="database.name"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.username')" prop="username" key="dbusername">
<el-form-item :label="$t('setup.username')" prop="username" key="dbusername" >
<el-input v-model="database.username"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.pin')" prop="pin" key="dbpassword">
<el-input v-model="database.pin" type="password" show-password></el-input>
<el-form-item :label="$t('setup.pin')" prop="pin" key="dbpassword" >
<el-input v-model="database.pin" type="password" show-password ></el-input>
</el-form-item>
</el-form>
<div class="setup-help">
<div class="help-header">
{{$t('setup.database.configTitle')}}
{{ $t("setup.database.configTitle") }}
</div>
<div class="help-body">
{{$t('setup.database.configTip')}}
{{ $t("setup.database.configTip") }}
</div>
</div>
</div>
</template>
<template v-if="activeStep == 2">
<div class="setup-config">
<el-form ref="redis-form" :model="redis" label-width="80px" :rules="redisRules" label-position="top" size="small" style="width: 600px" :validate-on-rule-change="false">
<el-form-item :label="$t('setup.host')" prop="host" key="rdhost">
<el-form ref="redis-form" :model="redis" label-width="80px" :rules="redisRules" label-position="top" size="small" style="width: 600px" :validate-on-rule-change="false" >
<el-form-item :label="$t('setup.host')" prop="host" key="rdhost" >
<el-input v-model="redis.host"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.port')" prop="port" key="rdport">
<el-form-item :label="$t('setup.port')" prop="port" key="rdport" >
<el-input v-model="redis.port"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.pin')" prop="pin" key="rdpassword">
<el-input v-model="redis.pin" type="password" show-password></el-input>
<el-form-item :label="$t('setup.pin')" prop="pin" key="rdpassword" >
<el-input v-model="redis.pin" type="password" show-password ></el-input>
</el-form-item>
</el-form>
<div class="setup-help">
<div class="help-header">
{{$t('setup.redis.configTitle')}}
{{ $t("setup.redis.configTitle") }}
</div>
<div class="help-body">
{{$t('setup.redis.configTip')}}
{{ $t("setup.redis.configTip") }}
</div>
</div>
</div>
</template>
<template v-if="activeStep == 3">
<div class="setup-config">
<el-form ref="sys-form" :model="system" label-width="80px" :rules="sysRules" label-position="top" size="small" style="width: 600px" :validate-on-rule-change="false">
<el-form-item :label="$t('setup.username')" prop="host" key="syshost">
<el-form ref="sys-form" :model="system" label-width="80px" :rules="sysRules" label-position="top" size="small" style="width: 640px" :validate-on-rule-change="false" >
<el-form-item :label="$t('setup.username')" prop="host" key="syshost" >
<el-input v-model="system.username"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.pin')" prop="pin" key="syspassword">
<el-input v-model="system.pin" type="password" show-password></el-input>
<el-form-item :label="$t('setup.pin')" prop="pin" key="syspassword" >
<el-input v-model="system.pin" type="password" show-password ></el-input>
</el-form-item>
<el-form-item :label="$t('setup.alertPath')" prop="alertPath" key="sysalertPath">
<el-input v-model="system.alertPath" ></el-input>
<el-form-item :label="$t('setup.alertPath')" prop="alertPath" key="sysalertPath" >
<el-input v-model="system.alertPath"></el-input>
</el-form-item>
<el-form-item :label="$t('setup.promentheusFederationEnabled')" prop="prometheusFederationEnabled" key="sysprometheusFederationEnabled" >
<el-select v-model="system.prometheusFederationEnabled" style="width: 100%" placeholder="Enable">
<el-option label="Enable" value="1"></el-option>
<el-option label="Close" value="0"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('setup.alertPrefix')" prop="alertPrefix" key="sysalertPrefix">
<el-input v-model="system.alertPrefix" ></el-input>
@@ -141,7 +179,7 @@
</template>
<div class="setup-bottom-btn">
<button @click="preStep" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" v-if="activeStep != 0">
<button @click="preStep" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" v-if="activeStep != 0" style="background-color:#fff;color:#333;border:1px solid rgba(0,0,0,0.15);">
<span>{{$t('setup.back')}}</span>
</button>
<button @click="nextStep" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" :disabled="prevent_next" v-if="activeStep != 3" :class="{'nz-btn-disabled':prevent_next}">
@@ -170,16 +208,20 @@ export default {
step: 0,
activeStep: 0,
database: {
host: '',
host: "",
port: 3306,
name: 'nz',
username: '',
pin: ''
name: "nz",
username: "",
pin: "",
},
dbRules: {
host: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: host, trigger: 'blur' }
{
required: true,
message: this.$t("validate.required"),
trigger: "blur",
},
{ validator: host, trigger: "blur" },
],
port: [{ validator: port, trigger: 'blur' }],
name: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
@@ -187,14 +229,18 @@ export default {
pin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
},
redis: {
host: '',
host: "",
port: 6379,
pin: ''
pin: "",
},
redisRules: {
host: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: host, trigger: 'blur' }
{
required: true,
message: this.$t("validate.required"),
trigger: "blur",
},
{ validator: host, trigger: "blur" },
],
port: [{ validator: port, trigger: 'blur' }]
},
@@ -204,13 +250,15 @@ export default {
alertPath: '',
alertPrefix: '',
haMode: 1,
haVip: ''
haVip: '',
prometheusFederationEnabled:'',
},
sysRules: {
username: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
pin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
alertPath: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
haVip: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
haVip: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
prometheusFederationEnabled: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
},
reloadTime: 5000,
reloadTimeout: null,
@@ -421,94 +469,129 @@ export default {
</script>
<style scoped>
.setup{
.setup {
/*display: flex;*/
width: 1250px;
width: 100%;
height: 100%;
margin: 0 auto;
}
.logo-header{
}
.logo-header {
padding-left: 20px;
width: 100%;
height: 100px;
}
.language-select{
position: absolute;
right: 20px;
height: 50px;
background-color: #202f3f;
position: relative;
}
.logo-header-text {
font-family: Verdand;
font-size: 18px;
font-weight: 400;
letter-spacing: 0;
color: #dedede;
}
.language-select {
position: absolute;
top: 0;
right: 20px;
z-index: 2;
}
.setup .step-box{
width: 200px;
margin-top: 15px;
margin-right: 20px;
}
.flex-box{
height: calc(100% - 50px);
}
.setup .step-box {
width: 240px;
height: 100%;
}
.setup .setup-box{
width: calc(100% - 200px);
}
.setup .setup-box {
width: calc(100% - 240px);
height: 100%;
}
.step-box .step-inner {
height: 100%;
}
.step-box .step-inner{
height: 600px;
padding:20px;
}
.setup-box .setup-inner{
position: relative;
width: calc(100% - 42px);
height: 600px;
padding: 20px;
border: 1px solid #EEEEEE;
}
.setup-inner .setup-config{
padding-left: 0;
box-sizing: border-box;
}
.setup-box .setup-inner {
position: relative;
}
.setup-inner .setup-help{
width: calc(100% - 640px);
height: 500px;
height: 100%;
padding: 40px 30px 0 30px;
border: 10px solid #eeeeee;
box-sizing: border-box;
}
.setup-inner .setup-config {
position: relative;
height: 100%;
}
.setup-inner .setup-help {
width: calc(100% - 710px);;
height:calc(100% - 50px);
position: absolute;
top: 20px;
right: 0px;
border-left: 1px solid #ddd;
padding-left: 10px;
}
.setup .setup-help .help-header{
font-weight: 800;
font-size: 30px;
}
.setup .setup-help .help-body{
border-left: 1px solid #E7EAED;
padding-left: 30px;
}
.setup .setup-help .help-header {
font-family: Roboto-Medium;
font-size: 22px;
color: #333333;
font-weight: 500;
margin-bottom: 20px;
}
.setup .setup-help .help-body {
font-family: Roboto-Regular;
font-size: 16px;
color: #333333;
line-height: 28px;
font-weight: 400;
}
.welcome {
line-height: 35px;
font-size: 16px;
}
.welcome{
line-height: 35px;
font-size: 16px;
}
.welcome .wel-header{
font-weight: 800;
font-size: 30px;
}
.wizard-header{
font-weight: 600;
font-size: 20px;
}
.welcome ul li{
}
.welcome .wel-header {
font-family: Roboto-Medium;
font-size: 26px;
color: #333333;
font-weight: 500;
}
.wizard-header {
font-family: Roboto-Bold;
font-size: 14px;
color: #333333;
font-weight: 700;
}
.welcome ul li {
list-style: inside !important;
}
.welcome pre{
border: 1px solid #ddd;
border-left: 4px solid #e6522c;
font-family: Roboto-Regular;
font-size: 14px;
color: #333333;
font-weight: 400;
}
.welcome pre {
border: 1px solid #eae7ed;
border-left: 4px solid #fa901c;
border-radius: 0;
font-family: "Courier New", Monaco, Menlo, Consolas, monospace;
background-color: #f5f5f5;
font-size: 14px;
background-color: #f9f9f9;
color: #333;
padding: 15px;
}
.welcome .content-divider{
height: 48px;
line-height: 16px;
box-sizing: border-box;
}
.welcome .content-divider {
height: 1px;
width: 100%;
border-bottom: 2px solid #C0C4CC;
border-bottom: 1px solid #eae7ed;
margin: 5px 0px;
}
.setup-bottom-btn{
}
.setup-bottom-btn {
width: 100%;
height: 49px;
position: absolute;
@@ -516,18 +599,67 @@ export default {
right: 20px;
padding-top: 20px;
text-align: right;
}
}
/* 步骤条样式 */
/deep/ .el-step{
height: 46px ;
/* height: 46px !important; */
}
/deep/ .el-step .el-step__head{
/* display: none !important; */
display: none ;
}
/deep/ .el-step .el-step__main{
padding-left: 20px ;
height: 46px ;
line-height: 46px;
/* padding-left: 20px !important;
height: 46px !important; */
}
/deep/ .el-step .el-step__main .el-step__title{
padding: 0 0 0 20px ;
font-family: Roboto-Medium;
font-size: 16px;
color: #999;
letter-spacing: 0;
font-weight: 400;
padding-left: 20px;
margin-top: 11px;
/* padding: 0 0 0 20px !important; */
}
/deep/ .el-step .el-step__main .el-step__title.is-process{
border-left:2px solid #fa901c ;
color: #333333;
font-weight: 500;
padding-left: 18px;
/* border-left:2px solid #fa901c !important; */
/* padding-left: 18px !important; */
}
/deep/ .el-step .el-step__main .el-step__title.is-success{
color: #333333;
font-weight: 500;
}
/deep/ .el-step .el-step__main .el-step__description{
/* display: none !important; */
display: none ;
}
.el-select-dropdown__item.selected{
font-weight: 400;
}
/* .el-select-dropdown__item.hover{
font-weight: 700;
} */
</style>
<style>
.setup .el-menu--horizontal>.el-submenu.is-active .el-submenu__title {
.setup .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: unset !important;
color: #303133;
background-color:transparent;
}
.language-select .el-submenu__title{
background-color: transparent;
}
.language-select .el-submenu__title {
height: 50px !important;
}
.language-select .el-submenu{
}
.language-select .el-submenu {
height: 50px !important;
}
}
</style>

View File

@@ -250,6 +250,7 @@ import draggable from 'vuedraggable'
import notifyMethod from './system/notifyMethodTab'
import linkTab from './system/linkTab'
import apiKeyTab from './system/apiKeyTab'
import moment from 'moment-timezone'
export default {
name: 'system',
components: { draggable, latlngPicker, notifyMethod, linkTab, apiKeyTab },
@@ -459,6 +460,10 @@ export default {
if (response.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
// this.resetForm(formName);
if (type == 'basic') {
localStorage.setItem('nz-sys-timezone', param.timezone)
localStorage.setItem('timezoneOffset', moment.tz(param.timezone).format('Z'))
}
setTimeout(() => {
this.querySetInfo(type)
}, 200)

View File

@@ -50,7 +50,7 @@
</template>
<template v-if="item.prop == 'expireAt'">
<!-- <el-popover :content="rules.expireAt.message" placement="top" trigger="manual" v-model="rules.expireAt.switch" popper-class="small-pop warn-pop" @after-enter="popShow(rules.expireAt)">-->
<el-date-picker
<my-date-picker
slot="reference"
style="width: 100%;"
v-model="scope.row[item.prop]"
@@ -60,7 +60,7 @@
type="datetime"
:picker-options="pickerOptions"
:placeholder="$t('el.datepicker.selectTime')">
</el-date-picker>
</my-date-picker>
<!-- </el-popover>-->
</template>
</template>

View File

@@ -10,7 +10,7 @@
<el-button class="metric-btn nz-btn nz-btn-size-normal nz-btn-style-light" @click="toggleDropdown">Metric
&nbsp;<i class="nz-icon nz-icon-arrow-down"></i></el-button>
<el-cascader-panel v-loading="tempBoxShowLoading" v-show="dropDownVisible" v-model="cascaderValue" v-clickoutside="closeDropdown"
slot="dropdown" ref="metricSelector" :props="{emitPath:false,}"
slot="dropdown" ref="metricSelector" :props="{emitPath:false,}" :loading="loading"
:options="metricOptions" @change="metricChange">
<template slot-scope="{ node, data }">
@@ -178,6 +178,10 @@ export default {
typeContentLoading: {
type: Boolean,
default: false
},
fromFatherData: {
type: Boolean,
default: false
}
// metricOptions: {type: Array},
// metricStore: {type: Array}
@@ -204,11 +208,14 @@ export default {
datacenterOption: [],
projectOption: [],
filterSilence: '',
tempBoxId: {}
tempBoxId: {},
loading: false
}
},
created () {
mounted () {
if (!this.fromFatherData) {
this.queryMetrics()
}
},
methods: {
closeDropdown () {
@@ -229,8 +236,15 @@ export default {
},
toggleDropdown () {
this.dropDownVisible = !this.dropDownVisible
this.getMetricOptions()
},
getMetricOptions () {
if (!this.metricOptions.length) {
this.queryMetrics()
}
},
queryMetrics: function () {
this.loading = true
this.$get('prom/api/v1/label/__name__/values').then(response => {
if (response.status == 'success') {
const metrics = response.data.sort()
@@ -300,6 +314,7 @@ export default {
},
getExprTemp () {
this.$get('/expression/tmpl/gname').then(res => {
this.loading = false
if (res.code === 200) {
res.data.list.forEach(item => {
this.metricOptions.unshift({

View File

@@ -17,7 +17,7 @@
<!--<div class="top-tools">
<div class="float-right mr-10">
<el-date-picker size="mini" ref="calendar"
<my-date-picker size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm"
@change="dateChange"
v-model="searchTime"
@@ -27,7 +27,7 @@
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')"
align="right">
</el-date-picker>
</my-date-picker>
</div>
</div>-->
<div class="table-list" >
@@ -38,7 +38,7 @@
</el-col>
<el-col :span="0.5" ><div>&nbsp;</div></el-col>
<el-col :span="13" class="chart-preview-area" >
<el-date-picker size="mini" ref="calendar"
<my-date-picker size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm"
@change="dateChange"
v-model="searchTime"
@@ -49,7 +49,7 @@
:end-placeholder="$t('dashboard.panel.endTime')"
style="position:absolute; right: 10px"
align="right">
</el-date-picker>
</my-date-picker>
<el-row class="border-area" v-show="chartCount === 'single'" style="margin-top: 40px;">
<div class="chartBox">
<line-chart-block

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
.overview {
height: 100%;
padding: 0 10px;
background-color: #f6f6f6;
}
.overview-content-header{

View File

@@ -57,7 +57,7 @@
</template>
<template v-slot:after>
<el-dropdown-item v-has="'panel_chart_add'">
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-download1"></i>Add template</div>
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-download1"></i>Add by template</div>
</el-dropdown-item>
</template>
</top-tool-more-options>
@@ -65,7 +65,7 @@
</template>
</div>
<div id="tableList" class="table-list">
<div ref="dashboardScrollbar" style="height: 100%; overflow: auto;">
<div ref="dashboardScrollbar" style="height: calc(100% - 1px); overflow: auto;" :class="overScroll10?'border-t-1-de':'border-t-1-tr'">
<div class="box-content">
<chart-list ref="chartList" :class="{'show-top':showTopBtn}" :from="$CONSTANTS.fromRoute.panel" :panel-lock="panelLock" @on-edit-chart="editChart" @on-refresh-time="refreshTime" @on-remove-chart="delChart" @on-add-group-item-chart="addGroupItem"></chart-list>
</div>
@@ -102,6 +102,7 @@ export default {
name: 'panel',
data () {
return {
overScroll10: false,
panelLock: true,
showTopBtn: false, // top按钮
visible: false,
@@ -571,6 +572,7 @@ export default {
const _self = this
this.scrollbarWrap.addEventListener('scroll', bus.debounce(function () {
_self.showTopBtn = _self.scrollbarWrap.scrollTop > 50
_self.overScroll10 = _self.scrollbarWrap.scrollTop > 50
_self.$refs.chartList.loadChartData(_self.scrollbarWrap.scrollTop)
}, 300))
},
@@ -783,6 +785,12 @@ export default {
}
</script>
<style lang="scss">
.border-t-1-de{
border-top: 1px solid #dedede;
}
.border-t-1-tr{
border-top: 1px solid transparent;
}
.panel {
height: 100%;
display: flex;

View File

@@ -65,7 +65,7 @@
<addEndpointBox v-if="rightBox.show" :endpoint="object" @close="closeRightBox"></addEndpointBox>
</transition>
<transition name="right-box">
<edit-endpoint-box-new v-if="rightBox.editShow" :module="object" @close="closeRightEditBox" :disabled="true" :type="'edit'"></edit-endpoint-box-new>
<edit-endpoint-box-new v-if="rightBox.editShow" :module="object" @close="closeRightEditBox" :disabled="true" :optionType="'edit'"></edit-endpoint-box-new>
</transition>
<transition name="right-box">
<batchModifyEndpoint v-if="rightBox.batchModify" :module="object" @close="closeRightBatchModify" :selectEndpointList="batchDeleteObjs" :disabled="true" :type="'edit'"></batchModifyEndpoint>

View File

@@ -28,7 +28,7 @@ export function get (url, params) {
axios.get(url, {
params: params
}).then(response => {
resolve(response.data, response)
resolve(response.data)
}).catch(err => {
if (err.response) {
resolve(err.response.data)

View File

@@ -272,6 +272,20 @@ export default new Vue({
return sourceTime
}
},
// 将本地时区转为系统配置的时区
computeTimezoneTime: function (sourceTime) {
let offset = localStorage.getItem('nz-sys-timezone')
offset = moment.tz(offset).format('Z')
if (offset && offset !== 'undefined') {
offset = Number.parseInt(offset)
const date = new Date(sourceTime)
const localOffset = date.getTimezoneOffset() * 60 * 1000 // 默认 一分钟显示时区偏移的结果
const utcTime = date.getTime() + localOffset
return utcTime + (offset * 60 * 60 * 1000)
} else {
return sourceTime
}
},
getTimezontDateRange: function (offset = -1) {
return [
new Date(new Date(this.computeTimezone(new Date().getTime())).setHours(new Date(this.computeTimezone(new Date().getTime())).getHours() + offset)),

View File

@@ -31,15 +31,16 @@ import loading from '@/components/common/loading'
import pickTime from '@/components/common/pickTime'
import bus from '@/libs/bus'
import theme from '@/assets/css/theme.scss'
import myDatePicker from '@/components/common/myDatePicker'
import vSelectPage from 'v-selectpage'
Vue.use(vSelectPage)
Vue.use(myDatePicker)
Vue.component('Pagination', Pagination)
Vue.component('searchInput', searchInput)
Vue.component('element-set', elementSet)
Vue.component('loading', loading)
Vue.component('pick-time', pickTime)
Vue.component('myDatePicker', myDatePicker)
Vue.prototype.$axios = axios
Vue.prototype.$post = post

View File

@@ -31,7 +31,7 @@ export default new Router({
},
{
path: 'overview',
component: resolve => require(['../components/page/dashboard/overview/overview2.vue'], resolve)
component: resolve => require(['../components/page/dashboard/overview/overview.vue'], resolve)
},
{
path: '/monitor/project',

View File

@@ -2,6 +2,7 @@ import { post } from '../http'
import router from '../router'
import bus from '../libs/bus'
import { sortByOrderNum } from '../permission'
import moment from 'moment-timezone'
const user = {
state: {
@@ -44,6 +45,7 @@ const user = {
localStorage.setItem('nz-sys-logo', res.data.systemLogo)
}
localStorage.setItem('nz-sys-timezone', res.data.timezone)
localStorage.setItem('timezoneOffset', moment.tz(res.data.timezone).format('Z'))
localStorage.setItem('nz-sys-default-cabinet-usize', res.data.defaultCabinetUsize)
localStorage.setItem('nz-sys-max-terminal-num', res.data.maxTerminalNum)
localStorage.setItem('nz-sys-asset-ping-switch', res.data.assetPingSwitch)
@@ -56,7 +58,7 @@ const user = {
bus.$emit('login')
router.push({
path: menuList.find(menu => { return menu.route && menu.route != '/header' }).route,
path: 'overview',
query: {
t: +new Date()
}