NEZ-1820 fix:修复dashboard内存泄漏
This commit is contained in:
@@ -24,6 +24,11 @@ For a detailed explanation on how things work, check out the [guide](http://vuej
|
||||
|
||||
需要配置 config.json 为 {"baseUrl":"http://192.168.40.42:8080/", "version": "21.04"}
|
||||
|
||||
#自动化测试
|
||||
npm run unit
|
||||
根目录下 /test/jest.conf.js collectCoverageFrom 变量配置需要测试报告的文件 (因为暂时不测所有 只能一个个引入)
|
||||
specs 配置对应的测试用例 (https://docs.geedge.net/pages/viewpage.action?pageId=58310079 参考匹配器)
|
||||
|
||||
#思维导图
|
||||
https://docs.geedge.net/pages/viewpage.action?pageId=67209306
|
||||
|
||||
|
||||
276
nezha-fronted/package-lock.json
generated
276
nezha-fronted/package-lock.json
generated
@@ -517,6 +517,231 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@codemirror/autocomplete": {
|
||||
"version": "0.19.15",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.15.tgz",
|
||||
"integrity": "sha512-GQWzvvuXxNUyaEk+5gawbAD8s51/v2Chb++nx0e2eGWrphWk42isBtzOMdc3DxrxrZtPZ55q2ldNp+6G8KJLIQ==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.4",
|
||||
"@codemirror/text": "^0.19.2",
|
||||
"@codemirror/tooltip": "^0.19.12",
|
||||
"@codemirror/view": "^0.19.0",
|
||||
"@lezer/common": "^0.15.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/basic-setup": {
|
||||
"version": "0.19.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/basic-setup/-/basic-setup-0.19.3.tgz",
|
||||
"integrity": "sha512-2hfO+QDk/HTpQzeYk1NyL1G9D5L7Sj78dtaQP8xBU42DKU9+OBPF5MdjLYnxP0jKzm6IfQfsLd89fnqW3rBVfQ==",
|
||||
"requires": {
|
||||
"@codemirror/autocomplete": "^0.19.0",
|
||||
"@codemirror/closebrackets": "^0.19.0",
|
||||
"@codemirror/commands": "^0.19.0",
|
||||
"@codemirror/comment": "^0.19.0",
|
||||
"@codemirror/fold": "^0.19.0",
|
||||
"@codemirror/gutter": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.0",
|
||||
"@codemirror/history": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/lint": "^0.19.0",
|
||||
"@codemirror/matchbrackets": "^0.19.0",
|
||||
"@codemirror/rectangular-selection": "^0.19.2",
|
||||
"@codemirror/search": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.31"
|
||||
}
|
||||
},
|
||||
"@codemirror/closebrackets": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/closebrackets/-/closebrackets-0.19.2.tgz",
|
||||
"integrity": "sha512-ClMPzPcPP0eQiDcVjtVPl6OLxgdtZSYDazsvT0AKl70V1OJva0eHgl4/6kCW3RZ0pb2n34i9nJz4eXCmK+TYDA==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.2",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.44"
|
||||
}
|
||||
},
|
||||
"@codemirror/commands": {
|
||||
"version": "0.19.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.8.tgz",
|
||||
"integrity": "sha512-65LIMSGUGGpY3oH6mzV46YWRrgao6NmfJ+AuC7jNz3K5NPnH6GCV1H5I6SwOFyVbkiygGyd0EFwrWqywTBD1aw==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/matchbrackets": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.2",
|
||||
"@codemirror/text": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.22",
|
||||
"@lezer/common": "^0.15.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/comment": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/comment/-/comment-0.19.1.tgz",
|
||||
"integrity": "sha512-uGKteBuVWAC6fW+Yt8u27DOnXMT/xV4Ekk2Z5mRsiADCZDqYvryrJd6PLL5+8t64BVyocwQwNfz1UswYS2CtFQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.9",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/fold": {
|
||||
"version": "0.19.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/fold/-/fold-0.19.4.tgz",
|
||||
"integrity": "sha512-0SNSkRSOa6gymD6GauHa3sxiysjPhUC0SRVyTlvL52o0gz9GHdc8kNqNQskm3fBtGGOiSriGwF/kAsajRiGhVw==",
|
||||
"requires": {
|
||||
"@codemirror/gutter": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.22"
|
||||
}
|
||||
},
|
||||
"@codemirror/gutter": {
|
||||
"version": "0.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/gutter/-/gutter-0.19.9.tgz",
|
||||
"integrity": "sha512-PFrtmilahin1g6uL27aG5tM/rqR9DZzZYZsIrCXA5Uc2OFTFqx4owuhoU9hqfYxHp5ovfvBwQ+txFzqS4vog6Q==",
|
||||
"requires": {
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.23"
|
||||
}
|
||||
},
|
||||
"@codemirror/highlight": {
|
||||
"version": "0.19.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.19.8.tgz",
|
||||
"integrity": "sha512-v/lzuHjrYR8MN2mEJcUD6fHSTXXli9C1XGYpr+ElV6fLBIUhMTNKR3qThp611xuWfXfwDxeL7ppcbkM/MzPV3A==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.3",
|
||||
"@codemirror/view": "^0.19.39",
|
||||
"@lezer/common": "^0.15.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/history": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/history/-/history-0.19.2.tgz",
|
||||
"integrity": "sha512-unhP4t3N2smzmHoo/Yio6ueWi+il8gm9VKrvi6wlcdGH5fOfVDNkmjHQ495SiR+EdOG35+3iNebSPYww0vN7ow==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.2",
|
||||
"@codemirror/view": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/language": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.10.tgz",
|
||||
"integrity": "sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.0",
|
||||
"@lezer/common": "^0.15.5",
|
||||
"@lezer/lr": "^0.15.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/lint": {
|
||||
"version": "0.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-0.19.6.tgz",
|
||||
"integrity": "sha512-Pbw1Y5kHVs2J+itQ0uez3dI4qY9ApYVap7eNfV81x1/3/BXgBkKfadaw0gqJ4h4FDG7OnJwb0VbPsjJQllHjaA==",
|
||||
"requires": {
|
||||
"@codemirror/gutter": "^0.19.4",
|
||||
"@codemirror/panel": "^0.19.0",
|
||||
"@codemirror/rangeset": "^0.19.1",
|
||||
"@codemirror/state": "^0.19.4",
|
||||
"@codemirror/tooltip": "^0.19.16",
|
||||
"@codemirror/view": "^0.19.22",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"@codemirror/matchbrackets": {
|
||||
"version": "0.19.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/matchbrackets/-/matchbrackets-0.19.4.tgz",
|
||||
"integrity": "sha512-VFkaOKPNudAA5sGP1zikRHCEKU0hjYmkKpr04pybUpQvfTvNJXlReCyP0rvH/1iEwAGPL990ZTT+QrLdu4MeEA==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.0",
|
||||
"@lezer/common": "^0.15.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/panel": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/panel/-/panel-0.19.1.tgz",
|
||||
"integrity": "sha512-sYeOCMA3KRYxZYJYn5PNlt9yNsjy3zTNTrbYSfVgjgL9QomIVgOJWPO5hZ2sTN8lufO6lw0vTBsIPL9MSidmBg==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/rangeset": {
|
||||
"version": "0.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.9.tgz",
|
||||
"integrity": "sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/rectangular-selection": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/rectangular-selection/-/rectangular-selection-0.19.2.tgz",
|
||||
"integrity": "sha512-AXK/p5eGwFJ9GJcLfntqN4dgY+XiIF7eHfXNQJX5HhQLSped2wJE6WuC1rMEaOlcpOqlb9mrNi/ZdUjSIj9mbA==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/text": "^0.19.4",
|
||||
"@codemirror/view": "^0.19.48"
|
||||
}
|
||||
},
|
||||
"@codemirror/search": {
|
||||
"version": "0.19.10",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-0.19.10.tgz",
|
||||
"integrity": "sha512-qjubm69HJixPBWzI6HeEghTWOOD8NXiHOTRNvdizqs8xWRuFChq9zkjD3XiAJ7GXSTzCuQJnAP9DBBGCLq4ZIA==",
|
||||
"requires": {
|
||||
"@codemirror/panel": "^0.19.0",
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.3",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.34",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"@codemirror/state": {
|
||||
"version": "0.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz",
|
||||
"integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==",
|
||||
"requires": {
|
||||
"@codemirror/text": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/text": {
|
||||
"version": "0.19.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz",
|
||||
"integrity": "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA=="
|
||||
},
|
||||
"@codemirror/tooltip": {
|
||||
"version": "0.19.16",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/tooltip/-/tooltip-0.19.16.tgz",
|
||||
"integrity": "sha512-zxKDHryUV5/RS45AQL+wOeN+i7/l81wK56OMnUPoTSzCWNITfxHn7BToDsjtrRKbzHqUxKYmBnn/4hPjpZ4WJQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/view": "^0.19.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/view": {
|
||||
"version": "0.19.48",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.48.tgz",
|
||||
"integrity": "sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==",
|
||||
"requires": {
|
||||
"@codemirror/rangeset": "^0.19.5",
|
||||
"@codemirror/state": "^0.19.3",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
"style-mod": "^4.0.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
|
||||
@@ -1161,6 +1386,19 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"@lezer/common": {
|
||||
"version": "0.15.12",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz",
|
||||
"integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig=="
|
||||
},
|
||||
"@lezer/lr": {
|
||||
"version": "0.15.8",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz",
|
||||
"integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==",
|
||||
"requires": {
|
||||
"@lezer/common": "^0.15.0"
|
||||
}
|
||||
},
|
||||
"@riophae/vue-treeselect": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@riophae/vue-treeselect/-/vue-treeselect-0.4.0.tgz",
|
||||
@@ -3820,6 +4058,29 @@
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"codemirror-promql": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/codemirror-promql/-/codemirror-promql-0.19.0.tgz",
|
||||
"integrity": "sha512-SUomAfs8S2+UihtCYMEG7e+5DYCDJTJiTOJjqSXSAylHacgyx5z/V20vA4KA7uSe+KHgKXxjM6R9ZOfkz4SJPg==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"codepage": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
|
||||
@@ -4429,6 +4690,11 @@
|
||||
"sha.js": "^2.4.8"
|
||||
}
|
||||
},
|
||||
"crelt": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
|
||||
"integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
@@ -16907,6 +17173,11 @@
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||
"dev": true
|
||||
},
|
||||
"style-mod": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
|
||||
},
|
||||
"stylehacks": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
|
||||
@@ -18394,6 +18665,11 @@
|
||||
"browser-process-hrtime": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"w3c-keyname": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
|
||||
"integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw=="
|
||||
},
|
||||
"walker": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
"unit": "jest --config test/unit/jest.conf.js --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.15",
|
||||
"@codemirror/basic-setup": "^0.19.3",
|
||||
"@codemirror/highlight": "^0.19.8",
|
||||
"@codemirror/language": "^0.19.10",
|
||||
"@codemirror/lint": "^0.19.6",
|
||||
"@codemirror/state": "^0.19.9",
|
||||
"@codemirror/view": "^0.19.48",
|
||||
"@johmun/vue-tags-input": "^2.1.0",
|
||||
"@riophae/vue-treeselect": "^0.4.0",
|
||||
"@svgdotjs/svg.js": "^3.0.16",
|
||||
@@ -24,6 +31,7 @@
|
||||
"@topology/layout": "^0.3.0",
|
||||
"@topology/sequence-diagram": "^0.3.0",
|
||||
"axios": "^0.19.0",
|
||||
"codemirror-promql": "^0.19.0",
|
||||
"cytoscape": "^3.15.2",
|
||||
"d3": "^6.7.0",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
|
||||
@@ -425,10 +425,10 @@
|
||||
}
|
||||
.chart-stat{
|
||||
width: 100%;
|
||||
height: calc(100% - 20px);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 5px;
|
||||
padding: 2px;
|
||||
box-sizing: border-box;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
@@ -441,7 +441,7 @@
|
||||
word-break: break-all;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
padding: 2px;
|
||||
//padding: 2px;
|
||||
overflow: hidden;
|
||||
color: $--color-text-regular;
|
||||
flex-grow: 1
|
||||
|
||||
@@ -1,38 +1,80 @@
|
||||
.chart-fullscreen.nz-dialog .panel-chart--fullscreen{
|
||||
.alert-message-info-header{
|
||||
border-bottom: 1px solid rgba(0,0,0,0.09);;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.alert-message-info-box{
|
||||
box-sizing: border-box;
|
||||
.chart-fullscreen.nz-dialog .panel-chart--fullscreen {
|
||||
.alert-message-info-header {
|
||||
height: 72px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.09);
|
||||
padding: 20px;
|
||||
margin-top: 0;
|
||||
|
||||
.chart-header__title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
font-family: PingFangSC-Medium;
|
||||
|
||||
.alert-message-state {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
margin-right: 15px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
color: $--color-text-label;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.alert-message-info-box {
|
||||
box-sizing: border-box;
|
||||
padding: 20px 20px 33px 30px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
.info-box-left{
|
||||
|
||||
.info-box-left {
|
||||
width: 66%;
|
||||
min-width: 500px;
|
||||
min-height: 600px;
|
||||
margin-right: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.nz-chart {
|
||||
height: 36%;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid $--border-color-light;
|
||||
flex: none;
|
||||
}
|
||||
.alert-message-info-tab{
|
||||
|
||||
.alert-message-info-tab {
|
||||
height: 63%;
|
||||
flex: 1;
|
||||
|
||||
.alert-label-header-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.alert-rule-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-rule-value {
|
||||
padding-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-tabs.el-tabs--card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.el-tabs__header{
|
||||
|
||||
.el-tabs__header {
|
||||
margin: 0;
|
||||
.el-tabs__item{
|
||||
|
||||
.el-tabs__item {
|
||||
border: 1px solid $--border-color-light;
|
||||
border-radius: 2px;
|
||||
//border-bottom: none;
|
||||
@@ -40,19 +82,22 @@
|
||||
background: $--background-color-base;
|
||||
color: $--color-text-regular;
|
||||
}
|
||||
.el-tabs__item:hover{
|
||||
|
||||
.el-tabs__item:hover {
|
||||
color: $--color-warning;
|
||||
background: $--background-color-empty;
|
||||
border-bottom-color: $--background-color-empty;
|
||||
}
|
||||
.el-tabs__item.is-active{
|
||||
|
||||
.el-tabs__item.is-active {
|
||||
color: $--color-warning;
|
||||
background: $--background-color-empty;
|
||||
border-bottom-color: $--background-color-empty;
|
||||
}
|
||||
}
|
||||
.el-tabs__content{
|
||||
padding: 20px;
|
||||
|
||||
.el-tabs__content {
|
||||
padding: 25px 30px;
|
||||
flex: 1;
|
||||
border: 1px solid $--border-color-light;
|
||||
border-top: none;
|
||||
@@ -61,72 +106,118 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.info-box-right{
|
||||
|
||||
.info-box-right {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border: 1px solid #E7EAED;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
padding: 0px 20px 20px 0;
|
||||
|
||||
.table-no-data {
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
.time-line-header{
|
||||
padding: 20px;
|
||||
|
||||
.time-line-header {
|
||||
padding: 20px 20px 35px 20px;
|
||||
font-size: 16px;
|
||||
color: $--color-text-primary;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.scope-icon-box {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
.scope-box {
|
||||
cursor: pointer;
|
||||
color: $--background-color-disabled;
|
||||
|
||||
.nz-icon {
|
||||
margin-right: 5px;
|
||||
color: $--background-color-disabled ;
|
||||
margin-right: 20px;
|
||||
color: $--background-color-disabled;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
.scope-box.is-select{
|
||||
|
||||
.scope-box.is-select {
|
||||
color: $--color-monitor;
|
||||
|
||||
.nz-icon {
|
||||
color: $--color-monitor;
|
||||
}
|
||||
}
|
||||
#time-line-scope{
|
||||
|
||||
#time-line-scope {
|
||||
//float: right;
|
||||
}
|
||||
}
|
||||
.el-timeline{
|
||||
|
||||
.el-timeline {
|
||||
height: calc(100% - 80px);
|
||||
overflow-y: auto;
|
||||
padding-top: 14px;
|
||||
padding-left: 40px;
|
||||
box-sizing: border-box;
|
||||
.el-timeline-item{
|
||||
padding-bottom: 24px;
|
||||
|
||||
.el-timeline-item {
|
||||
padding-bottom: 20px;
|
||||
|
||||
.el-timeline-item__wrapper {
|
||||
.el-timeline-item__timestamp.is-top {
|
||||
top: -50px;
|
||||
}
|
||||
|
||||
.el-timeline-item__content {
|
||||
.nz-alert-tag.nz-alert-tag_info {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nz-alert-tag_info {
|
||||
.nz-alert-tag__label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.nz-alert-tag__content {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.has-time{
|
||||
|
||||
.has-time {
|
||||
padding-top: 36px;
|
||||
.el-timeline-item__tail{
|
||||
|
||||
.el-timeline-item__tail {
|
||||
height: calc(100% + 14px);
|
||||
top: -14px;
|
||||
}
|
||||
}
|
||||
.el-timeline-item.last .el-timeline-item__tail{
|
||||
|
||||
.el-timeline-item.last .el-timeline-item__tail {
|
||||
display: block;
|
||||
top: -100%;
|
||||
}
|
||||
.el-timeline-item:last-child .el-timeline-item__tail.only{
|
||||
|
||||
.el-timeline-item:last-child .el-timeline-item__tail.only {
|
||||
display: block;
|
||||
top: -100%;
|
||||
}
|
||||
.el-timeline-item__timestamp.is-top{
|
||||
|
||||
.el-timeline-item__timestamp.is-top {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: -20px;
|
||||
@@ -137,21 +228,25 @@
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.el-timeline-item__node {
|
||||
z-index: 1;
|
||||
}
|
||||
.time-line-item-header{
|
||||
|
||||
.time-line-item-header {
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
.load-more-box{
|
||||
|
||||
.load-more-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-no-data {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -160,20 +255,24 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.el-tabs__nav{
|
||||
|
||||
.el-tabs__nav {
|
||||
border: none;
|
||||
}
|
||||
.info-box-header{
|
||||
|
||||
.info-box-header {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.info-box-title{
|
||||
|
||||
.info-box-title {
|
||||
font-size: 16px;
|
||||
color: $--color-text-primary;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.info-box-content{
|
||||
|
||||
.info-box-content {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
font-weight: 400;
|
||||
@@ -183,3 +282,223 @@
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
.alert-message-info-box {
|
||||
.info-box-right {
|
||||
.el-timeline {
|
||||
.el-timeline-item {
|
||||
.el-timeline-item__wrapper {
|
||||
.el-timeline-item__content {
|
||||
.alert-message-summary {
|
||||
margin: 10px 0 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.alert-message-startAt {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 400;
|
||||
margin: 3px 0 5px;
|
||||
padding-left: 5px;
|
||||
|
||||
span:nth-of-type(n) {
|
||||
color: #999999;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
span:nth-of-type(2n) {
|
||||
color: #666666;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.margin-b-10 {
|
||||
.alert-message-state.gray-bg {
|
||||
margin-right: 5px;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-message-labels {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.nz-alert-tag.nz-alert-tag_normal {
|
||||
display: inline-block;
|
||||
margin-right: 10px !important;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.nz-alert-tag__label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nz-alert-tag__content {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.nz-alert-tag.nz-alert-tag_info {
|
||||
display: inline-block;
|
||||
margin-right: 10px !important;
|
||||
|
||||
.nz-alert-tag__label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.nz-alert-tag__content {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-box-left {
|
||||
.alert-message-info-tab {
|
||||
.el-tabs.el-tabs--card.el-tabs--top {
|
||||
.el-tabs__content {
|
||||
#pane-detail {
|
||||
.info-box-header {
|
||||
.info-box-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.nz-alert-tag.nz-alert-tag_normal {
|
||||
display: inline-block;
|
||||
margin-right: 20px !important;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.nz-alert-tag__label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nz-alert-tag__content {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.nz-alert-tag.nz-alert-tag_info {
|
||||
display: inline-block;
|
||||
margin-right: 20px !important;
|
||||
|
||||
.nz-alert-tag__label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.nz-alert-tag__content {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-dc {
|
||||
.alert-label-info {
|
||||
.alert-label-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-label-title {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-asset {
|
||||
.alert-label-info {
|
||||
.alert-label-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-label-title {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-endpoint {
|
||||
.alert-label-info {
|
||||
.alert-label-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-label-title {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-module {
|
||||
.alert-label-info {
|
||||
.alert-label-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-label-title {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-project {
|
||||
.alert-label-info {
|
||||
.alert-label-box {
|
||||
margin-bottom: 25px;
|
||||
|
||||
.alert-label-title {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pane-trbShot {
|
||||
.editor-core.ql-container.ql-snow {
|
||||
background-color: #23241E;
|
||||
border-radius: 2px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
#editor{
|
||||
width: 100%;
|
||||
}
|
||||
.no-resize{
|
||||
background: rgba(255,255,255,0);
|
||||
.el-textarea__inner {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
|
||||
<template>
|
||||
<div :style="showHeader&&chartInfo.param.showHeader ? '' : 'padding-top: 15px;'" class="nz-chart" :class="showHeader&&chartInfo.param.showHeader ? '' : 'no-header'" >
|
||||
<loading :loading="loading"></loading>
|
||||
<chart-no-data v-if="isNoData || isError || chartChildrenData"></chart-no-data>
|
||||
<template v-else>
|
||||
<!-- <chart-time-series
|
||||
<chart-time-series
|
||||
v-if="isTimeSeries(chartInfo.type)"
|
||||
:ref="'chart' + chartInfo.id"
|
||||
:chart-data="chartData"
|
||||
@@ -105,7 +106,7 @@
|
||||
:is-fullscreen="isFullscreen"
|
||||
@chartIsNoData="chartIsNoData"
|
||||
:chart-option="chartOption"
|
||||
></chart-diagram> -->
|
||||
></chart-diagram>
|
||||
<chartAutotopology
|
||||
:ref="'chart' + chartInfo.id"
|
||||
v-if="isAutotopology(chartInfo.type)"
|
||||
@@ -115,7 +116,7 @@
|
||||
:is-fullscreen="isFullscreen"
|
||||
@chartIsNoData="chartIsNoData"
|
||||
></chartAutotopology>
|
||||
<!-- <chartMap
|
||||
<chartMap
|
||||
:ref="'chart' + chartInfo.id"
|
||||
v-if="isMap(chartInfo.type)"
|
||||
:chart-data="chartData"
|
||||
@@ -180,7 +181,7 @@
|
||||
:chart-option="chartOption"
|
||||
:is-fullscreen="isFullscreen"
|
||||
@chartIsNoData="chartIsNoData"
|
||||
></chart-topology> -->
|
||||
></chart-topology>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -63,7 +63,7 @@ export default {
|
||||
statData: [],
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
boxPadding: 5,
|
||||
boxPadding: 2,
|
||||
statTimer: null,
|
||||
tooltip: {
|
||||
x: 0,
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<i class="el-icon-copy-document" style="font-size: 16px;"></i>
|
||||
<span>{{$t('dashboard.duplicate')}}</span>
|
||||
</li>
|
||||
<li v-if="from !== this.$CONSTANTS.fromRoute.chartTemp && chartInfo.pid" v-has="'main_edit'" class="el-dropdown-menu__item" @click="$emit('sync')">
|
||||
<li v-if="from !== this.$CONSTANTS.fromRoute.chartTemp && chartInfo.pid" v-has="'main_edit'" class="el-dropdown-menu__item" @click="sync">
|
||||
<i class="nz-icon nz-icon-sync" style="font-size: 16px;"></i>
|
||||
<span>{{$t('overall.syncChart')}}</span>
|
||||
</li>
|
||||
|
||||
@@ -43,18 +43,25 @@ export default {
|
||||
chart: this.chartInfo,
|
||||
type: 'edit'
|
||||
})
|
||||
this.dropdownMenuShow = false
|
||||
},
|
||||
removeChart () {
|
||||
this.$store.dispatch('dispatchDelChart', {
|
||||
chart: this.chartInfo,
|
||||
type: 'delete'
|
||||
})
|
||||
this.dropdownMenuShow = false
|
||||
},
|
||||
duplicate () {
|
||||
this.$store.dispatch('dispatchEditChart', {
|
||||
chart: this.chartInfo,
|
||||
type: 'duplicate'
|
||||
})
|
||||
this.dropdownMenuShow = false
|
||||
},
|
||||
sync () {
|
||||
this.$emit('sync')
|
||||
this.dropdownMenuShow = false
|
||||
},
|
||||
clickos () {
|
||||
this.dropdownMenuShow = false
|
||||
|
||||
@@ -123,7 +123,8 @@ export default {
|
||||
alias += chartInfo.elements[expressionIndex].expression
|
||||
}
|
||||
// proj_status_
|
||||
const name = alias + '-' + dataIndex
|
||||
const legendIndex = expressionIndex + 'and' + dataIndex
|
||||
const name = alias + '-' + legendIndex
|
||||
|
||||
// 若需要统计,处理统计数据
|
||||
const statisticsTypes = chartInfo.param.legend ? chartInfo.param.legend.values : ''
|
||||
@@ -144,7 +145,6 @@ export default {
|
||||
}
|
||||
},
|
||||
handleLegendAlias (legend, aliasExpression) {
|
||||
// console.log(legend, aliasExpression)
|
||||
if (/\{\{.+\}\}/.test(aliasExpression)) {
|
||||
const labelValue = aliasExpression.replace(/(\{\{.+?\}\})/g, function (i) {
|
||||
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
|
||||
|
||||
@@ -1,51 +1,96 @@
|
||||
<template>
|
||||
<div style="height: 100%;width: 100%">
|
||||
<div style="height: 100%; width: 100%">
|
||||
<div class="time-line-header">
|
||||
<span>{{$t('alert.relatedAlerts')}}</span>
|
||||
<span>{{ $t("alert.relatedAlerts") }}</span>
|
||||
<div class="scope-icon-box">
|
||||
<div class="scope-box" v-for="item in scopeList" :class="item.isSelect ? 'is-select' : ''" :key="item.type" @click="scopeChange(item)" :title="item.label">
|
||||
<div
|
||||
class="scope-box"
|
||||
v-for="item in scopeList"
|
||||
:class="item.isSelect ? 'is-select' : ''"
|
||||
:key="item.type"
|
||||
@click="scopeChange(item)"
|
||||
:title="item.label"
|
||||
>
|
||||
<i class="nz-icon" :class="selectIcon(item)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-timeline v-my-loading="loading" v-if="!noData && timeLineData.length">
|
||||
<el-timeline-item
|
||||
v-for="(item,index) in timeLineData"
|
||||
v-for="(item, index) in timeLineData"
|
||||
:key="item.id"
|
||||
:class="{
|
||||
'only': timeLineData.length === 1 ,
|
||||
only: timeLineData.length === 1,
|
||||
'has-time': item.startAt,
|
||||
'last': index === timeLineData.length-1 && index !==0
|
||||
last: index === timeLineData.length - 1 && index !== 0,
|
||||
}"
|
||||
:color="item.severity.color"
|
||||
:timestamp="item.startAt?item.startAt: ''"
|
||||
placement="top">
|
||||
<div >
|
||||
<div class='margin-b-10'>
|
||||
<span slot="title-icon" v-if="item['state']" style="margin-left: 5px" class="alert-message-state" :class="{'gray-bg': item['state'] == 3, 'red-bg': item['state'] == 1,'yellow-bg': item['state'] == 2}">{{$t(stateOptions.find(state=>state.value == item['state']).label)}}</span>
|
||||
<span class="time-line-item-header"> {{item.alertRule.name}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span v-for="(label, i) in labelsSort(JSON.parse(item.labels))" :key="i">
|
||||
:timestamp="item.startAt ? item.startAt : ''"
|
||||
placement="top"
|
||||
>
|
||||
<div>
|
||||
<div class="margin-b-10">
|
||||
<span
|
||||
@mouseenter="labelHover(item, label.label, true, true, $event)"
|
||||
@mouseleave="labelHover(item, label.label, false, true,)">
|
||||
<nz-alert-tag
|
||||
v-if="label.label !== 'alertname' && label.label !== 'severity'" :key="label.label" :cursor-point="tagType(label.label) !== 'info'"
|
||||
:label="label.label"
|
||||
:type="tagType(label.label)"
|
||||
style="margin: 5px 0 5px 5px;"
|
||||
slot="title-icon"
|
||||
v-if="item['state']"
|
||||
style="margin-left: 5px"
|
||||
class="alert-message-state"
|
||||
:class="{
|
||||
'gray-bg': item['state'] == 3,
|
||||
'red-bg': item['state'] == 1,
|
||||
'yellow-bg': item['state'] == 2,
|
||||
}"
|
||||
>{{
|
||||
$t(
|
||||
stateOptions.find((state) => state.value == item["state"])
|
||||
.label
|
||||
)
|
||||
}}</span
|
||||
>
|
||||
<span class="time-line-item-header">
|
||||
{{ item.alertRule.name }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="alert-message-summary">{{ item.summary }}</div>
|
||||
<div class="alert-message-startAt">
|
||||
<span>Start time:</span>
|
||||
<span>{{item.startTime.split(" ")[1]}}</span>
|
||||
<span>Duration:</span>
|
||||
<span>{{getDuration(item)}}</span>
|
||||
</div>
|
||||
<div class="alert-message-labels">
|
||||
<span
|
||||
v-for="(label, i) in labelsSort(JSON.parse(item.labels))"
|
||||
:key="i"
|
||||
>
|
||||
<span
|
||||
@mouseenter="labelHover(item, label.label, true, true, $event)"
|
||||
@mouseleave="labelHover(item, label.label, false, true)"
|
||||
>
|
||||
{{label.value}}
|
||||
</nz-alert-tag>
|
||||
<nz-alert-tag
|
||||
v-if="
|
||||
label.label !== 'alertname' && label.label !== 'severity'
|
||||
"
|
||||
:key="label.label"
|
||||
:cursor-point="tagType(label.label) !== 'info'"
|
||||
:label="label.label"
|
||||
:type="tagType(label.label)"
|
||||
style="margin: 5px 0 5px 5px"
|
||||
>
|
||||
{{ label.value }}
|
||||
</nz-alert-tag>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
<div v-if="timeLineData.length >= total" style="text-align: center">{{$t('overall.noMoreData')}}</div>
|
||||
<div v-if="timeLineData.length >= total" style="text-align: center">
|
||||
{{ $t("overall.noMoreData") }}
|
||||
</div>
|
||||
<div v-else class="load-more-box">
|
||||
<el-button size="small" @click="getTimeLineData()" :loading="loading">{{$t('overall.loadMore')}}</el-button>
|
||||
<el-button size="small" @click="getTimeLineData()" :loading="loading">{{
|
||||
$t("overall.loadMore")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-timeline>
|
||||
<div class="table-no-data" v-else>
|
||||
@@ -65,178 +110,224 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { alertMessage as alertMessageConstant } from '@/components/common/js/constants'
|
||||
import alertMessageLabelMixin from '@/components/common/alert/alertMessageLabelMixin'
|
||||
import alertLabelMixin from '@/components/common/mixin/alertLabelMixin'
|
||||
import { alertMessage as alertMessageConstant } from "@/components/common/js/constants";
|
||||
import alertMessageLabelMixin from "@/components/common/alert/alertMessageLabelMixin";
|
||||
import alertLabelMixin from "@/components/common/mixin/alertLabelMixin";
|
||||
import { calcDurationByStringTimeB } from '@/components/common/js/tools.js'
|
||||
|
||||
export default {
|
||||
name: 'alertMessageInfoTimeLine',
|
||||
name: "alertMessageInfoTimeLine",
|
||||
props: {
|
||||
infoData: {
|
||||
type: Object
|
||||
type: Object,
|
||||
},
|
||||
time: {}
|
||||
time: {},
|
||||
},
|
||||
mixins: [alertMessageLabelMixin, alertLabelMixin],
|
||||
computed: {
|
||||
severityData () {
|
||||
return this.$store.getters.severityData
|
||||
severityData() {
|
||||
return this.$store.getters.severityData;
|
||||
},
|
||||
getDuration () {
|
||||
return function (record) {
|
||||
if (record.endAt) {
|
||||
return calcDurationByStringTimeB(record.startTime, record.endAt)
|
||||
}
|
||||
return calcDurationByStringTimeB(record.startTime, this.nowTime)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
time: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler (n) {
|
||||
handler(n) {
|
||||
if (n && n.length) {
|
||||
this.pageNo = 1
|
||||
this.getTimeLineData()
|
||||
this.pageNo = 1;
|
||||
this.getTimeLineData();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
scope: ['asset', 'datacenter', 'project', 'module', 'endpoint', 'alertrule', 'hash'],
|
||||
scope: [
|
||||
"asset",
|
||||
"datacenter",
|
||||
"project",
|
||||
"module",
|
||||
"endpoint",
|
||||
"alertrule",
|
||||
"hash",
|
||||
],
|
||||
timeLineData: [],
|
||||
lastDataTime: '',
|
||||
lastDataTime: "",
|
||||
loading: false,
|
||||
dateFormatStr: localStorage.getItem('nz-default-dateFormat') ? localStorage.getItem('nz-default-dateFormat') : 'YYYY-MM-DD HH:ss:mm',
|
||||
dateFormatStr: localStorage.getItem("nz-default-dateFormat")
|
||||
? localStorage.getItem("nz-default-dateFormat")
|
||||
: "YYYY-MM-DD HH:ss:mm",
|
||||
noData: false,
|
||||
stateOptions: alertMessageConstant.states,
|
||||
scopeList: [{
|
||||
key: 'asset',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.asset')
|
||||
}, {
|
||||
key: 'datacenter',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.dc')
|
||||
}, {
|
||||
key: 'project',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.project')
|
||||
}, {
|
||||
key: 'module',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.module')
|
||||
}, {
|
||||
key: 'endpoint',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.endpoint')
|
||||
},
|
||||
{
|
||||
key: 'alertrule',
|
||||
isSelect: true,
|
||||
label: this.$t('alert.alertRule')
|
||||
}, {
|
||||
key: 'hash',
|
||||
isSelect: true,
|
||||
label: this.$t('overall.hash')
|
||||
}
|
||||
scopeList: [
|
||||
{
|
||||
key: "asset",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.asset"),
|
||||
},
|
||||
{
|
||||
key: "datacenter",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.dc"),
|
||||
},
|
||||
{
|
||||
key: "project",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.project"),
|
||||
},
|
||||
{
|
||||
key: "module",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.module"),
|
||||
},
|
||||
{
|
||||
key: "endpoint",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.endpoint"),
|
||||
},
|
||||
{
|
||||
key: "alertrule",
|
||||
isSelect: true,
|
||||
label: this.$t("alert.alertRule"),
|
||||
},
|
||||
{
|
||||
key: "hash",
|
||||
isSelect: true,
|
||||
label: this.$t("overall.hash"),
|
||||
},
|
||||
],
|
||||
total: 20,
|
||||
scopeChangeTimer: null
|
||||
}
|
||||
scopeChangeTimer: null,
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
// this.getTimeLineData(1)
|
||||
const dateFormatStr = localStorage.getItem('nz-default-dateFormat')
|
||||
const dateFormatStr = localStorage.getItem("nz-default-dateFormat");
|
||||
if (dateFormatStr) {
|
||||
this.dateFormatStr = dateFormatStr.split(' ')[0]
|
||||
this.dateFormatStr = dateFormatStr.split(" ")[0];
|
||||
} else {
|
||||
this.dateFormatStr = 'YYYY-MM-DD'
|
||||
this.dateFormatStr = "YYYY-MM-DD";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTimeLineData () {
|
||||
this.noData = false
|
||||
this.loading = true
|
||||
getTimeLineData() {
|
||||
this.noData = false;
|
||||
this.loading = true;
|
||||
const params = {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
scope: this.scopeList.filter(item => item.isSelect).map(item => item.key).join(','),
|
||||
scope: this.scopeList
|
||||
.filter((item) => item.isSelect)
|
||||
.map((item) => item.key)
|
||||
.join(","),
|
||||
id: this.infoData.id,
|
||||
state: '',
|
||||
startAt: this.timezoneToUtcTimeStr(this.time[0] * 1000, 'YYYY-MM-DD HH:mm:ss'),
|
||||
endAt: this.timezoneToUtcTimeStr(this.time[1] * 1000, 'YYYY-MM-DD HH:mm:ss'),
|
||||
orderBy: '-startAt'
|
||||
}
|
||||
this.$get('/alert/message/rel', params).then(res => {
|
||||
this.loading = false
|
||||
if (res.code === 200) {
|
||||
this.total = res.data.total
|
||||
if (this.pageNo == 1) {
|
||||
this.timeLineData = res.data.list
|
||||
state: "",
|
||||
startAt: this.timezoneToUtcTimeStr(
|
||||
this.time[0] * 1000,
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
),
|
||||
endAt: this.timezoneToUtcTimeStr(
|
||||
this.time[1] * 1000,
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
),
|
||||
orderBy: "-startAt",
|
||||
};
|
||||
this.$get("/alert/message/rel", params)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.code === 200) {
|
||||
this.total = res.data.total;
|
||||
if (this.pageNo == 1) {
|
||||
this.timeLineData = res.data.list;
|
||||
} else {
|
||||
this.timeLineData.push(...res.data.list);
|
||||
}
|
||||
this.disposeTime(this.pageNo);
|
||||
this.noData = false;
|
||||
this.pageNo++;
|
||||
} else {
|
||||
this.timeLineData.push(...res.data.list)
|
||||
this.noData = true;
|
||||
}
|
||||
this.disposeTime(this.pageNo)
|
||||
this.noData = false
|
||||
this.pageNo++
|
||||
} else {
|
||||
this.noData = true
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
this.noData = true
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
this.noData = true;
|
||||
});
|
||||
},
|
||||
disposeTime (pageNo) {
|
||||
let i = (pageNo - 1) * this.pageSize
|
||||
disposeTime(pageNo) {
|
||||
let i = (pageNo - 1) * this.pageSize;
|
||||
for (i; i < this.timeLineData.length; i++) {
|
||||
const lastDataTime = this.timestampStr(this.timeLineData[i].startAt, this.dateFormatStr)
|
||||
this.timeLineData[i].color = '#fa8'
|
||||
const lastDataTime = this.timestampStr(
|
||||
this.timeLineData[i].startAt,
|
||||
this.dateFormatStr
|
||||
);
|
||||
this.timeLineData[i].color = "#fa8";
|
||||
this.timeLineData[i].startTime = this.timeLineData[i].startAt;
|
||||
if (this.lastDataTime !== lastDataTime) {
|
||||
this.lastDataTime = lastDataTime
|
||||
this.timeLineData[i].startAt = lastDataTime
|
||||
this.lastDataTime = lastDataTime;
|
||||
this.timeLineData[i].startAt = lastDataTime;
|
||||
} else {
|
||||
this.timeLineData[i].startAt = ''
|
||||
this.timeLineData[i].startAt = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
selectIcon (item) {
|
||||
selectIcon(item) {
|
||||
switch (item.key) {
|
||||
case 'asset' : return 'nz-icon-overview-project'
|
||||
case 'datacenter' : return 'nz-icon-Datacenter2'
|
||||
case 'project' : return 'nz-icon-project'
|
||||
case 'module' : return 'nz-icon-overview-module'
|
||||
case 'endpoint' : return 'nz-icon-overview-endpoint'
|
||||
case 'alertrule' : return 'nz-icon-Alertrule'
|
||||
case 'hash' : return 'nz-icon-module5'
|
||||
case "asset":
|
||||
return "nz-icon-overview-project";
|
||||
case "datacenter":
|
||||
return "nz-icon-Datacenter2";
|
||||
case "project":
|
||||
return "nz-icon-project";
|
||||
case "module":
|
||||
return "nz-icon-overview-module";
|
||||
case "endpoint":
|
||||
return "nz-icon-overview-endpoint";
|
||||
case "alertrule":
|
||||
return "nz-icon-Alertrule";
|
||||
case "hash":
|
||||
return "nz-icon-module5";
|
||||
}
|
||||
return 'nz-icon-module5'
|
||||
return "nz-icon-module5";
|
||||
},
|
||||
scopeChange (scope) {
|
||||
scopeChange(scope) {
|
||||
if (this.scopeChangeTimer) {
|
||||
clearInterval(this.scopeChangeTimer)
|
||||
this.scopeChangeTimer = null
|
||||
clearInterval(this.scopeChangeTimer);
|
||||
this.scopeChangeTimer = null;
|
||||
}
|
||||
this.loading = true
|
||||
const isSelectArr = this.scopeList.filter(item => item.isSelect)
|
||||
this.loading = true;
|
||||
const isSelectArr = this.scopeList.filter((item) => item.isSelect);
|
||||
if (isSelectArr.length === this.scopeList.length) {
|
||||
this.scopeList.forEach(item => {
|
||||
item.isSelect = false
|
||||
})
|
||||
scope.isSelect = !scope.isSelect
|
||||
this.scopeList.forEach((item) => {
|
||||
item.isSelect = false;
|
||||
});
|
||||
scope.isSelect = !scope.isSelect;
|
||||
} else if (isSelectArr.length === 1 && isSelectArr[0].key === scope.key) {
|
||||
this.scopeList.forEach(item => {
|
||||
item.isSelect = true
|
||||
})
|
||||
this.scopeList.forEach((item) => {
|
||||
item.isSelect = true;
|
||||
});
|
||||
} else {
|
||||
scope.isSelect = !scope.isSelect
|
||||
scope.isSelect = !scope.isSelect;
|
||||
}
|
||||
this.scopeChangeTimer = setTimeout(() => {
|
||||
this.pageNo = 1
|
||||
this.getTimeLineData()
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.pageNo = 1;
|
||||
this.getTimeLineData();
|
||||
}, 100);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{{alertRuleData && alertRuleData.name ? alertRuleData.name : '--'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert-rule-info" >
|
||||
<div class="alert-rule-nfo" >
|
||||
<div class="alert-rule-box">
|
||||
<div class="alert-rule-title">ID</div>
|
||||
<div class="alert-rule-value">{{alertRuleData.id ? alertRuleData.id : '--'}}</div>
|
||||
|
||||
@@ -181,6 +181,7 @@ export default {
|
||||
return {
|
||||
fromRoute,
|
||||
pdfId: 'pdfDom',
|
||||
htmlTitle: 'panel',
|
||||
panelTabLoading: false,
|
||||
showTopBtn: false, // top按钮
|
||||
visible: false,
|
||||
|
||||
@@ -34,6 +34,7 @@ export function getHexagon (key) {
|
||||
const topologyCache = {}
|
||||
|
||||
export function getTopology (key) {
|
||||
// console.log(topologyCache, 'topologyCache')
|
||||
return topologyCache[`topology${key}`]
|
||||
}
|
||||
|
||||
@@ -41,6 +42,18 @@ export function setTopology (key, value) {
|
||||
topologyCache[`topology${key}`] = value
|
||||
}
|
||||
|
||||
// const topologyImgList = localStorage.getItem('nz-imgList') ? JSON.parse(localStorage.getItem('nz-imgList')) : {}
|
||||
|
||||
export function getTopologyImg (key) {
|
||||
// console.log(topologyCache, 'topologyCache')
|
||||
// console.log(localStorage.getItem('nz-img-' + key), !localStorage.getItem('nz-img-' + key))
|
||||
return localStorage.getItem('nz-img-' + key)
|
||||
}
|
||||
|
||||
export function setTopologyImg (key, img) {
|
||||
localStorage.setItem('nz-img-' + key, img)
|
||||
}
|
||||
|
||||
export function setHexagon (key, value) {
|
||||
hexagonCache[`hexagon${key}`] = value
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ import {
|
||||
myCubec,
|
||||
myCubeAnchors
|
||||
} from './L5/services/canvas.js'
|
||||
import { getTopology, setTopology } from '../js/common'
|
||||
import { getTopology, setTopology, getTopologyImg, setTopologyImg } from '../js/common'
|
||||
import CanvasProps from './L5/CanvasProps'
|
||||
import topologyTopTool from './L5//topologyTopTool'
|
||||
import CanvasContextMenu from './L5/CanvasContextMenu'
|
||||
@@ -826,6 +826,7 @@ export default {
|
||||
this.saveData = JSON.parse(JSON.stringify(data))
|
||||
this.topologyInfo.name = this.obj.name
|
||||
resolve(data)
|
||||
data = null
|
||||
} else {
|
||||
if (data.data) {
|
||||
this.topologyInfo = {
|
||||
@@ -868,13 +869,13 @@ export default {
|
||||
item.image = img ? img.image : imgDefault
|
||||
}
|
||||
if (item.type === 0) {
|
||||
promiseArr.push(this.$get('stat/module/abnormal', { moduleId: item.data.moduleId }))
|
||||
// promiseArr.push(this.$get('stat/module/abnormal', { moduleId: item.data.moduleId }))
|
||||
item.data.state = {}
|
||||
item.data.state.asset = false
|
||||
item.data.state.endpoint = false
|
||||
item.data.state.alert = false
|
||||
} else {
|
||||
promiseArr.push({ type: 1 })
|
||||
// promiseArr.push({ type: 1 })
|
||||
item.data.state = {}
|
||||
item.data.state.asset = false
|
||||
item.data.state.endpoint = false
|
||||
@@ -899,13 +900,13 @@ export default {
|
||||
data.bkColor = '#FFFFFF00'
|
||||
}
|
||||
Promise.all(promiseArr).then(res => {
|
||||
res.forEach((response, index) => {
|
||||
const item = data.pens[index]
|
||||
res[0].data.list.forEach((module, index) => {
|
||||
const item = data.pens.find(pens => module.id === pens.data.moduleId)
|
||||
if (item.type === 0 && item.data.state && res[index].data.list.length) {
|
||||
item.data.state.error = item.data.error = !res[index].data.list[0].state
|
||||
item.data.state.asset = !!res[index].data.list[0].asset
|
||||
item.data.state.alert = !!res[index].data.list[0].alert
|
||||
item.data.state.endpoint = !!res[index].data.list[0].endpoint
|
||||
item.data.state.error = item.data.error = !module.state
|
||||
item.data.state.asset = !!module.asset
|
||||
item.data.state.alert = !!module.alert
|
||||
item.data.state.endpoint = !!module.endpoint
|
||||
} else {
|
||||
item.data.state = {
|
||||
error: false,
|
||||
@@ -1066,9 +1067,10 @@ export default {
|
||||
|
||||
getNodesArr () {
|
||||
if (!getTopology(this.topologyIndex)) return
|
||||
let arr = []
|
||||
this.offsetX = getTopology(this.topologyIndex).data.x
|
||||
this.offsetY = getTopology(this.topologyIndex).data.y
|
||||
this.nodesArr = getTopology(this.topologyIndex).data.pens.filter(item => {
|
||||
arr = getTopology(this.topologyIndex).data.pens.filter(item => {
|
||||
if (!item.data) {
|
||||
item.data = {
|
||||
moduleId: '',
|
||||
@@ -1083,7 +1085,14 @@ export default {
|
||||
return item.type === 0
|
||||
})
|
||||
// 打开动画 是否更新顶部图标
|
||||
this.nodesArr = arr.map(item => {
|
||||
return {
|
||||
rect: item.rect,
|
||||
data: item.data
|
||||
}
|
||||
})
|
||||
this.nodesArr = JSON.parse(JSON.stringify(this.nodesArr))
|
||||
arr = null
|
||||
},
|
||||
|
||||
modelTopClick (item, index) {
|
||||
@@ -1290,9 +1299,9 @@ export default {
|
||||
this.tooltipPosition.show = false
|
||||
setTimeout(() => {
|
||||
this.tooltipPosition.show = true
|
||||
const ePosition = window.ePosition
|
||||
const boxWidth = document.getElementsByClassName('page')[0].offsetWidth
|
||||
const boxHeight = document.getElementsByClassName('page')[0].offsetHeight
|
||||
let ePosition = window.ePosition
|
||||
let boxWidth = document.getElementsByClassName('page')[0].offsetWidth
|
||||
let boxHeight = document.getElementsByClassName('page')[0].offsetHeight
|
||||
this.tooltipPosition.left = ePosition.layerX + 20
|
||||
this.tooltipPosition.top = ePosition.layerY
|
||||
this.$nextTick(() => {
|
||||
@@ -1308,6 +1317,9 @@ export default {
|
||||
this.tooltipPosition.top = ePosition.layerY - this.$refs.topoTooltip.offsetHeight
|
||||
}
|
||||
}
|
||||
ePosition = null
|
||||
boxWidth = null
|
||||
boxHeight = null
|
||||
})
|
||||
}, 100)
|
||||
break
|
||||
@@ -1434,22 +1446,26 @@ export default {
|
||||
}
|
||||
break
|
||||
case 'resize': {
|
||||
const dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
const domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
let dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
let domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
if (getTopology(this.topologyIndex)) {
|
||||
getTopology(this.topologyIndex).canvasPos = domRect
|
||||
}
|
||||
dom = null
|
||||
domRect = null
|
||||
break
|
||||
}
|
||||
case 'scale': {
|
||||
if (this.$refs.topTool) {
|
||||
this.$refs.topTool.scaleNum = parseInt(data * 100)
|
||||
}
|
||||
const dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
const domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
let dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
let domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
if (getTopology(this.topologyIndex)) {
|
||||
getTopology(this.topologyIndex).canvasPos = domRect
|
||||
}
|
||||
dom = null
|
||||
domRect = null
|
||||
break
|
||||
}
|
||||
case 'locked': {
|
||||
@@ -1720,18 +1736,26 @@ export default {
|
||||
this.$get('monitor/project/topo/icon').then(res => {
|
||||
this.imgageLoading = true
|
||||
this.tools = [...Tools]
|
||||
const imgArr = []
|
||||
const promiseArr = []
|
||||
let imgArr = []
|
||||
let promiseArr = []
|
||||
res.data.list.forEach((item, index) => {
|
||||
item.imageName = item.name
|
||||
delete item.name
|
||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}/1`))
|
||||
if (getTopologyImg(item.id)) {
|
||||
promiseArr.push(getTopologyImg(item.id))
|
||||
} else {
|
||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}/1`))
|
||||
}
|
||||
imgArr.push({ ...item })
|
||||
})
|
||||
Promise.all(promiseArr).then((res2, header) => {
|
||||
this.iconArray = [...res.data.list]
|
||||
this.iconArray.forEach((item, index) => {
|
||||
item.image = res2[index].data
|
||||
console.log(res2[index])
|
||||
item.image = res2[index].data || res2[index]
|
||||
if (!getTopologyImg(item.id)) {
|
||||
setTopologyImg(item.id, item.image)
|
||||
}
|
||||
const group = this.tools.find(tool => tool.group === item.unit)
|
||||
if (group) {
|
||||
group.children.push({
|
||||
@@ -1771,18 +1795,24 @@ export default {
|
||||
|
||||
this.imgInit = true
|
||||
this.imgageLoading = false
|
||||
imgArr = null
|
||||
promiseArr = null
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.imgageLoading = true
|
||||
this.$get('monitor/project/topo/icon').then((imageAllId) => {
|
||||
const promiseArr = []
|
||||
let promiseArr = []
|
||||
if (!imageAllId || !imageAllId.data) {
|
||||
return
|
||||
}
|
||||
imgidList.forEach((item, index) => {
|
||||
if (item.data.imageId && imageAllId.data.list.find(image => item.data.imageId === image.id)) {
|
||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}/1`))
|
||||
if (getTopologyImg(item.data.imageId)) {
|
||||
promiseArr.push(getTopologyImg(item.data.imageId))
|
||||
} else {
|
||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}/1`))
|
||||
}
|
||||
} else if (item.data.imageId) {
|
||||
promiseArr.push(imgDefault)
|
||||
} else {
|
||||
@@ -1797,12 +1827,16 @@ export default {
|
||||
})
|
||||
this.iconArray.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
item.image = res2[index].data
|
||||
item.image = res2[index].data || res2[index]
|
||||
if (!getTopologyImg(item.id)) {
|
||||
setTopologyImg(item.id, item.image)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.imgInit = true
|
||||
this.imgageLoading = false
|
||||
imgidList = null
|
||||
promiseArr = null
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -2040,10 +2074,12 @@ export default {
|
||||
this.editTopologyFlag = false
|
||||
this.$nextTick(() => {
|
||||
getTopology(this.topologyIndex).lock(1)
|
||||
const dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
const domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
let dom = document.getElementById('topology-canvas' + this.topologyIndexF)
|
||||
let domRect = dom ? dom.getBoundingClientRect() : {}
|
||||
getTopology(this.topologyIndex).canvasPos = domRect
|
||||
this.$store.commit('setShowTopoScreen', this.topoScreenState)
|
||||
dom = null
|
||||
domRect = null
|
||||
})
|
||||
this.reload()
|
||||
},
|
||||
@@ -2115,7 +2151,7 @@ export default {
|
||||
|
||||
winResize () {
|
||||
setTimeout(() => {
|
||||
const domRect = document.getElementById('topology-canvas' + this.topologyIndex).getBoundingClientRect()
|
||||
let domRect = document.getElementById('topology-canvas' + this.topologyIndex).getBoundingClientRect()
|
||||
getTopology(this.topologyIndex).canvasPos = domRect
|
||||
if (this.fromOverView) {
|
||||
getTopology(this.topologyIndex).open(this.oldTopologyData)
|
||||
@@ -2138,6 +2174,7 @@ export default {
|
||||
getTopology(this.topologyIndex).resize()
|
||||
getTopology(this.topologyIndex).centerView()
|
||||
this.getNodesArr()
|
||||
domRect = null
|
||||
}, 500)
|
||||
},
|
||||
contextmenuNone () {
|
||||
@@ -2186,18 +2223,6 @@ export default {
|
||||
}
|
||||
return flag
|
||||
},
|
||||
modelPopError (pen, state) {
|
||||
if (item.id === 'asset' && this.activeModelItem.assetError) {
|
||||
return true
|
||||
}
|
||||
if (item.id === 'alert' && this.activeModelItem.alertError) {
|
||||
return true
|
||||
}
|
||||
if (item.id === 'endpoint' && this.activeModelItem.endpointError) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
redoIndexChange (index) {
|
||||
this.redoIndex = index
|
||||
},
|
||||
@@ -2264,6 +2289,13 @@ export default {
|
||||
if (getTopology(this.topologyIndex)) {
|
||||
getTopology(this.topologyIndex).off('contextmenu', this.onContextMenu)
|
||||
getTopology(this.topologyIndex).destroy()
|
||||
window.topology = null
|
||||
window.Le5leTopologyPoint = null
|
||||
window.topologyPoint = null
|
||||
window.topologyRect = null
|
||||
Object.keys(getTopology(this.topologyIndex)).forEach(key => {
|
||||
getTopology(this.topologyIndex)[key] = null
|
||||
})
|
||||
setTopology(this.topologyIndex, null)
|
||||
}
|
||||
if (document.getElementById('topology-canvas' + this.topologyIndexF)) {
|
||||
|
||||
@@ -348,6 +348,7 @@ import { noSpecialChar, nzNumber } from '../js/validate'
|
||||
import editRigthBox from '../mixin/editRigthBox'
|
||||
import richTextEditor from '@/components/chart/richTextEditor'
|
||||
import promqlInputMixin from '@/components/common/mixin/promqlInput'
|
||||
|
||||
export default {
|
||||
name: 'alertRuleBox',
|
||||
props: {
|
||||
|
||||
@@ -50,13 +50,17 @@
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else-if="item.prop === 'alertNum'">
|
||||
<span style="cursor: pointer" @click="$emit('showBottomBox', 'alertMessageTab', scope.row)">
|
||||
<span
|
||||
style="cursor: pointer"
|
||||
@click="$emit('showBottomBox', 'alertMessageTab', scope.row)"
|
||||
>
|
||||
<i
|
||||
:class="scope.row.alertNum > 0 ? 'gray' : 'green'"
|
||||
class="nz-icon nz-icon-overview-alert vertical-align-top;"
|
||||
@mouseenter="tooltipHover(scope.row, true, $event)"
|
||||
@mouseleave="tooltipHover(scope.row, false, $event)"
|
||||
></i><span>{{scope.row.alerts}}</span>
|
||||
></i
|
||||
><span>{{ scope.row.alerts }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="item.prop === 'matchers'">
|
||||
@@ -207,13 +211,6 @@ export default {
|
||||
minWidth: 200,
|
||||
sortable: "custom",
|
||||
},
|
||||
{
|
||||
label: this.$t("alert.alert"),
|
||||
prop: "alertNum",
|
||||
show: true,
|
||||
minWidth: 120,
|
||||
sortable: "custom",
|
||||
},
|
||||
{
|
||||
label: this.$t("alert.silence.startTime"),
|
||||
prop: "startAt",
|
||||
@@ -239,6 +236,13 @@ export default {
|
||||
show: false,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
label: this.$t("alert.alert"),
|
||||
prop: "alertNum",
|
||||
show: true,
|
||||
minWidth: 120,
|
||||
sortable: "custom",
|
||||
},
|
||||
{
|
||||
label: this.$t("alert.silence.state"),
|
||||
prop: "state",
|
||||
|
||||
183
nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx
Normal file
183
nezha-fronted/src/components/page/dashboard/explore/CMTheme.tsx
Normal file
@@ -0,0 +1,183 @@
|
||||
import { HighlightStyle, tags } from '@codemirror/highlight';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
|
||||
export const baseTheme = EditorView.theme({
|
||||
'&': {
|
||||
'&.cm-focused': {
|
||||
outline: 'none',
|
||||
outline_fallback: 'none',
|
||||
},
|
||||
},
|
||||
'.cm-scroller': {
|
||||
overflow: 'hidden',
|
||||
fontFamily: '"DejaVu Sans Mono", monospace',
|
||||
},
|
||||
'.cm-placeholder': {
|
||||
fontFamily:
|
||||
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"',
|
||||
},
|
||||
|
||||
'.cm-matchingBracket': {
|
||||
color: '#000',
|
||||
backgroundColor: '#dedede',
|
||||
fontWeight: 'bold',
|
||||
outline: '1px dashed transparent',
|
||||
},
|
||||
'.cm-nonmatchingBracket': { borderColor: 'red' },
|
||||
|
||||
'.cm-tooltip': {
|
||||
backgroundColor: '#f8f8f8',
|
||||
borderColor: 'rgba(52, 79, 113, 0.2)',
|
||||
},
|
||||
|
||||
'.cm-tooltip.cm-tooltip-autocomplete': {
|
||||
'& > ul': {
|
||||
maxHeight: '350px',
|
||||
fontFamily: '"DejaVu Sans Mono", monospace',
|
||||
maxWidth: 'unset',
|
||||
},
|
||||
'& > ul > li': {
|
||||
padding: '2px 1em 2px 3px',
|
||||
},
|
||||
'& li:hover': {
|
||||
backgroundColor: '#ddd',
|
||||
},
|
||||
'& > ul > li[aria-selected]': {
|
||||
backgroundColor: '#d6ebff',
|
||||
color: 'unset',
|
||||
},
|
||||
minWidth: '30%',
|
||||
},
|
||||
|
||||
'.cm-completionDetail': {
|
||||
float: 'right',
|
||||
color: '#999',
|
||||
},
|
||||
|
||||
'.cm-tooltip.cm-completionInfo': {
|
||||
marginTop: '-11px',
|
||||
padding: '10px',
|
||||
fontFamily: "'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;",
|
||||
border: 'none',
|
||||
backgroundColor: '#d6ebff',
|
||||
minWidth: '250px',
|
||||
maxWidth: 'min-content',
|
||||
},
|
||||
|
||||
'.cm-completionInfo.cm-completionInfo-right': {
|
||||
'&:before': {
|
||||
content: "' '",
|
||||
height: '0',
|
||||
position: 'absolute',
|
||||
width: '0',
|
||||
left: '-20px',
|
||||
border: '10px solid transparent',
|
||||
borderRightColor: '#d6ebff',
|
||||
},
|
||||
marginLeft: '12px',
|
||||
},
|
||||
'.cm-completionInfo.cm-completionInfo-left': {
|
||||
'&:before': {
|
||||
content: "' '",
|
||||
height: '0',
|
||||
position: 'absolute',
|
||||
width: '0',
|
||||
right: '-20px',
|
||||
border: '10px solid transparent',
|
||||
borderLeftColor: '#d6ebff',
|
||||
},
|
||||
marginRight: '12px',
|
||||
},
|
||||
|
||||
'.cm-completionMatchedText': {
|
||||
textDecoration: 'none',
|
||||
fontWeight: 'bold',
|
||||
color: '#0066bf',
|
||||
},
|
||||
|
||||
'.cm-line': {
|
||||
'&::selection': {
|
||||
backgroundColor: '#add6ff',
|
||||
},
|
||||
'& > span::selection': {
|
||||
backgroundColor: '#add6ff',
|
||||
},
|
||||
},
|
||||
|
||||
'.cm-selectionMatch': {
|
||||
backgroundColor: '#e6f3ff',
|
||||
},
|
||||
|
||||
'.cm-diagnostic': {
|
||||
'&.cm-diagnostic-error': {
|
||||
borderLeft: '3px solid #e65013',
|
||||
},
|
||||
},
|
||||
|
||||
'.cm-completionIcon': {
|
||||
boxSizing: 'content-box',
|
||||
fontSize: '16px',
|
||||
lineHeight: '1',
|
||||
marginRight: '10px',
|
||||
verticalAlign: 'top',
|
||||
'&:after': { content: "'\\ea88'" },
|
||||
fontFamily: 'codicon',
|
||||
paddingRight: '0',
|
||||
opacity: '1',
|
||||
color: '#007acc',
|
||||
},
|
||||
|
||||
'.cm-completionIcon-function, .cm-completionIcon-method': {
|
||||
'&:after': { content: "'\\ea8c'" },
|
||||
color: '#652d90',
|
||||
},
|
||||
'.cm-completionIcon-class': {
|
||||
'&:after': { content: "'○'" },
|
||||
},
|
||||
'.cm-completionIcon-interface': {
|
||||
'&:after': { content: "'◌'" },
|
||||
},
|
||||
'.cm-completionIcon-variable': {
|
||||
'&:after': { content: "'𝑥'" },
|
||||
},
|
||||
'.cm-completionIcon-constant': {
|
||||
'&:after': { content: "'\\eb5f'" },
|
||||
color: '#007acc',
|
||||
},
|
||||
'.cm-completionIcon-type': {
|
||||
'&:after': { content: "'𝑡'" },
|
||||
},
|
||||
'.cm-completionIcon-enum': {
|
||||
'&:after': { content: "'∪'" },
|
||||
},
|
||||
'.cm-completionIcon-property': {
|
||||
'&:after': { content: "'□'" },
|
||||
},
|
||||
'.cm-completionIcon-keyword': {
|
||||
'&:after': { content: "'\\eb62'" },
|
||||
color: '#616161',
|
||||
},
|
||||
'.cm-completionIcon-namespace': {
|
||||
'&:after': { content: "'▢'" },
|
||||
},
|
||||
'.cm-completionIcon-text': {
|
||||
'&:after': { content: "'\\ea95'" },
|
||||
color: '#ee9d28',
|
||||
},
|
||||
});
|
||||
|
||||
export const promqlHighlighter = HighlightStyle.define([
|
||||
{ tag: tags.name, color: '#000' },
|
||||
{ tag: tags.number, color: '#09885a' },
|
||||
{ tag: tags.string, color: '#a31515' },
|
||||
{ tag: tags.keyword, color: '#008080' },
|
||||
{ tag: tags.function(tags.variableName), color: '#008080' },
|
||||
{ tag: tags.labelName, color: '#800000' },
|
||||
{ tag: tags.operator },
|
||||
{ tag: tags.modifier, color: '#008080' },
|
||||
{ tag: tags.paren },
|
||||
{ tag: tags.squareBracket },
|
||||
{ tag: tags.brace },
|
||||
{ tag: tags.invalid, color: 'red' },
|
||||
{ tag: tags.comment, color: '#888', fontStyle: 'italic' },
|
||||
]);
|
||||
@@ -6,100 +6,268 @@
|
||||
<div v-if="plugins.indexOf('metric-selector') > -1">
|
||||
<el-dropdown class="metric-selector">
|
||||
<el-dropdown-menu style="display: none"></el-dropdown-menu>
|
||||
<button class="top-tool-btn top-tool-btn--text" type="button" @click="toggleDropdown">{{type === 'log' ? $t("overall.logLabels") : $t("overall.metric") }}
|
||||
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px"></i></button>
|
||||
<el-cascader-panel v-show="dropDownVisible" ref="metricSelector" slot="dropdown" v-model="cascaderValue"
|
||||
v-clickoutside="closeDropdown" v-my-loading="tempBoxShowLoading" :loading="loading" :options="metricOptions"
|
||||
v-if="type !== 'log'" :props="cascaderProps" @change="metricChangeNew" style="margin-top: 5px">
|
||||
|
||||
<button
|
||||
class="top-tool-btn top-tool-btn--text"
|
||||
type="button"
|
||||
@click="toggleDropdown"
|
||||
>
|
||||
{{
|
||||
type === "log" ? $t("overall.logLabels") : $t("overall.metric")
|
||||
}}
|
||||
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px"></i>
|
||||
</button>
|
||||
<el-cascader-panel
|
||||
v-show="dropDownVisible"
|
||||
ref="metricSelector"
|
||||
slot="dropdown"
|
||||
v-model="cascaderValue"
|
||||
v-clickoutside="closeDropdown"
|
||||
v-my-loading="tempBoxShowLoading"
|
||||
:loading="loading"
|
||||
:options="metricOptions"
|
||||
v-if="type !== 'log'"
|
||||
:props="cascaderProps"
|
||||
@change="metricChangeNew"
|
||||
style="margin-top: 5px"
|
||||
>
|
||||
<template slot-scope="{ node, data }">
|
||||
<div :class="['nz-cascade',data.temp&&!data.child?'nz-cascade-temp':'',data.more?'cascader-panel-more':'']" @click="()=>{lazyLoad(node,data)}" :title="data.label">
|
||||
<div
|
||||
:class="[
|
||||
'nz-cascade',
|
||||
data.temp && !data.child ? 'nz-cascade-temp' : '',
|
||||
data.more ? 'cascader-panel-more' : '',
|
||||
]"
|
||||
@click="
|
||||
() => {
|
||||
lazyLoad(node, data);
|
||||
}
|
||||
"
|
||||
:title="data.label"
|
||||
>
|
||||
<i class="nz-icon nz-icon-template2"></i>
|
||||
{{data.label}}
|
||||
{{ data.label }}
|
||||
<i v-if="data.more" class="nz-icon nz-icon-arrow-down"></i>
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
<el-cascader-panel v-else v-show="dropDownVisible" ref="metricSelector" slot="dropdown"
|
||||
v-model="cascaderValue" v-clickoutside="closeDropdown" v-my-loading="tempBoxShowLoading"
|
||||
:loading="loading" :props="cascaderProps" @change="logLabelChange" style="margin-top: 5px;">
|
||||
<el-cascader-panel
|
||||
v-else
|
||||
v-show="dropDownVisible"
|
||||
ref="metricSelector"
|
||||
slot="dropdown"
|
||||
v-model="cascaderValue"
|
||||
v-clickoutside="closeDropdown"
|
||||
v-my-loading="tempBoxShowLoading"
|
||||
:loading="loading"
|
||||
:props="cascaderProps"
|
||||
@change="logLabelChange"
|
||||
style="margin-top: 5px"
|
||||
>
|
||||
<template slot-scope="{ node, data }">
|
||||
<div :title="data.label" class="nz-cascade">
|
||||
{{data.label}}
|
||||
{{ data.label }}
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<div v-if="plugins.indexOf('metric-input') > -1" class="input-box" @click="dropDownVisible=false">
|
||||
<el-input :id="inputId" v-model="expressionList[index]" :autosize="{ minRows: 1, maxRows: 6}"
|
||||
class="not-fixed-height no-resize" type="textarea"
|
||||
@input="metricKeyDown" @keyup.enter.native="expressionChange" ref="elInput"></el-input>
|
||||
<div v-if="errorMsg" class="append-msg error"><span>{{errorMsg}}</span></div>
|
||||
<div v-if="appendMsg" class="append-msg error"><span>{{appendMsg}}</span></div>
|
||||
<div
|
||||
v-if="plugins.indexOf('metric-input') > -1"
|
||||
class="input-box"
|
||||
@click="dropDownVisible = false"
|
||||
>
|
||||
<div id="editor"
|
||||
>
|
||||
</div>
|
||||
<!-- <el-input
|
||||
:id="inputId"
|
||||
v-model="expressionList[index]"
|
||||
:autosize="{ minRows: 1, maxRows: 6 }"
|
||||
class="not-fixed-height no-resize"
|
||||
type="textarea"
|
||||
@input="metricKeyDown"
|
||||
@keyup.enter.native="expressionChange"
|
||||
ref="elInput"
|
||||
></el-input> -->
|
||||
|
||||
<div v-if="errorMsg" class="append-msg error">
|
||||
<span>{{ errorMsg }}</span>
|
||||
</div>
|
||||
<div v-if="appendMsg" class="append-msg error">
|
||||
<span>{{ appendMsg }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-tool-btn-group">
|
||||
<button v-if="plugins.indexOf('add') > -1" class="top-tool-btn"
|
||||
@click="addExpression"><i class="nz-icon nz-icon-plus"></i></button>
|
||||
<button v-if="plugins.indexOf('copy') > -1" class="top-tool-btn"
|
||||
@click="copyExpression"><i class="nz-icon nz-icon-override"></i></button>
|
||||
<button v-if="plugins.indexOf('remove') > -1" class="top-tool-btn"
|
||||
@click="removeExpression"><i class="nz-icon nz-icon-minus"></i></button>
|
||||
<button
|
||||
v-if="plugins.indexOf('add') > -1"
|
||||
class="top-tool-btn"
|
||||
@click="addExpression"
|
||||
>
|
||||
<i class="nz-icon nz-icon-plus"></i>
|
||||
</button>
|
||||
<button
|
||||
v-if="plugins.indexOf('copy') > -1"
|
||||
class="top-tool-btn"
|
||||
@click="copyExpression"
|
||||
>
|
||||
<i class="nz-icon nz-icon-override"></i>
|
||||
</button>
|
||||
<button
|
||||
v-if="plugins.indexOf('remove') > -1"
|
||||
class="top-tool-btn"
|
||||
@click="removeExpression"
|
||||
>
|
||||
<i class="nz-icon nz-icon-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<!--right-box里的样式-->
|
||||
<template v-if="styleType === 2 || styleType === 3">
|
||||
<el-row v-if="plugins.indexOf('metric-input') > -1 || plugins.indexOf('metric-selector') > -1"
|
||||
style="width: 100%;">
|
||||
<el-col
|
||||
:class="[plugins.indexOf('metric-selector') > -1 ?'metric-selector-title':'metric-null-title']">
|
||||
<el-dropdown class="metric-selector" v-if="plugins.indexOf('metric-selector') > -1">
|
||||
<el-dropdown-menu style="display: none"></el-dropdown-menu>
|
||||
<span :class="{'expr-title':projectRightBox}" style="cursor: pointer;" @click="toggleDropdown">{{type === 'log' ? $t("overall.logLabels") : $t("overall.metric") }}<i
|
||||
<el-row
|
||||
v-if="
|
||||
plugins.indexOf('metric-input') > -1 ||
|
||||
plugins.indexOf('metric-selector') > -1
|
||||
"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-col
|
||||
:class="[
|
||||
plugins.indexOf('metric-selector') > -1
|
||||
? 'metric-selector-title'
|
||||
: 'metric-null-title',
|
||||
]"
|
||||
>
|
||||
<el-dropdown
|
||||
class="metric-selector"
|
||||
v-if="plugins.indexOf('metric-selector') > -1"
|
||||
>
|
||||
<el-dropdown-menu style="display: none"></el-dropdown-menu>
|
||||
<span
|
||||
:class="{ 'expr-title': projectRightBox }"
|
||||
style="cursor: pointer"
|
||||
@click="toggleDropdown"
|
||||
>{{
|
||||
type === "log"
|
||||
? $t("overall.logLabels")
|
||||
: $t("overall.metric")
|
||||
}}<i
|
||||
class="nz-icon nz-icon-arrow-down"
|
||||
style="font-size: 14px; -webkit-transform:scale(0.75);display:inline-block;"></i></span>
|
||||
<el-cascader-panel v-my-loading="tempBoxShowLoading" v-show="dropDownVisible" v-clickoutside="closeDropdown" v-model="cascaderValue"
|
||||
style="text-align: left;margin-top: 5px" slot="dropdown" ref="metricSelector"
|
||||
v-if="type !== 'log'" :props="{emitPath:false}" :options="metricOptions" @change="metricChangeNew">
|
||||
style="
|
||||
font-size: 14px;
|
||||
-webkit-transform: scale(0.75);
|
||||
display: inline-block;
|
||||
"
|
||||
></i
|
||||
></span>
|
||||
<el-cascader-panel
|
||||
v-my-loading="tempBoxShowLoading"
|
||||
v-show="dropDownVisible"
|
||||
v-clickoutside="closeDropdown"
|
||||
v-model="cascaderValue"
|
||||
style="text-align: left; margin-top: 5px"
|
||||
slot="dropdown"
|
||||
ref="metricSelector"
|
||||
v-if="type !== 'log'"
|
||||
:props="{ emitPath: false }"
|
||||
:options="metricOptions"
|
||||
@change="metricChangeNew"
|
||||
>
|
||||
<template slot-scope="{ node, data }">
|
||||
<div
|
||||
:class="[
|
||||
'nz-cascade',
|
||||
data.temp && !data.child ? 'nz-cascade-temp' : '',
|
||||
data.more ? 'cascader-panel-more' : '',
|
||||
]"
|
||||
@click="
|
||||
() => {
|
||||
lazyLoad(node, data);
|
||||
}
|
||||
"
|
||||
:title="data.label"
|
||||
>
|
||||
<i class="nz-icon nz-icon-template2"></i>
|
||||
{{ data.label }}
|
||||
<i v-if="data.more" class="nz-icon nz-icon-arrow-down"></i>
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
<el-cascader-panel
|
||||
v-else
|
||||
v-show="dropDownVisible"
|
||||
ref="metricSelector"
|
||||
slot="dropdown"
|
||||
v-model="cascaderValue"
|
||||
v-clickoutside="closeDropdown"
|
||||
v-my-loading="tempBoxShowLoading"
|
||||
:loading="loading"
|
||||
:props="cascaderProps"
|
||||
@change="logLabelChange"
|
||||
>
|
||||
<template slot-scope="{ node, data }">
|
||||
<div :title="data.label" class="nz-cascade">
|
||||
{{ data.label }}
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
</el-dropdown>
|
||||
</el-col>
|
||||
<el-col
|
||||
:class="
|
||||
plugins.indexOf('metric-selector') > -1
|
||||
? 'metric-selector-input-box'
|
||||
: 'metric-null-input-box'
|
||||
"
|
||||
:style="{ height: '100%' }"
|
||||
>
|
||||
|
||||
<template slot-scope="{ node, data }">
|
||||
<div :class="['nz-cascade',data.temp&&!data.child?'nz-cascade-temp':'',data.more?'cascader-panel-more':'']" @click="()=>{lazyLoad(node,data)}" :title="data.label">
|
||||
<i class="nz-icon nz-icon-template2"></i>
|
||||
{{data.label}}
|
||||
<i v-if="data.more" class="nz-icon nz-icon-arrow-down"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="input-box"
|
||||
@click="dropDownVisible = false"
|
||||
v-if="plugins.indexOf('metric-input') > -1"
|
||||
>
|
||||
<div id="editor"
|
||||
class="not-fixed-height no-resize"
|
||||
ref="elInput"
|
||||
|
||||
</el-cascader-panel>
|
||||
<el-cascader-panel v-else v-show="dropDownVisible" ref="metricSelector" slot="dropdown"
|
||||
v-model="cascaderValue" v-clickoutside="closeDropdown" v-my-loading="tempBoxShowLoading"
|
||||
:loading="loading" :props="cascaderProps" @change="logLabelChange">
|
||||
<template slot-scope="{ node, data }">
|
||||
<div :title="data.label" class="nz-cascade">
|
||||
{{data.label}}
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
</el-dropdown>
|
||||
</el-col>
|
||||
<el-col
|
||||
:class="plugins.indexOf('metric-selector') > -1 ?'metric-selector-input-box':'metric-null-input-box'"
|
||||
:style="{height: '100%'}">
|
||||
<div class="input-box" @click="dropDownVisible=false" v-if="plugins.indexOf('metric-input') > -1">
|
||||
<el-input v-model="expressionList[index]" @input="metricKeyDown" type="textarea" :maxlength="styleType === 3 ? 512 : 4096" show-word-limit
|
||||
:autosize="{ minRows: 1, maxRows: 6}" class="not-fixed-height no-resize" ref="elInput"></el-input>
|
||||
<div class="append-msg error" v-if="errorMsg"><span>{{errorMsg}}</span></div>
|
||||
<div class="append-msg error" v-if="appendMsg"><span>{{appendMsg}}</span></div>
|
||||
></div>
|
||||
<!-- <el-input
|
||||
v-model="expressionList[index]"
|
||||
@input="metricKeyDown"
|
||||
type="textarea"
|
||||
:maxlength="styleType === 3 ? 512 : 4096"
|
||||
show-word-limit
|
||||
:autosize="{ minRows: 1, maxRows: 6 }"
|
||||
class="not-fixed-height no-resize"
|
||||
ref="elInput"
|
||||
></el-input> -->
|
||||
<div class="append-msg error" v-if="errorMsg">
|
||||
<span>{{ errorMsg }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<div class="append-msg error" v-if="appendMsg">
|
||||
<span>{{ appendMsg }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="styleType == 2&&showRemove">
|
||||
<div class="option" @click="addExpression" v-if="plugins.indexOf('add') > -1"><i class="nz-icon nz-icon-plus"></i>
|
||||
<div v-if="styleType == 2 && showRemove">
|
||||
<div
|
||||
class="option"
|
||||
@click="addExpression"
|
||||
v-if="plugins.indexOf('add') > -1"
|
||||
>
|
||||
<i class="nz-icon nz-icon-plus"></i>
|
||||
</div>
|
||||
<div
|
||||
class="option"
|
||||
style="margin-left: 5px; line-height: 32px"
|
||||
@click="removeExpression"
|
||||
v-if="plugins.indexOf('remove') > -1"
|
||||
>
|
||||
<i class="nz-icon nz-icon-minus"></i>
|
||||
</div>
|
||||
<div class="option" style="margin-left: 5px; line-height: 32px;" @click="removeExpression"
|
||||
v-if="plugins.indexOf('remove') > -1"><i class="nz-icon nz-icon-minus"></i></div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
@@ -109,56 +277,141 @@
|
||||
:custom-class="'nz-temp-box'"
|
||||
:destroy-on-close="true"
|
||||
@closed="tempBoxClose"
|
||||
center>
|
||||
<el-form v-model="tempBox" class="temp-form-box" ref="tempFormBox" v-if="tempBoxShow">
|
||||
center
|
||||
>
|
||||
<el-form
|
||||
v-model="tempBox"
|
||||
class="temp-form-box"
|
||||
ref="tempFormBox"
|
||||
v-if="tempBoxShow"
|
||||
>
|
||||
<span class="temp-form-box-title">Expression</span>
|
||||
<el-form-item prop="expression">
|
||||
<el-input class="temp-form-box-input" v-model="tempBox.expression" size="small" disabled></el-input>
|
||||
<el-input
|
||||
class="temp-form-box-input"
|
||||
v-model="tempBox.expression"
|
||||
size="small"
|
||||
disabled
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<span class="temp-form-box-title" v-if="tempBox.vars.length">Variable</span>
|
||||
<el-form-item v-for="(item,index) in tempBox.vars" :prop="item" :key="index">
|
||||
<span class="temp-form-box-title" v-if="tempBox.vars.length"
|
||||
>Variable</span
|
||||
>
|
||||
<el-form-item
|
||||
v-for="(item, index) in tempBox.vars"
|
||||
:prop="item"
|
||||
:key="index"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="7" class="temp-form-box-col">
|
||||
<el-input class="temp-form-box-input" v-model="tempBox.vars[index]" :id="'tempBox'+index" size="small" :disabled="true"></el-input>
|
||||
<el-input
|
||||
class="temp-form-box-input"
|
||||
v-model="tempBox.vars[index]"
|
||||
:id="'tempBox' + index"
|
||||
size="small"
|
||||
:disabled="true"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :span="16" v-if="format(item).key">
|
||||
<select-alert-silence :filter-silence="filterSilence" :silence-data="format(item).arr" :panel-lock="false" :placement="'bottom-start'" :typeContentLoading="typeContentLoading"
|
||||
@selectSilence="(val)=>{silenceChange(val,item)}" ref="selectPanel" style="width: 240px;">
|
||||
<select-alert-silence
|
||||
:filter-silence="filterSilence"
|
||||
:silence-data="format(item).arr"
|
||||
:panel-lock="false"
|
||||
:placement="'bottom-start'"
|
||||
:typeContentLoading="typeContentLoading"
|
||||
@selectSilence="
|
||||
(val) => {
|
||||
silenceChange(val, item);
|
||||
}
|
||||
"
|
||||
ref="selectPanel"
|
||||
style="width: 240px"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<div class="explore-select-header">
|
||||
<el-input :placeholder="$t('overall.search')" clearable size="mini" style="width: 300px;padding: 0 10px;" v-model="filterSilence" id="panel-list-search"></el-input>
|
||||
<el-input
|
||||
:placeholder="$t('overall.search')"
|
||||
clearable
|
||||
size="mini"
|
||||
style="width: 300px; padding: 0 10px"
|
||||
v-model="filterSilence"
|
||||
id="panel-list-search"
|
||||
></el-input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:trigger>
|
||||
<el-input class="panel-name" placeholder="" readonly="readonly" v-model="tempBox[item]" size="small">
|
||||
<span slot="suffix" class="el-input__icon el-icon-circle-close el-input__clear" @click.stop="clearValue(item)"></span>
|
||||
<el-input
|
||||
class="panel-name"
|
||||
placeholder=""
|
||||
readonly="readonly"
|
||||
v-model="tempBox[item]"
|
||||
size="small"
|
||||
>
|
||||
<span
|
||||
slot="suffix"
|
||||
class="
|
||||
el-input__icon
|
||||
el-icon-circle-close
|
||||
el-input__clear
|
||||
"
|
||||
@click.stop="clearValue(item)"
|
||||
></span>
|
||||
</el-input>
|
||||
</template>
|
||||
</select-alert-silence>
|
||||
</el-col>
|
||||
<el-col :span="17" v-else>
|
||||
<el-input v-model="tempBox[item]" :id="'tempBox'+item" size="small"></el-input>
|
||||
<el-input
|
||||
v-model="tempBox[item]"
|
||||
:id="'tempBox' + item"
|
||||
size="small"
|
||||
></el-input>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer">
|
||||
<button id="temp-box-esc" class="nz-btn nz-btn-size-normal nz-btn-style-light" @click="tempBoxShowChange(false)">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
<button
|
||||
id="temp-box-esc"
|
||||
class="nz-btn nz-btn-size-normal nz-btn-style-light"
|
||||
@click="tempBoxShowChange(false)"
|
||||
>
|
||||
<span>{{ $t("overall.cancel") }}</span>
|
||||
</button>
|
||||
<button
|
||||
id="chart-box-save"
|
||||
v-has="`expressionTemplate_add`"
|
||||
:disabled="prevent_opt.save"
|
||||
class="nz-btn nz-btn-size-normal nz-btn-style-normal"
|
||||
@click="tempBoxShowChange(true)"
|
||||
>
|
||||
<span>{{ $t("overall.save") }}</span>
|
||||
</button>
|
||||
<button id="chart-box-save" v-has="`expressionTemplate_add`" :disabled="prevent_opt.save" class="nz-btn nz-btn-size-normal nz-btn-style-normal" @click="tempBoxShowChange(true)" >
|
||||
<span>{{$t('overall.save')}}</span>
|
||||
</button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import selectAlertSilence from '../../../common/alert/selectAlertSilence'
|
||||
import { get } from '@/http'
|
||||
import selectAlertSilence from '../../../common/alert/selectAlertSilence';
|
||||
import { get } from '@/http';
|
||||
import { PromQLExtension } from 'codemirror-promql';
|
||||
import { basicSetup } from '@codemirror/basic-setup';
|
||||
// import { EditorState } from '@codemirror/state';
|
||||
import { highlightSelectionMatches } from '@codemirror/search';
|
||||
import { EditorState, Prec, Compartment } from '@codemirror/state';
|
||||
import { indentOnInput, syntaxTree } from '@codemirror/language';
|
||||
import { EditorView , highlightSpecialChars, keymap, ViewUpdate, placeholder} from '@codemirror/view';
|
||||
import { history, historyKeymap } from '@codemirror/history';
|
||||
import { bracketMatching } from '@codemirror/matchbrackets';
|
||||
import { defaultKeymap, insertNewlineAndIndent } from '@codemirror/commands';
|
||||
import { commentKeymap } from '@codemirror/comment';
|
||||
import { lintKeymap } from '@codemirror/lint';
|
||||
import { baseTheme, lightTheme, darkTheme, promqlHighlighter } from './CMTheme.tsx';
|
||||
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
|
||||
import { autocompletion, completionKeymap, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
|
||||
export default {
|
||||
name: 'promqlInput',
|
||||
components: {
|
||||
@@ -262,6 +515,38 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
||||
let promQL = new PromQLExtension().setComplete(
|
||||
// {
|
||||
// remote: { url: 'https://prometheus.land' }
|
||||
// }
|
||||
)
|
||||
// const dynamicConfigCompartment = new Compartment();
|
||||
|
||||
new EditorView({
|
||||
state: EditorState.create({
|
||||
extensions: [
|
||||
baseTheme,
|
||||
highlightSpecialChars(),
|
||||
history(),
|
||||
indentOnInput(),
|
||||
bracketMatching(),
|
||||
closeBrackets(),
|
||||
autocompletion(),
|
||||
highlightSelectionMatches(),
|
||||
keymap.of([
|
||||
...closeBracketsKeymap,
|
||||
...defaultKeymap,
|
||||
...historyKeymap,
|
||||
...commentKeymap,
|
||||
...completionKeymap,
|
||||
...lintKeymap,
|
||||
]),
|
||||
placeholder('Expression (press Shift+Enter for newlines)'),
|
||||
basicSetup, promQL.asExtension()],
|
||||
}),
|
||||
parent: document.getElementById('editor')
|
||||
});
|
||||
if (!this.fromFatherData && this.type !== 'logs') {
|
||||
this.queryMetrics()
|
||||
}
|
||||
@@ -363,11 +648,13 @@ export default {
|
||||
this.cascaderValue = ''
|
||||
},
|
||||
metricKeyDown (val) {
|
||||
console.log(val);
|
||||
if (this.required) {
|
||||
this.metricChange(val)
|
||||
}
|
||||
},
|
||||
expressionChange: function () {
|
||||
console.log('expressionChange');
|
||||
this.$emit('change')
|
||||
},
|
||||
setError: function (errMsg) {
|
||||
@@ -642,19 +929,19 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.input-box .el-input__inner {
|
||||
height: 30px;
|
||||
}
|
||||
.nz-temp-box /deep/ .el-dialog__body{
|
||||
padding: 10px 20px 0 20px;
|
||||
}
|
||||
.nz-temp-box /deep/ .el-dialog__footer{
|
||||
margin-top: 0;
|
||||
}
|
||||
.nz-temp-box .nz-btn-style-light{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.nz-temp-box .nz-btn-style-normal{
|
||||
margin-left: 10px;
|
||||
}
|
||||
.input-box .el-input__inner {
|
||||
height: 30px;
|
||||
}
|
||||
.nz-temp-box /deep/ .el-dialog__body {
|
||||
padding: 10px 20px 0 20px;
|
||||
}
|
||||
.nz-temp-box /deep/ .el-dialog__footer {
|
||||
margin-top: 0;
|
||||
}
|
||||
.nz-temp-box .nz-btn-style-light {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.nz-temp-box .nz-btn-style-normal {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -77,9 +77,9 @@
|
||||
<el-dropdown-item v-has="'main_add'">
|
||||
<div id="chart-htmltopdf" @click="htmlToPdf"><i class="nz-icon nz-icon-export-pdf"></i>{{ $t('overall.downloadToPdf') }}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has="'main_add'">
|
||||
<div id="chart-htmltoData" @click="exportData"><i class="nz-icon nz-icon-download1"></i>{{ $t('overall.downloadToPdf') }}</div>
|
||||
</el-dropdown-item>
|
||||
<!-- <el-dropdown-item v-has="'main_add'">-->
|
||||
<!-- <div id="chart-htmltoData" @click="exportData"><i class="nz-icon nz-icon-download1"></i>{{ $t('overall.downloadToPdf') }}</div>-->
|
||||
<!-- </el-dropdown-item>-->
|
||||
</template>
|
||||
</top-tool-more-options>
|
||||
</div>
|
||||
@@ -823,7 +823,7 @@ export default {
|
||||
const dom = document.getElementsByClassName(this.pdfId)[0]
|
||||
if (dom) {
|
||||
// dom = dom.getElementsByClassName('vue-grid-layout')[0]
|
||||
this.htmlTitle = this.panel.name
|
||||
this.htmlTitle = this.showPanel.name
|
||||
this.scrollbarWrap.scrollTop = this.scrollbarWrap.scrollHeight
|
||||
this.$refs.chartList.onScroll(this.scrollbarWrap.scrollTop)
|
||||
// const div = document.createElement('div')
|
||||
|
||||
@@ -36,6 +36,18 @@ import myDatePicker from '@/components/common/myDatePicker'
|
||||
import vSelectPage from '@/components/common/v-selectpagenew'
|
||||
import nzDataList from '@/components/common/table/nzDataList'
|
||||
import htmlToPdf from '@/components/common/js/htmlToPdf'
|
||||
import { registerNode } from '@topology/core'
|
||||
import {
|
||||
myAnchors,
|
||||
myCubeAnchors,
|
||||
myCubec,
|
||||
myIconRect,
|
||||
myShape,
|
||||
myTextRect
|
||||
} from '@/components/common/project/L5/services/canvas'
|
||||
// 注册到画布
|
||||
registerNode('rectangleImg', myShape, myAnchors, myIconRect, myTextRect)
|
||||
registerNode('myCube', myCubec, myCubeAnchors, null, null)
|
||||
Vue.use(htmlToPdf)
|
||||
Vue.use(vSelectPage, {
|
||||
dataLoad: function (vue, url, params) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import user from './user'
|
||||
import panel from './panel'
|
||||
// import topology from './topology'
|
||||
|
||||
Vue.use(Vuex)
|
||||
const store = new Vuex.Store({
|
||||
|
||||
24
nezha-fronted/src/store/topology.js
Normal file
24
nezha-fronted/src/store/topology.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const topology = {
|
||||
state: {
|
||||
imgList: localStorage.getItem('nz-topology-imgList') || {}
|
||||
},
|
||||
mutations: {
|
||||
setImgList (state, imgList) {
|
||||
state.imgList = imgList
|
||||
},
|
||||
setImgListItem (state, item) {
|
||||
state.imgList[item.key] = item.img
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getImgList (state) {
|
||||
return state.imgList
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
dispatchAddImgList (store, obj) {
|
||||
store.commit('setImgListItem', obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
export default topology
|
||||
@@ -1,3 +1,7 @@
|
||||
module.exports = {
|
||||
get: jest.fn(() => Promise.resolve({ status: 200 }))
|
||||
get: jest.fn(() => Promise.resolve({ status: 200 })),
|
||||
post: jest.fn(() => Promise.resolve({ status: 200 })),
|
||||
put: jest.fn(() => Promise.resolve({ status: 200 })),
|
||||
del: jest.fn(() => Promise.resolve({ status: 200 })),
|
||||
requestsArr: []
|
||||
}
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
module.exports = 'test-file-stub';
|
||||
module.exports = {
|
||||
'test-file-stub': 'test-file-stub',
|
||||
getters: {},
|
||||
commit: ()=>{}
|
||||
}
|
||||
|
||||
3
nezha-fronted/test/unit/__mocks__/i18nMock.js
Normal file
3
nezha-fronted/test/unit/__mocks__/i18nMock.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
t: () => { return 'i18n' }
|
||||
}
|
||||
@@ -8,25 +8,39 @@ module.exports = {
|
||||
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
|
||||
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
|
||||
},
|
||||
// moduleFileExtensions: [
|
||||
// 'js',
|
||||
// 'json',
|
||||
// 'vue'
|
||||
// ],
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'json',
|
||||
'vue'
|
||||
],
|
||||
transformIgnorePatterns: ['/node_modules/(?!vue-awesome)', 'element-ui'],
|
||||
moduleNameMapper: {
|
||||
moduleNameMapper: { // 处理引入报错的文件 将其改为引入空文件 或者自定义的 function
|
||||
'element-ui/*': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
// 'libs/*': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/i18n': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
// 'libs/*': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'^@\/(.*?\.?(js|vue)?|)$': '<rootDir>/src/$1', // @路径转换,例如:@/components/Main.vue -> rootDir/src/components/Main.vue
|
||||
'css/font/*': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'store/*': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'elSelect/MyElSelect': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/chartList': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/myDatePicker/': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'v-selectpage/': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'@topology/': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/diagram': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/topology': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'@svgdotjs': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'@interactjs': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'pl-table': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/htmlToPdf': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'\/*\/http': '<rootDir>/test/unit/__mocks__/axios.js',
|
||||
// '\/*\/permission': '<rootDir>/test/unit/__mocks__/fileMock.js',
|
||||
'/i18n': '<rootDir>/test/unit/__mocks__/i18nMock.js',
|
||||
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/test/unit/__mocks__/fileMock.js', // 模拟加载静态文件
|
||||
'\\.(css|less|scss|sass)$': '<rootDir>/test/unit/__mocks__/styleMock.js' // 模拟加载样式文件
|
||||
'\\.(css|less|scss|sass)$': '<rootDir>/test/unit/__mocks__/styleMock.js', // 模拟加载样式文件
|
||||
'\\.(css|less|scss|sass|style)$': 'jest-css-modules',
|
||||
'^@\/(.*?\.?(js|vue)?|)$': '<rootDir>/src/$1' // @路径转换,例如:@/components/Main.vue -> rootDir/src/components/Main.vue
|
||||
},
|
||||
testMatch: [ // 匹配测试用例的文件
|
||||
'<rootDir>/test/unit/specs/*.spec.js',
|
||||
'<rootDir>/test/unit/specs/lib/*.spec.js',
|
||||
'<rootDir>/test/unit/specs/components/*.spec.js',
|
||||
'<rootDir>/test/unit/specs/components/*.spec.js'
|
||||
],
|
||||
moduleDirectories: [
|
||||
'node_modules'
|
||||
@@ -41,8 +55,9 @@ module.exports = {
|
||||
// 'test/unit/specs/*.(js)',
|
||||
'src/components/common/js/example.js',
|
||||
'src/libs/bus.js',
|
||||
'src/main.js',
|
||||
// 'src/components/common/js/tools.js',
|
||||
'!src/*.(js)',
|
||||
// '!src/*.(js)',
|
||||
'!src/http.js',
|
||||
'!src/router/index.js',
|
||||
'!**/node_modules/**'
|
||||
|
||||
17
nezha-fronted/test/unit/specs/main.spec.js
Normal file
17
nezha-fronted/test/unit/specs/main.spec.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import main from '@/main'
|
||||
import bus from '@/libs/bus'
|
||||
describe('时间函数', () => {
|
||||
// 测试代码可读性最好
|
||||
// 分组
|
||||
// const str = 'node_load1{module="node-exporter",endpoint_id="69",project="Common",datacenter="xin_xi_gang_DC",asset_id="11",endpoint="node-exporter-192.168.44.18",module_id="165",nz_agent_id="75",project_id="17",olap="node_exporter_nacos",asset="Bifang-CM-Server2",datacenter_id="4"} '
|
||||
// it('正常替换一个', () => {
|
||||
// expect(dealLegendAlias(str, '{{module}}')).toBe('node-exporter')
|
||||
// })
|
||||
|
||||
it('正常替换一个', () => {
|
||||
expect(main.utcTimeToTimezone(1650006960000)).toBe(1650006960000)
|
||||
})
|
||||
it('2', () => {
|
||||
expect(main.utcTimeToTimezone('2022-04-15 15:16:00')).toBe(1650006960000)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user