diff --git a/nezha-fronted/build/webpack.dev.conf.js b/nezha-fronted/build/webpack.dev.conf.js index 3c6ef7a3d..3c79326bf 100644 --- a/nezha-fronted/build/webpack.dev.conf.js +++ b/nezha-fronted/build/webpack.dev.conf.js @@ -55,6 +55,7 @@ const devWebpackConfig = merge(baseWebpackConfig, { new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ + favicon: path.resolve(__dirname, '../src/assets/img/favicon.ico'), filename: 'index.html', template: 'index.html', inject: true diff --git a/nezha-fronted/build/webpack.prod.conf.js b/nezha-fronted/build/webpack.prod.conf.js index 37f617375..b3d516e39 100644 --- a/nezha-fronted/build/webpack.prod.conf.js +++ b/nezha-fronted/build/webpack.prod.conf.js @@ -91,6 +91,7 @@ const webpackConfig = merge(baseWebpackConfig, { // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ + favicon: path.resolve(__dirname, '../src/assets/img/favicon.ico'), filename: config.build.index, template: 'index.html', hash: false, diff --git a/nezha-fronted/config/index.js b/nezha-fronted/config/index.js index 6a6ff39bc..b270f7a71 100644 --- a/nezha-fronted/config/index.js +++ b/nezha-fronted/config/index.js @@ -22,7 +22,7 @@ module.exports = { // host: '0.0.0.0', // can be overwritten by process.env.HOST host: 'localhost', // can be overwritten by process.env.HOST port: 80, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined - autoOpenBrowser: true, + autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- diff --git a/nezha-fronted/index.html b/nezha-fronted/index.html index 740f68da9..835362dc2 100644 --- a/nezha-fronted/index.html +++ b/nezha-fronted/index.html @@ -5,8 +5,7 @@ - - + Network Zodiac diff --git a/nezha-fronted/src/components/common/alert/alertMessageInfoTab.vue b/nezha-fronted/src/components/common/alert/alertMessageInfoTab.vue index e50b10ad7..b9347c7ec 100644 --- a/nezha-fronted/src/components/common/alert/alertMessageInfoTab.vue +++ b/nezha-fronted/src/components/common/alert/alertMessageInfoTab.vue @@ -40,8 +40,8 @@ diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/panelTabNew.vue b/nezha-fronted/src/components/common/bottomBox/tabs/panelTabNew.vue index 56b62dcc3..d5ce05025 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/panelTabNew.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/panelTabNew.vue @@ -494,7 +494,6 @@ export default { if (this.$refs.pickTime) { const nowTimeType = this.$refs.pickTime.$refs.timePicker.nowTimeType this.nowTimeType = this.$refs.pickTime.$refs.timePicker.nowTimeType - console.log(nowTimeType, this.nowTimeType) this.setSearchTime(nowTimeType.type, nowTimeType.value) this.filter.start_time = bus.timeFormate(this.searchTime[0]) this.filter.end_time = bus.timeFormate(this.searchTime[1]) @@ -520,7 +519,6 @@ export default { this.$set(this.searchTime, 0, startTime) this.$set(this.searchTime, 1, endTime) this.$set(this.searchTime, 2, val + 'h') - console.log(this.searchTime) } else if (type === 'date') { const startTime = bus.timeFormate(new Date(bus.computeTimezone(new Date().getTime())).setDate(new Date(bus.computeTimezone(new Date().getTime())).getDate() - val)) const endTime = bus.timeFormate(new Date(bus.computeTimezone(new Date().getTime()))) diff --git a/nezha-fronted/src/components/common/js/validate.js b/nezha-fronted/src/components/common/js/validate.js index 7e614a1dd..695c01fda 100644 --- a/nezha-fronted/src/components/common/js/validate.js +++ b/nezha-fronted/src/components/common/js/validate.js @@ -221,3 +221,10 @@ export function sysObjectIdInput (rule, value, callback) { export function longAndLat (rule, value, callback) { // 校验经纬度 } +export function dataValidate () { + // const time = '([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$' + // const YMD = '/((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))' + // const DMY = '/((^(3[01]|[12][0-9]|0[1-9])(\\/)(10|12|0[13578])(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(30|[12][0-9]|0[1-9])(\\/)(11|0[469])(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(2[0-8]|1[0-9]|0[1-9])(\\/)(02)(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(29)(\\/)(02)(\\/)([2468][048]00)$)|(^(29)(\\/)(02)(\\/)([3579][26]00)$)|(^(29)(\\/)(02)(\\/)([1][89][0][48])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][0][48])$)|(^(29)(\\/)(02)(\\/)([1][89][2468][048])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][2468][048])$)|(^(29)(\\/)(02)(\\/)([1][89][13579][26])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][13579][26])$))/' + // const MDY = +} + diff --git a/nezha-fronted/src/components/common/myDatePicker/src/panel/date-range.vue b/nezha-fronted/src/components/common/myDatePicker/src/panel/date-range.vue index a557e15a7..facc15492 100644 --- a/nezha-fronted/src/components/common/myDatePicker/src/panel/date-range.vue +++ b/nezha-fronted/src/components/common/myDatePicker/src/panel/date-range.vue @@ -5,7 +5,8 @@ class="el-picker-panel el-date-range-picker el-popper time-picker-popover__select-top" :class="[{ 'has-sidebar': $slots.sidebar || shortcuts, - 'has-time': showTime + 'has-time': showTime, + 'el-picker-panel__body__only': isOnly }, popperClass]">
@@ -17,7 +18,7 @@ :key="key" @click="handleShortcutClick(shortcut)">{{shortcut.text}}
-
+
@@ -84,7 +85,9 @@
-
+
+ + + +
{{ leftLabel }}
+
-
+
@@ -327,6 +332,7 @@ export default { const vm = this return { assetConstants, + judgeTypes: true, showAllTalonOption: false, showAddressOption: true, talonShowTow: true, @@ -546,6 +552,14 @@ export default { this.getFieldGroupData() }, methods: { + judgeType () { + if (!this.editAsset.type.name) { + this.$message.error(this.$t('asset.assetBox.message.type')) + return false + } else { + this.judgeTypes = false + } + }, clickOutside () { this.esc(false) }, @@ -629,6 +643,10 @@ export default { }) }, selectType (type) { + this.$refs.cascader.$refs.panel.clearCheckedNodes() + this.$refs.cascader.$refs.panel.activePath = [] + this.editAsset.brandAndModel = '' + this.lockModelInputValue = '' this.editAsset.type = { ...type } this.editAsset.typeId = type.id ? type.id : '' this.editAsset.authType = '' @@ -639,6 +657,7 @@ export default { this.editAsset.snmpCredentialId = '' this.editAsset.authProtocolPort = '' this.editAsset.pid = '' + this.getModelData() }, addLabel ([groupId, metaId]) { const label = this.options.metaOptions.find(m => m.id === metaId) @@ -798,7 +817,7 @@ export default { }, getModelData () { return new Promise(resolve => { - this.$get('asset/model?pageSize=-1').then(response => { + this.$get('asset/model?pageSize=-1&typeIds=' + this.editAsset.typeId).then(response => { if (response.code === 200) { this.options.modelOptions = response.data.list const titleSearchData = {} @@ -810,6 +829,11 @@ export default { } }) this.options.brandAndModelOptions = Object.keys(titleSearchData).map(b => titleSearchData[b]) + if (!this.editAsset.type.name) { + this.judgeTypes = true + } else { + this.judgeTypes = false + } } resolve() }) diff --git a/nezha-fronted/src/components/common/timePicker.vue b/nezha-fronted/src/components/common/timePicker.vue index 52f41880f..b0bc33fee 100644 --- a/nezha-fronted/src/components/common/timePicker.vue +++ b/nezha-fronted/src/components/common/timePicker.vue @@ -46,22 +46,32 @@ size="mini" ref="calendar" :format="timeFormatStrToDatePickFormat(timeFormatMain)" - @change="dateChange(whoChoose)" - v-model="searchTimeValue" - type="date" + :value-format="timeFormatStrToDatePickFormat(timeFormatMain)" + @change="dateChange" + :default-time="['00:00:00', '23:59:59']" + v-model="oldSearchTime" + :isOnly="true" + type="daterange" popper-class="panel-time-picker-popper time-picker-popover__select-top" align="right" > - +
{{$t('dashboard.panel.chartForm.valMapping.from')}}
-
- +
+ +
+ +
+
{{inputError}}
{{$t('dashboard.panel.chartForm.valMapping.to')}}
-
- - +
+ +
+ +
+
{{$t('date.formatError')}}
import bus from '@/libs/bus' +import moment from 'moment-timezone' export default { name: 'timePicker', @@ -159,6 +170,13 @@ export default { bus.timeFormate(bus.getOffsetTimezoneData(-1)), bus.timeFormate(bus.getOffsetTimezoneData()) ], + oldSearchTime: [bus.timeFormate(bus.getOffsetTimezoneData(-1)), + bus.timeFormate(bus.getOffsetTimezoneData())], + oldSearchTimeError: { + 0: false, + 1: false + }, + inputError: this.$t('date.formatError'), showTime: { id: 4, text: this.$t('dashboard.panel.lastOneHour') @@ -253,6 +271,9 @@ export default { this.getItem() this.getUtcStr() this.getRangeHistoryArr() + const timeTemp = this.$loadsh.cloneDeep(this.searchTime) + this.oldSearchTime[0] = timeTemp[0] + this.oldSearchTime[1] = timeTemp[1] }, methods: { changeDropdownFlag () { @@ -268,8 +289,8 @@ export default { this.utc = localStorage.getItem('timezoneOffset') }, myDatePickerShow (item) { - this.whoChoose = item - this.isCustom = true + // this.whoChoose = item + // this.isCustom = true this.$refs.calendar.focus() this.$refs.calendar.pickerVisible = true if (document.getElementById('viewGraphDialog')) { @@ -308,9 +329,13 @@ export default { this.utcStr = str + this.utc }, timeRange (item) { + if (this.oldSearchTimeError[0] || this.oldSearchTimeError[1]) { + return + } + this.searchTime = this.$loadsh.cloneDeep(this.oldSearchTime) this.showTime = this.nowTimeType = { id: 0, - text: this.$t('dashboard.panel.customTimeRange'), + text: this.searchTime[0] + ' ' + this.$t('dashboard.panel.to') + ' ' + this.searchTime[1], value: -1 } this.isCustom = true @@ -329,49 +354,42 @@ export default { this.$emit('change', this.searchTime) }, showDropdown () { + const timeTemp = this.$loadsh.cloneDeep(this.searchTime) + this.oldSearchTime[0] = timeTemp[0] + this.oldSearchTime[1] = timeTemp[1] + this.oldSearchTimeError[0] = false + this.oldSearchTimeError[1] = false this.dropdownFlag = !this.dropdownFlag }, - dateChange (type, v) { + dateInputChange (type, v) { if (type == 'start') { - if (!v) { - const startTime = bus.timeFormate(this.searchTimeValue).trim().split(' ')[0] + ' ' - this.$set(this.searchTime, 0, startTime) + const dateValidate = moment(this.oldSearchTime[0], this.timeFormatMain).isValid() + if (!dateValidate) { + this.inputError = this.$t('date.formatError') + this.oldSearchTimeError[0] = true } else { - const str = v.trim().split(' ')[1] - const reg = /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/ - if (reg.test(str)) { - const startTime = bus.timeFormate(v) - this.$set(this.searchTime, 0, startTime) - } else { - this.$set(this.searchTime, 0, '') - } + this.oldSearchTimeError[0] = false + this.oldSearchTime[0] = bus.timeFormate(this.oldSearchTime[0]) } } else if (type == 'end') { - if (!v) { - const endTime = bus.timeFormate(this.searchTimeValue).trim().split(' ')[0] + ' ' - this.$set(this.searchTime, 1, endTime) + const dateValidate = moment(this.oldSearchTime[1], this.timeFormatMain).isValid() + if (!dateValidate) { + this.oldSearchTimeError[1] = true } else { - const str = v.trim().split(' ')[1] - const reg = /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/ - if (reg.test(str)) { - const endTime = bus.timeFormate(v) - this.$set(this.searchTime, 1, endTime) - } else { - this.$set(this.searchTime, 1, '') - } + this.oldSearchTimeError[1] = false + // this.$set(this.oldSearchTime, 1, bus.timeFormate(this.oldSearchTime[1])) + this.oldSearchTime[1] = bus.timeFormate(this.oldSearchTime[1]) } } - this.searchTime[2] = '' - this.$set(this.showTime, 'id', 0) - this.$set( - this.showTime, - 'text', - this.searchTime[0] + - ' ' + - this.$t('dashboard.panel.to') + - ' ' + - this.searchTime[1] - ) + console.log(moment(this.oldSearchTime[0], this.timeFormatMain).isValid(), moment(this.oldSearchTime[1], this.timeFormatMain).isValid(), !moment(this.oldSearchTimeError[0]).isBefore(this.oldSearchTime[1])) + if (moment(this.oldSearchTime[0], this.timeFormatMain).isValid() && moment(this.oldSearchTime[1], this.timeFormatMain).isValid() && !moment(this.oldSearchTimeError[0]).isBefore(this.oldSearchTime[1])) { + this.oldSearchTimeError[0] = true + this.inputError = this.$t('date.fromGreaterTo') + } + }, + dateChange () { + this.oldSearchTimeError[0] = false + this.oldSearchTimeError[1] = false }, setCustomTime (timeGroup, timeRange) { if (timeGroup) { @@ -560,6 +578,13 @@ export default { } } } + }, + sign (n) { + if (n) { + this.rangeHistory = localStorage.getItem('date-range-history' + this.sign) + ? JSON.parse(localStorage.getItem('date-range-history' + this.sign)) + : [] + } } } } diff --git a/nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx b/nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx index cb9051b71..312fa1134 100644 --- a/nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx +++ b/nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx @@ -120,15 +120,15 @@ export const baseTheme = EditorView.theme({ lineHeight: '1', marginRight: '10px', verticalAlign: 'top', - '&:after': { content: "'\\ea88'" }, - fontFamily: 'codicon', + '&:after': { content: "'\\e76f'" }, + fontFamily: 'nz-icon', paddingRight: '0', opacity: '1', color: '#007acc', }, '.cm-completionIcon-function, .cm-completionIcon-method': { - '&:after': { content: "'\\ea8c'" }, + '&:after': { content: "'\\e76f'" }, color: '#652d90', }, '.cm-completionIcon-class': { @@ -141,7 +141,7 @@ export const baseTheme = EditorView.theme({ '&:after': { content: "'𝑥'" }, }, '.cm-completionIcon-constant': { - '&:after': { content: "'\\eb5f'" }, + '&:after': { content: "'\\e76f'" }, color: '#007acc', }, '.cm-completionIcon-type': { @@ -154,14 +154,14 @@ export const baseTheme = EditorView.theme({ '&:after': { content: "'□'" }, }, '.cm-completionIcon-keyword': { - '&:after': { content: "'\\eb62'" }, + '&:after': { content: "'\\e76f'" }, color: '#616161', }, '.cm-completionIcon-namespace': { '&:after': { content: "'▢'" }, }, '.cm-completionIcon-text': { - '&:after': { content: "'\\ea95'" }, + '&:after': { content: "'\\e76f'" }, color: '#ee9d28', }, }); @@ -180,4 +180,4 @@ export const promqlHighlighter = HighlightStyle.define([ { tag: tags.brace }, { tag: tags.invalid, color: 'red' }, { tag: tags.comment, color: '#888', fontStyle: 'italic' }, -]); \ No newline at end of file +]); diff --git a/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue b/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue index 4aefd59ce..16d9d83ac 100644 --- a/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue +++ b/nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue @@ -76,15 +76,18 @@ class="input-box" @click="dropDownVisible = false" > -
- + >
{{ errorMsg }} @@ -231,8 +234,10 @@ @click="dropDownVisible = false" v-if="plugins.indexOf('metric-input') > -1" > -
- + >
{{ errorMsg }}
@@ -420,6 +426,7 @@ import { lintKeymap } from '@codemirror/lint' import { baseTheme, promqlHighlighter } from './CMTheme.tsx' import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets' import { autocompletion, completionKeymap, CompletionContext, CompletionResult } from '@codemirror/autocomplete' +import { newCompleteStrategy } from 'codemirror-promql/dist/esm/complete' export default { name: 'promqlInput', @@ -459,7 +466,7 @@ export default { }, data () { return { - oldcCodeLength:'', + oldcCodeLength: '', newView: null, codeMirrorValue: [], dropDownVisible: false, @@ -527,8 +534,7 @@ export default { } }, mounted () { - this.initCodeMirror() - if (!this.fromFatherData && this.type !== 'logs') { + if (!this.fromFatherData && this.type !== 'log') { this.queryMetrics() } }, @@ -537,22 +543,48 @@ export default { const self = this const promQL = new PromQLExtension().setComplete( { - remote: { - url: 'http://192.168.40.42:8080/prom', - fetchFn: this.fetchFn, - cache: { - initialMetricList: [ - 'ALERTS', - 'ALERTS_FOR_STATE', - 'alertmanager_alerts', - 'alertmanager_alerts_invalid_total', - 'alertmanager_alerts_received_total', - 'nz-agent' - ] + completeStrategy: query(newCompleteStrategy({ + remote: { + url: 'http://192.168.40.42:8080/prom', + fetchFn: this.fetchFn } - } + })) } ) + function query (CompleteStrategy) { + const obj = {} + obj.complete = CompleteStrategy + obj.queryHistory = [] + obj.promQL = function (context) { + return Promise.resolve(this.complete.promQL(context)).then((res) => { + const { state, pos } = context + const tree = syntaxTree(state).resolve(pos, -1) + const start = res != null ? res.from : tree.from + + if (start !== 0) { + return res + } + + const historyItems = { + from: start, + to: pos, + options: this.queryHistory.map((q) => ({ + label: q.length < 80 ? q : q.slice(0, 76).concat('...'), + detail: 'past query', + apply: q, + info: q.length < 80 ? undefined : q + })), + span: /^[a-zA-Z0-9_:]+$/ + } + if (res !== null) { + historyItems.options = historyItems.options.concat(res.options) + } + // console.log(historyItems) + return historyItems + }) + } + return obj + } const dynamicConfigCompartment = new Compartment() const dynamicConfig = [ promqlHighlighter, @@ -622,92 +654,63 @@ export default { const view = new EditorView({ state: EditorViewstate, // parent: document.getElementById('editor') - parent: document.getElementById('editor'+self.index) + parent: document.getElementById('editor' + self.index) }) self.newView = view } else { - console.log('viewIsOk') + // console.log('viewIsOk') // const { from} = self.newView.state.selection.ranges[0] // const to = self.codeMirrorValue.length const to = self.oldcCodeLength const from = self.oldcCodeLength - console.log(from,to); + // console.log(from, to) self.newView.dispatch( self.newView.state.update({ effects: dynamicConfigCompartment.reconfigure(dynamicConfig), - changes:{from,to,insert:self.codeMirrorValue[self.index]} + changes: { from, to, insert: self.codeMirrorValue[self.index] } }) ) } }, newChange (val) { - console.log('newchange', val) - if(val){ + // console.log('newchange', val) + if (val) { this.oldcCodeLength = val.length - console.log(this.oldcCodeLength); + // console.log(this.oldcCodeLength) this.codeMirrorValue[this.index] = val this.expressionList[this.index] = val - console.log(this.codeMirrorValue); + // console.log(this.codeMirrorValue) this.metricKeyDown(val) - }else{ - this.oldcCodeLength = 0; + } else { + this.oldcCodeLength = 0 this.codeMirrorValue[this.index] = '' } }, newDoc (val) { - console.log('doc', val) - }, - getHint (val, params, b, c, d) { - if (params) { - console.log(val, params, b, c, d, 123123123) - console.log(JSON.stringify(params.body)) - return this.sendAjax('', params) - } else { - return this.sendAjax('http://192.168.44.61:10091/api/v1/series', {}) - } - - // this.$post('api/v1/series') + // console.log('doc', val) }, fetchFn (a, b) { + const params = {} if (b) { - const form = new FormData() - console.log(b.body) - form.append('match[]', b.body.getAll('match[]')) - return this.$post(a, form) - } else { - return this.$get(a) - } - }, - sendAjax (url, body) { - // 构造表单数据 - return new Promise(resolve => { - const nowUrl = url - const formData = new FormData() - formData.append('username', 'johndoe') - formData.append('id', 123456) - // 创建xhr对象 - const xhr = { - ...new XMLHttpRequest(), - ...body - } - - // 设置xhr请求的超时时间 - xhr.timeout = 3000 - // 设置响应返回的数据格式 - xhr.responseType = '' - // 创建一个 post 请求,采用异步 - xhr.open('post', nowUrl, true) - xhr.setRequestHeader('Authorization', localStorage.getItem('nz-token')) - // 注册相关事件回调处理函数 - xhr.onload = function (e) { - if (this.status == 200 || this.status == 304) { - // alert(this.responseText) - resolve(JSON.parse(this.responseText)) + params['match[]'] = b.body.get('match[]') + params.start = b.body.get('start') + params.end = b.body.get('end') + a += '?match[]=' + b.body.get('match[]') + return fetch(a, { + ...b, + // body: JSON.stringify(params), + redirect: 'follow', + headers: { + Authorization: localStorage.getItem('nz-token'), + 'content-type': 'application/x-www-form-urlencoded' } + }) + } + return fetch(a, { + ...b, + headers: { + Authorization: localStorage.getItem('nz-token') } - xhr.onerror = function (e) { console.log(e) } - // 发送数据 - xhr.send() }) }, closeDropdown () { @@ -792,7 +795,7 @@ export default { this.cascaderValue = '' }, metricChangeNew (value) { - console.log(value); + // console.log(value) if (!value) return this.insertText(value) this.dropDownVisible = false @@ -1063,7 +1066,6 @@ export default { // elInput.selectionEnd = startPos + insertTxt.length this.expressionList[this.index] = insertTxt this.codeMirrorValue[this.index] = insertTxt - console.log('inserttext', this.codeMirrorValue[this.index]) this.initCodeMirror() } /* setMsg:function(){ @@ -1088,16 +1090,15 @@ export default { } } }, - expressionList:{ + expressionList: { deep: true, immediate: true, handler (n, o) { - console.log(n,n[this.index]); - this.codeMirrorValue[this.index] = n[this.index]; - + // console.log(n, n[this.index]) + this.codeMirrorValue[this.index] = n[this.index] } }, - + // codeMirrorValue:{ // deep:true, // imediate:true, @@ -1107,6 +1108,17 @@ export default { // } // } // } + type: { + deep: true, + immediate: true, + handler (n) { + if (n !== 'log') { + this.$nextTick(() => { + this.initCodeMirror() + }) + } + } + } } } diff --git a/nezha-fronted/src/components/page/dashboard/panel.vue b/nezha-fronted/src/components/page/dashboard/panel.vue index d74732223..cc993fff4 100644 --- a/nezha-fronted/src/components/page/dashboard/panel.vue +++ b/nezha-fronted/src/components/page/dashboard/panel.vue @@ -40,7 +40,7 @@ - +