diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/alertMessageTabNew.vue b/nezha-fronted/src/components/common/bottomBox/tabs/alertMessageTabNew.vue index 786f9f1ba..1fa23aa89 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/alertMessageTabNew.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/alertMessageTabNew.vue @@ -343,7 +343,7 @@ export default { item.labels = JSON.parse(item.labels) if (!this.isBuildIn(item.alertRule)) { const paramStr = JSON.stringify(this.promQueryParamConvert(item)) - axiosAll.push(axios.get('/prom/api/v1/query?query=' + paramStr.substring(1, paramStr.length - 1).replace(/\+/g, '%2B').replace(/ /g, '%20').replace(/\\/g, ''))) + axiosAll.push(axios.get('/prom/api/v1/query?query=' + paramStr.substring(1, paramStr.length - 1))) } else { axiosAll.push('') } diff --git a/nezha-fronted/src/components/common/labelFilter/clickSearch.vue b/nezha-fronted/src/components/common/labelFilter/clickSearch.vue index fe88bf3ab..4d6b8329f 100644 --- a/nezha-fronted/src/components/common/labelFilter/clickSearch.vue +++ b/nezha-fronted/src/components/common/labelFilter/clickSearch.vue @@ -1,25 +1,30 @@ @@ -63,6 +68,23 @@ export default { } }, computed: { + moreBtnTop () { + return function (type) { + let top + switch (type) { + case 'checkBox': { + top = 4 + break + } + case 'dropdownCheckBox': { + top = 8 + break + } + default: break + } + return top + } + }, height () { const paddingHeight = 30 const checkBoxRowHeight = 31 @@ -84,10 +106,13 @@ export default { immediate: true, deep: true, handler (n) { - this.titleSearchListCopy = JSON.parse(JSON.stringify(n)) - this.$nextTick(() => { - this.needMore() - }) + if (n.ready) { + this.titleSearchListCopy = JSON.parse(JSON.stringify(n)) + this.$nextTick(() => { + this.setEachCascWidth() + this.needMore() + }) + } } }, selectValue: { @@ -109,16 +134,59 @@ export default { return { selectValueOut: {}, contentWidth: 0, // 搜索框内部区域的宽度 - titleSearchListCopy: {} + titleSearchListCopy: {}, + widthConstant: { + checkBox: { + boxMargin: 30, + + checkBox: 14, + tagPadding: 10, + tagBlankTotal: 24 // 以上2个空白占位的总和 + }, + dropdownCheckBox: { + boxMargin: 21, + labelPadding: 6, + + tagMaxWidth: 150, // 定义tag标签最大宽度 + // 先分解cascader输入框的结构,如下: + tagMargin: 6, + tagPadding: 10, + tagBorder: 2, + tagRemoveIcon: 11, + tagBlank: 2, + tagBlankTotal: 31, // 以上五个空白占位的总和 + textMaxWidth: 119, // 纯文本最大宽度,通过tag最大宽度减去total得到 + + inputOriginalWidth: 60, // 输入框初始宽度 + moreNumberWidth: 42, // 选中选项时右侧的+1、+2...数字提示内容的宽度 + arrowDownWidth: 30 // 输入框右端箭头区域的宽度 + } + } } }, mounted () { window.addEventListener('resize', this.needMore) }, methods: { - casChange (type, key) { + /* value: 选择器返回的值 */ + casChange (value, type, item, key) { this.$nextTick(() => { - const cascs = this.$refs[`${type}_cascader`] + // 计算change后新宽度 + const oldInputWidth = item.inputWidth + this.setEachCascWidth(value, type, item) + /* 为实现动态宽度而改变输入框宽度,因为cascader组件的宽度是由它决定的 */ + if (item.inputWidth !== oldInputWidth) { + this.$refs[`${type}_${item.id}_cascader`][0].$el.querySelector('.el-input__inner').style.width = `${item.inputWidth}px` + this.$nextTick(() => { + this.needMore(type, item) + }) + } + + /* 组织参数 */ + const cascs = [] + this.titleSearchListCopy[type].children.forEach(c => { + cascs.push(this.$refs[`${type}_${c.id}_cascader`][0]) + }) if (type === 'assetLabel') { // label特殊处理,组织成{“id”:[“张三”,"lw"],"id":["李四"]} const values = {} cascs.forEach(c => { @@ -145,55 +213,94 @@ export default { this.selectValueOut.change++ }) }, + computeCascWidth (textWidth, labelWidth) { // label + tag + margin + const tagWidth = textWidth > this.widthConstant.dropdownCheckBox.textMaxWidth ? this.widthConstant.dropdownCheckBox.textMaxWidth : textWidth + this.widthConstant.dropdownCheckBox.tagBlankTotal // 限制原始文字宽度不超过最大值,得到实际tag宽度 + const inputWidth = tagWidth + this.widthConstant.dropdownCheckBox.moreNumberWidth + this.widthConstant.dropdownCheckBox.arrowDownWidth + return { tagWidth, inputWidth, width: labelWidth + inputWidth + this.widthConstant.dropdownCheckBox.boxMargin } + }, + setEachCascWidth (value, type, item) { + if (type) { + if (value.length === 0) { // 回到初始宽度 + item.width = item.originalWidth + item.inputWidth = this.widthConstant.dropdownCheckBox.inputOriginalWidth + } else { + const showTag = item.children.find(c => c.id === value[0][0]) // 展示的tag + const { tagWidth, inputWidth, width } = this.computeCascWidth(this.computeDistance(showTag.name, 12), item.labelWidth) + item.width = width + item.inputWidth = inputWidth + } + } else { // 初始 + Object.keys(this.titleSearchListCopy).forEach(type => { + if (type !== 'ready') { + this.titleSearchListCopy[type].children.forEach(c => { + if (this.titleSearchListCopy[type].type === 'dropdownCheckBox') { + const labelWidth = this.computeDistance(c.name + ':') + this.widthConstant.dropdownCheckBox.labelPadding // cascader-label总宽度 + const width = labelWidth + this.widthConstant.dropdownCheckBox.inputOriginalWidth + this.widthConstant.dropdownCheckBox.boxMargin + this.$set(c, 'width', width) // 总宽 + this.$set(c, 'originalWidth', width) // 初始总宽 + this.$set(c, 'labelWidth', labelWidth) // label区域宽 + this.$set(c, 'inputWidth', this.widthConstant.dropdownCheckBox.inputOriginalWidth) // 内容区域宽 + } else if (this.titleSearchListCopy[type].type === 'checkBox') { + const width = this.computeDistance(c.name) + this.widthConstant.checkBox.tagBlankTotal + this.widthConstant.checkBox.boxMargin + this.$set(c, 'width', width) // 总宽 + } + }) + } + }) + } + }, casFocus (item, isFocus, e) { this.$set(item, 'isFocus', isFocus) }, - needMore (key) { - // setTimeout(() => { - this.$nextTick(() => { - this.contentWidth = this.$refs.searchContentBox[0].offsetWidth - 210 - - Object.keys(this.titleSearchListCopy).forEach(key => { - this.titleSearchListCopy[key].width = 0 - this.titleSearchListCopy[key].showMore = false - let index = -1 - this.titleSearchListCopy[key].children.forEach((item, i) => { - /* (基础宽度 + 文字宽度) 总和大于文本长时 显示更多 */ - if (index === -1) { - this.titleSearchListCopy[key].width += this.getDomWidth(this.titleSearchListCopy[key], item, i) - if (this.titleSearchListCopy[key].width > this.contentWidth) { - this.titleSearchListCopy[key].showMore = true - this.titleSearchListCopy[key].index = i - index = i - } + needMore (type, item) { + const contentWidth = this.$refs.searchContentBox[0].offsetWidth - 210 + // 窗口尺寸没改变,则只重排当前type + if (type && contentWidth === this.contentWidth) { + this.titleSearchListCopy[type].width = 0 + let showMore = false + this.titleSearchListCopy[type].children.forEach((item, i) => { + if (!showMore) { + this.titleSearchListCopy[type].width += item.width + if (this.titleSearchListCopy[type].width > this.contentWidth) { + showMore = true + this.titleSearchListCopy[type].index = i } - }) + } }) - }) + if (!showMore) { + this.titleSearchListCopy[type].index = this.titleSearchListCopy[type].children.length - 1 + } + } else { // 全体重排 + this.contentWidth = contentWidth + Object.keys(this.titleSearchListCopy).forEach(type => { + if (type !== 'ready') { + this.titleSearchListCopy[type].width = 0 + this.titleSearchListCopy[type].showMore = false + let showMore = false + this.titleSearchListCopy[type].children.forEach((item, i) => { + if (!showMore) { + this.titleSearchListCopy[type].width += item.width + if (this.titleSearchListCopy[type].width > this.contentWidth) { + showMore = true + this.titleSearchListCopy[type].index = i + } + } + }) + if (!showMore) { + this.titleSearchListCopy[type].index = this.titleSearchListCopy[type].children.length - 1 + } + } + }) + } }, - computeDistance (str) { + computeDistance (str, fontSize) { let width = 0 - const html = document.querySelector('.temp-dom') + const c = fontSize ? '.temp-dom--' + fontSize : '.temp-dom' + const html = document.querySelector(c) html.innerText = str width = html.offsetWidth return width }, - getDomWidth (parentData, item, index) { - let width - if (parentData.type === 'dropdownCheckBox') { - width = this.computeDistance(`${item.name}:`) - const marginRight = 22 - width = width + 182 + marginRight// 182是label框的宽度除去name外的部分 - } else { - width = this.computeDistance(item.name) - width = width > 150 ? 150 : width - const paddingLeft = 10 - const checkBox = 14 - const marginRight = 30 - width = width + paddingLeft + checkBox + marginRight - } - return width - }, changShowMore (key) { this.titleSearchListCopy[key].showMore = !this.titleSearchListCopy[key].showMore } @@ -204,7 +311,19 @@ export default { } - diff --git a/nezha-fronted/src/components/layout/home.vue b/nezha-fronted/src/components/layout/home.vue index 3debc86d4..1c1bcb2e8 100644 --- a/nezha-fronted/src/components/layout/home.vue +++ b/nezha-fronted/src/components/layout/home.vue @@ -11,6 +11,7 @@ + @@ -62,4 +63,9 @@ export default { font-size: 14px; position: fixed; } +.temp-dom--12 { + visibility: hidden; + font-size: 12px; + position: fixed; +} diff --git a/nezha-fronted/src/components/page/alert/alertMessage.vue b/nezha-fronted/src/components/page/alert/alertMessage.vue index f45798934..c6f3e7aaf 100644 --- a/nezha-fronted/src/components/page/alert/alertMessage.vue +++ b/nezha-fronted/src/components/page/alert/alertMessage.vue @@ -409,6 +409,7 @@ export default { } this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo) this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize) + this.$set(this.searchLabel, 'state', this.state) if (this.searchTime && this.searchTime.length > 1) { this.$set(this.searchLabel, 'startAt', this.timezoneToUtcTimeStr(this.searchTime[0])) this.$set(this.searchLabel, 'endAt', this.timezoneToUtcTimeStr(this.searchTime[1])) @@ -421,7 +422,7 @@ export default { delete this.searchLabel.startAt delete this.searchLabel.endAt } - this.$get(this.url + '?state=' + this.state, this.searchLabel).then(response => { + this.$get(this.url, this.searchLabel).then(response => { this.tools.loading = false if (response.code == 200) { this.nowTime = this.utcTimeToTimezoneStr(response.time) diff --git a/nezha-fronted/src/components/page/asset/asset.vue b/nezha-fronted/src/components/page/asset/asset.vue index 796b515d1..a5ebfc44e 100644 --- a/nezha-fronted/src/components/page/asset/asset.vue +++ b/nezha-fronted/src/components/page/asset/asset.vue @@ -208,6 +208,7 @@ export default { snmpCredentialData: [], fieldGroupData: [], titleSearchList: { + ready: false, dc: { label: this.$t('overall.dc'), key: 'dcIds', @@ -216,7 +217,7 @@ export default { show: true, showMore: false, width: 0, - index: 0 + index: -1 }, type: { label: this.$t('overall.type'), @@ -226,7 +227,7 @@ export default { show: true, showMore: false, width: 0, - index: 0 + index: -1 }, ping: { label: 'ping', @@ -239,7 +240,7 @@ export default { show: true, showMore: false, width: 0, - index: 0 + index: -1 }, model: { label: this.$t('asset.model'), @@ -249,7 +250,7 @@ export default { show: true, showMore: false, width: 0, - index: 0 + index: -1 }, assetLabel: { label: 'More', @@ -259,7 +260,7 @@ export default { show: true, showMore: false, width: 0, - index: 0 + index: -1 } }, selectValue: { @@ -298,7 +299,8 @@ export default { return new Promise(resolve => { this.$get('asset/typeConf?pageSize=-1').then(response => { if (response.code === 200) { - this.titleSearchList.type.children = response.data.list.map(d => { return { ...d, value: d.id } }) + resolve(response.data.list.map(d => { return { ...d, value: d.id } })) + // this.titleSearchList.type.children = response.data.list.map(d => { return { ...d, value: d.id } }) } resolve() }) @@ -329,7 +331,8 @@ export default { this.$get('dc', { pageSize: -1 }).then(response => { if (response.code === 200) { this.dcData = response.data.list - this.titleSearchList.dc.children = response.data.list.map(d => { return { ...d, value: d.id } }) + resolve(response.data.list.map(d => { return { ...d, value: d.id } })) + // this.titleSearchList.dc.children = response.data.list.map(d => { return { ...d, value: d.id } }) } resolve() }) @@ -372,7 +375,8 @@ export default { } } }) - this.titleSearchList.assetLabel.children = data + // this.titleSearchList.assetLabel.children = data + resolve(data) setTimeout(() => { const title = this.tools.customTableTitle const originalTitle = title.slice(0, this.$refs.dataTable.tableTitle.length) // 原title @@ -404,7 +408,8 @@ export default { titleSearchData[m.brand.name] = { ...m.brand, children: [m] } } }) - this.titleSearchList.model.children = Object.keys(titleSearchData).map(b => titleSearchData[b]) + resolve(Object.keys(titleSearchData).map(b => titleSearchData[b])) + // this.titleSearchList.model.children = Object.keys(titleSearchData).map(b => titleSearchData[b]) } resolve() }) @@ -440,12 +445,15 @@ export default { }, mounted () { // 初始化数据 - this.getModelData() + Promise.all([this.getModelData(), this.getTypeData(), this.getDcData(), this.getSearchableMetaData()]).then(res => { + this.titleSearchList.model.children = res[0] + this.titleSearchList.type.children = res[1] + this.titleSearchList.dc.children = res[2] + this.titleSearchList.assetLabel.children = res[3] + this.titleSearchList.ready = true + }) this.getStateData() this.getTypeTreeData() - this.getTypeData() - this.getDcData() - this.getSearchableMetaData() this.getSnmpCredentialData() this.getFieldGroupData() }, diff --git a/nezha-fronted/src/components/page/monitor/endpoint/endpointList.vue b/nezha-fronted/src/components/page/monitor/endpoint/endpointList.vue index 00a3f092e..abc988a82 100644 --- a/nezha-fronted/src/components/page/monitor/endpoint/endpointList.vue +++ b/nezha-fronted/src/components/page/monitor/endpoint/endpointList.vue @@ -42,7 +42,7 @@