diff --git a/package-lock.json b/package-lock.json index a53afd05..217941fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,9 @@ "echarts": "^5.2.2", "element-plus": "^2.0.2", "lodash": "^4.17.21", + "monaco-editor": "^0.27.0", "pinia": "^2.0.5", + "vis-timeline": "^7.5.1", "vue": "^3.0.0", "vue-grid-layout": "^3.0.0-beta1", "vue-i18n": "^9.1.9", @@ -50,6 +52,7 @@ "eslint-plugin-vue": "^7.0.0", "husky": "^7.0.4", "lint-staged": "^12.1.3", + "monaco-editor-webpack-plugin": "^4.1.2", "node-sass": "^6.0.1", "postcss-html": "^1.3.0", "postcss-scss": "^4.0.2", @@ -1811,6 +1814,18 @@ "ms": "^2.1.1" } }, + "node_modules/@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "peer": true, + "dependencies": { + "@types/hammerjs": "^2.0.36" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/@element-plus/icons-vue": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-0.2.7.tgz", @@ -3300,6 +3315,12 @@ "@types/node": "*" } }, + "node_modules/@types/hammerjs": { + "version": "2.0.41", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", + "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==", + "peer": true + }, "node_modules/@types/http-proxy": { "version": "1.17.8", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", @@ -7882,8 +7903,7 @@ "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/compressible": { "version": "2.0.18", @@ -8695,6 +8715,12 @@ "node": ">=4" } }, + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==", + "peer": true + }, "node_modules/cssnano": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", @@ -11080,9 +11106,9 @@ } }, "node_modules/eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.1.tgz", + "integrity": "sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==", "dev": true, "dependencies": { "original": "^1.0.0" @@ -16438,6 +16464,12 @@ "node": ">=0.6.0" } }, + "node_modules/keycharm": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", + "peer": true + }, "node_modules/killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -18229,11 +18261,42 @@ "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", - "dev": true, "engines": { "node": "*" } }, + "node_modules/monaco-editor": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.27.0.tgz", + "integrity": "sha512-UhwP78Wb8w0ZSYoKXQNTV/0CHObp6NS3nCt51QfKE6sKyBo5PBsvuDOHoI2ooBakc6uIwByRLHVeT7+yXQe2fQ==" + }, + "node_modules/monaco-editor-webpack-plugin": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.1.2.tgz", + "integrity": "sha512-snmHecygICKT0UlHhva+Cs2WaLPpxy3111xbvInhjjTr5m0xQTFHlmJ2QQDcB14Vzmm7f07uc1TtbvOpmL50BA==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0" + }, + "peerDependencies": { + "monaco-editor": "0.25.x || 0.26.x || 0.27.x", + "webpack": "^4.5.0 || 5.x" + } + }, + "node_modules/monaco-editor-webpack-plugin/node_modules/loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -21698,6 +21761,15 @@ "node": ">= 6" } }, + "node_modules/propagating-hammerjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagating-hammerjs/-/propagating-hammerjs-2.0.1.tgz", + "integrity": "sha512-PH3zG5whbSxMocphXJzVtvKr+vWAgfkqVvtuwjSJ/apmEACUoiw6auBAT5HYXpZOR0eGcTAfYG5Yl8h91O5Elg==", + "peer": true, + "peerDependencies": { + "@egjs/hammerjs": "^2.0.17" + } + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -26837,7 +26909,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -26897,6 +26968,59 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "node_modules/vis-data": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.4.tgz", + "integrity": "sha512-usy+ePX1XnArNvJ5BavQod7YRuGQE1pjFl+pu7IS6rCom2EBoG0o1ZzCqf3l5US6MW51kYkLR+efxRbnjxNl7w==", + "hasInstallScript": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "uuid": "^7.0.0 || ^8.0.0", + "vis-util": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/vis-timeline": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/vis-timeline/-/vis-timeline-7.5.1.tgz", + "integrity": "sha512-XZMHHbA8xm9/Y/iu3mE9MT7J5tfWgbdsW+PmqrgINU2QRX24AiqifNHZHV4YYzeJstiTSOg9Gs5qRkxQ0BvZJw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "@egjs/hammerjs": "^2.0.0", + "component-emitter": "^1.3.0", + "keycharm": "^0.3.0 || ^0.4.0", + "moment": "^2.24.0", + "propagating-hammerjs": "^1.4.0 || ^2.0.0", + "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0", + "vis-data": "^6.3.0 || ^7.0.0", + "vis-util": "^3.0.0 || ^4.0.0 || ^5.0.0", + "xss": "^1.0.0" + } + }, + "node_modules/vis-util": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz", + "integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "@egjs/hammerjs": "^2.0.0", + "component-emitter": "^1.3.0" + } + }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -28745,6 +28869,28 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xss": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.13.tgz", + "integrity": "sha512-clu7dxTm1e8Mo5fz3n/oW3UCXBfV89xZ72jM8yzo1vR/pIS0w3sgB3XV2H8Vm6zfGnHL0FzvLJPJEBhd86/z4Q==", + "peer": true, + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/xss/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "peer": true + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -30199,6 +30345,15 @@ } } }, + "@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "peer": true, + "requires": { + "@types/hammerjs": "^2.0.36" + } + }, "@element-plus/icons-vue": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-0.2.7.tgz", @@ -31462,6 +31617,12 @@ "@types/node": "*" } }, + "@types/hammerjs": { + "version": "2.0.41", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", + "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==", + "peer": true + }, "@types/http-proxy": { "version": "1.17.8", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", @@ -35153,8 +35314,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "compressible": { "version": "2.0.18", @@ -35795,6 +35955,12 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==", + "peer": true + }, "cssnano": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", @@ -37656,9 +37822,9 @@ "dev": true }, "eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.1.tgz", + "integrity": "sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==", "dev": true, "requires": { "original": "^1.0.0" @@ -41882,6 +42048,12 @@ "verror": "1.10.0" } }, + "keycharm": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", + "peer": true + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -43268,8 +43440,34 @@ "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", - "dev": true + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "monaco-editor": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.27.0.tgz", + "integrity": "sha512-UhwP78Wb8w0ZSYoKXQNTV/0CHObp6NS3nCt51QfKE6sKyBo5PBsvuDOHoI2ooBakc6uIwByRLHVeT7+yXQe2fQ==" + }, + "monaco-editor-webpack-plugin": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.1.2.tgz", + "integrity": "sha512-snmHecygICKT0UlHhva+Cs2WaLPpxy3111xbvInhjjTr5m0xQTFHlmJ2QQDcB14Vzmm7f07uc1TtbvOpmL50BA==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0" + }, + "dependencies": { + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } }, "move-concurrently": { "version": "1.0.1", @@ -45934,6 +46132,13 @@ "sisteransi": "^1.0.5" } }, + "propagating-hammerjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagating-hammerjs/-/propagating-hammerjs-2.0.1.tgz", + "integrity": "sha512-PH3zG5whbSxMocphXJzVtvKr+vWAgfkqVvtuwjSJ/apmEACUoiw6auBAT5HYXpZOR0eGcTAfYG5Yl8h91O5Elg==", + "peer": true, + "requires": {} + }, "proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -50035,8 +50240,7 @@ "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", @@ -50085,6 +50289,26 @@ } } }, + "vis-data": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.4.tgz", + "integrity": "sha512-usy+ePX1XnArNvJ5BavQod7YRuGQE1pjFl+pu7IS6rCom2EBoG0o1ZzCqf3l5US6MW51kYkLR+efxRbnjxNl7w==", + "peer": true, + "requires": {} + }, + "vis-timeline": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/vis-timeline/-/vis-timeline-7.5.1.tgz", + "integrity": "sha512-XZMHHbA8xm9/Y/iu3mE9MT7J5tfWgbdsW+PmqrgINU2QRX24AiqifNHZHV4YYzeJstiTSOg9Gs5qRkxQ0BvZJw==", + "requires": {} + }, + "vis-util": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz", + "integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==", + "peer": true, + "requires": {} + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -51596,6 +51820,24 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xss": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.13.tgz", + "integrity": "sha512-clu7dxTm1e8Mo5fz3n/oW3UCXBfV89xZ72jM8yzo1vR/pIS0w3sgB3XV2H8Vm6zfGnHL0FzvLJPJEBhd86/z4Q==", + "peer": true, + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "peer": true + } + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index ece16b3a..040092aa 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ "echarts": "^5.2.2", "element-plus": "^2.0.2", "lodash": "^4.17.21", + "monaco-editor": "^0.27.0", "pinia": "^2.0.5", + "vis-timeline": "^7.5.1", "vue": "^3.0.0", "vue-grid-layout": "^3.0.0-beta1", "vue-i18n": "^9.1.9", @@ -52,6 +54,7 @@ "eslint-plugin-vue": "^7.0.0", "husky": "^7.0.4", "lint-staged": "^12.1.3", + "monaco-editor-webpack-plugin": "^4.1.2", "node-sass": "^6.0.1", "postcss-html": "^1.3.0", "postcss-scss": "^4.0.2", diff --git a/src/assets/icons/add_fill.svg b/src/assets/icons/add_fill.svg new file mode 100644 index 00000000..5285acaa --- /dev/null +++ b/src/assets/icons/add_fill.svg @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/assets/icons/demand.svg b/src/assets/icons/demand.svg new file mode 100644 index 00000000..4b1b60db --- /dev/null +++ b/src/assets/icons/demand.svg @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/assets/icons/event.svg b/src/assets/icons/event.svg new file mode 100644 index 00000000..93bf25ec --- /dev/null +++ b/src/assets/icons/event.svg @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/constants/data.ts b/src/constants/data.ts index 5a8bf137..33779df9 100644 --- a/src/constants/data.ts +++ b/src/constants/data.ts @@ -28,15 +28,26 @@ export const Languages = [ export const RoutesMap: { [key: string]: string } = { GeneralServices: "GENERAL", + GeneralServicesActiveTabIndex: "GENERAL", Database: "VIRTUAL_DATABASE", + DatabaseActiveTabIndex: "VIRTUAL_DATABASE", MeshServices: "MESH", + MeshServicesActiveTabIndex: "MESH", ControlPanel: "MESH_CP", + ControlPanelActiveTabIndex: "MESH_CP", DataPanel: "MESH_DP", + DataPanelActiveTabIndex: "MESH_DP", Linux: "OS_LINUX", SkyWalkingServer: "SO11Y_OAP", + SkyWalkingServerActiveTabIndex: "SO11Y_OAP", + SatelliteActiveTabIndex: "SO11Y_SATELLITE", Satellite: "SO11Y_SATELLITE", Functions: "FAAS", + FunctionsActiveTabIndex: "FAAS", Browser: "BROWSER", + BrowserActiveTabIndex: "BROWSER", KubernetesCluster: "K8S", + KubernetesClusterActiveTabIndex: "K8S", KubernetesService: "K8S_SERVICE", + KubernetesServiceActiveTabIndex: "K8S_SERVICE", }; diff --git a/src/graphql/fragments/demand-log.ts b/src/graphql/fragments/demand-log.ts new file mode 100644 index 00000000..3579f8c5 --- /dev/null +++ b/src/graphql/fragments/demand-log.ts @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const queryContainers = { + variable: "$condition: OndemandContainergQueryCondition!", + query: ` + containers: listContainers(condition: $condition) { + errorReason + containers + }`, +}; + +export const queryStreamingLogs = { + variable: "$condition: OndemandLogQueryCondition", + query: ` + logs: ondemandPodLogs(condition: $condition) { + errorReason + logs { + content + } + }`, +}; diff --git a/src/graphql/index.ts b/src/graphql/index.ts index 6028e19e..b238336d 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -26,6 +26,7 @@ import * as profile from "./query/profile"; import * as alarm from "./query/alarm"; import * as event from "./query/event"; import * as ebpf from "./query/ebpf"; +import * as demandLog from "./query/demand-log"; const query: { [key: string]: string } = { ...app, @@ -38,6 +39,7 @@ const query: { [key: string]: string } = { ...alarm, ...event, ...ebpf, + ...demandLog, }; class Graphql { private queryData = ""; diff --git a/src/graphql/query/demand-log.ts b/src/graphql/query/demand-log.ts new file mode 100644 index 00000000..94fd1432 --- /dev/null +++ b/src/graphql/query/demand-log.ts @@ -0,0 +1,22 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { queryContainers, queryStreamingLogs } from "../fragments/demand-log"; + +export const fetchContainers = `query listContainers(${queryContainers.variable}) {${queryContainers.query}}`; + +export const fetchDemandPodLogs = `query ondemandPodLogs(${queryStreamingLogs.variable}) {${queryStreamingLogs.query}}`; diff --git a/src/hooks/useEcharts.ts b/src/hooks/useEcharts.ts index 16b505b2..01f7d7ed 100644 --- a/src/hooks/useEcharts.ts +++ b/src/hooks/useEcharts.ts @@ -79,7 +79,11 @@ export function useECharts( if (!el || !unref(el)) { return; } + const { width, height } = el.getBoundingClientRect(); + if (!width || !height) { + return; + } chartInstance = echarts.init(el, t); const { removeEvent } = useEventListener({ el: window, diff --git a/src/layout/components/SideBar.vue b/src/layout/components/SideBar.vue index 34ad6852..44392bc4 100644 --- a/src/layout/components/SideBar.vue +++ b/src/layout/components/SideBar.vue @@ -55,9 +55,9 @@ limitations under the License. --> - {{ t(m.meta.title) }} + {{ m.meta && t(m.meta.title) }} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 7f55d4a0..8c62373e 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -136,7 +136,13 @@ const msg = { targetType: "Target Type", ebpfTip: "Don't have a process for profiling", processSelect: "Click to select processes", + container: "Container", + limit: "Limit", page: "Page", + interval: "Refresh Interval", + pause: "Pause", + begin: "Start", + seconds: "Seconds", hourTip: "Select Hour", minuteTip: "Select Minute", secondTip: "Select Second", @@ -155,7 +161,7 @@ const msg = { dashboard: "Dashboard", topology: "Topology", trace: "Trace", - alarm: "Alarms", + alarm: "Alerting", auto: "Auto", reload: "Reload", version: "Version", diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts index 40ef1fda..794980e0 100644 --- a/src/locales/lang/es.ts +++ b/src/locales/lang/es.ts @@ -74,8 +74,10 @@ const msg = { editGraph: "Editar Opciones", dashboardName: "Selecciona Nombre del Panel", linkDashboard: "Nombre del panel relacionado con llamadas de la topología", - linkServerMetrics: "Métricas de servidor relacionadas con llamadas de la topología", - linkClientMetrics: "Métricas de cliente relacionadas con llamadas de la topología", + linkServerMetrics: + "Métricas de servidor relacionadas con llamadas de la topología", + linkClientMetrics: + "Métricas de cliente relacionadas con llamadas de la topología", nodeDashboard: "Nombre del panel relacionado con nodos de la topología", nodeMetrics: "Mêtricas relacionas con nodos de la topología", instanceDashboard: "Nombre del panel relacionado con instancias de servicio", @@ -137,6 +139,10 @@ const msg = { ebpfTip: "Le falta el proceso para perfilar", processSelect: "Click para seleccionar proceso", page: "Página", + interval: "Intervalo de actualización", + pause: "Pausa", + begin: "Inicio", + seconds: "Segundos", hourTip: "Seleccione Hora", minuteTip: "Seleccione Minuto", secondTip: "Seleccione Segundo", @@ -155,7 +161,7 @@ const msg = { dashboard: "Panel", topology: "Topología", trace: "Traza", - alarm: "Alarmas", + alarm: "Recordatorio en curso", auto: "Auto", reload: "Recargar", version: "Versión", @@ -303,7 +309,8 @@ const msg = { destEndpoint: "Endpoint Destinación", eventSource: "Fuente Envento", modalTitle: "Inspección", - selectRedirectPage: "Quiere inspeccionar las Trazas or Registros de datos del servicio %s?", + selectRedirectPage: + "Quiere inspeccionar las Trazas or Registros de datos del servicio %s?", logAnalysis: "Lenguaje de Análisis de Registro de Datos", logDataBody: "Contenido del Registro de Datos", addType: "Por favor introduzca un tipo", @@ -324,8 +331,10 @@ const msg = { addTraceID: "Por favor introduzca el ID de la traza", addTags: "Por favor introduzaca una etiqueta", addKeywordsOfContent: "Por favor introduzca una clave de contenido", - addExcludingKeywordsOfContent: "Por favor introduzca una clave excluyente de contenido", - noticeTag: "Por favor presione Intro después de introducir una etiqueta(clave=valor).", + addExcludingKeywordsOfContent: + "Por favor introduzca una clave excluyente de contenido", + noticeTag: + "Por favor presione Intro después de introducir una etiqueta(clave=valor).", conditionNotice: "Aviso: Por favor presione Intro después de introducir una clave de contenido, excluir clave de contenido(clave=valor).", language: "Lenguaje", diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index 88af9d13..10d8837a 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -134,7 +134,13 @@ const msg = { targetType: "目标类型", processSelect: "点击选择进程", ebpfTip: "没有进程可以分析", + container: "容器", + limit: "范围", page: "页面", + interval: "刷新间隔时间", + pause: "暂停", + begin: "开始", + seconds: "秒", hourTip: "选择小时", minuteTip: "选择分钟", secondTip: "选择秒数", diff --git a/src/router/alarm.ts b/src/router/alarm.ts index 6880e099..debaa61a 100644 --- a/src/router/alarm.ts +++ b/src/router/alarm.ts @@ -30,13 +30,13 @@ export const routesAlarm: Array = [ component: Layout, children: [ { - path: "/alarm", + path: "/alerting", name: "Alarm", meta: { exact: false, }, component: () => - import(/* webpackChunkName: "alarms" */ "@/views/Alarm.vue"), + import(/* webpackChunkName: "alerting" */ "@/views/Alarm.vue"), }, ], }, diff --git a/src/router/browser.ts b/src/router/browser.ts index e0633bb6..a7a4eb20 100644 --- a/src/router/browser.ts +++ b/src/router/browser.ts @@ -33,12 +33,20 @@ export const routesBrowser: Array = [ name: "Browser", meta: { title: "browser", - headPath: "/browser", exact: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/browser/tab/:activeTabIndex", + name: "BrowserActiveTabIndex", + meta: { + notShow: true, + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, ], }, ]; diff --git a/src/router/dashboard.ts b/src/router/dashboard.ts index 93fc53ac..c985e2fc 100644 --- a/src/router/dashboard.ts +++ b/src/router/dashboard.ts @@ -54,69 +54,156 @@ export const routesDashboard: Array = [ }, }, { - path: "/dashboard/:layerId/:entity/:name", + path: "", + redirect: "/dashboard/:layerId/:entity/:name", + name: "Create", component: () => import( /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" ), - name: "Create", meta: { - title: "dashboardEdit", - exact: false, notShow: true, }, + children: [ + { + path: "/dashboard/:layerId/:entity/:name", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "CreateChild", + }, + { + path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "CreateActiveTabIndex", + }, + ], }, { - path: "/dashboard/:layerId/:entity/:serviceId/:name", + path: "", component: () => import( /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" ), name: "View", + redirect: "/dashboard/:layerId/:entity/:serviceId/:name", meta: { - title: "dashboardEdit", - exact: false, notShow: true, }, + children: [ + { + path: "/dashboard/:layerId/:entity/:serviceId/:name", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewChild", + }, + { + path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewActiveTabIndex", + }, + ], }, { - path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", + path: "", + redirect: + "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", component: () => import( /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" ), name: "ViewServiceRelation", meta: { - title: "dashboardEdit", - exact: false, notShow: true, }, + children: [ + { + path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewServiceRelation", + }, + { + path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewServiceRelationActiveTabIndex", + }, + ], }, { - path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", + path: "", + redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", component: () => import( /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" ), name: "ViewPod", meta: { - title: "dashboardEdit", - exact: false, notShow: true, }, + children: [ + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewPod", + }, + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewPodActiveTabIndex", + }, + ], }, { - path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", + path: "", + redirect: + "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", component: () => import( /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" ), name: "ViewPodRelation", meta: { - title: "dashboardEdit", - exact: true, notShow: true, }, + children: [ + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewPodRelation", + }, + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex", + component: () => + import( + /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue" + ), + name: "ViewPodRelationActiveTabIndex", + }, + ], }, ], }, diff --git a/src/router/database.ts b/src/router/database.ts index 7dc0653c..70b82b35 100644 --- a/src/router/database.ts +++ b/src/router/database.ts @@ -34,12 +34,20 @@ export const routesDatabase: Array = [ name: "Database", meta: { title: "virtualDatabase", - headPath: "/database", exact: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/database/tab/:activeTabIndex", + name: "DatabaseActiveTabIndex", + meta: { + notShow: true, + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, ], }, ]; diff --git a/src/router/functions.ts b/src/router/functions.ts index be1fa338..ddafec92 100644 --- a/src/router/functions.ts +++ b/src/router/functions.ts @@ -32,13 +32,17 @@ export const routesFunctions: Array = [ path: "/functions", name: "Functions", meta: { - title: "functions", - headPath: "/functions", exact: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/functions/tab/:activeTabIndex", + name: "FunctionsActiveTabIndex", + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, ], }, ]; diff --git a/src/router/general.ts b/src/router/general.ts index 393b94f3..e9bb7b8f 100644 --- a/src/router/general.ts +++ b/src/router/general.ts @@ -33,8 +33,15 @@ export const routesGen: Array = [ path: "/general", name: "GeneralServices", meta: { - title: "services", - headPath: "/general/service", + exact: true, + }, + component: () => + import(/* webpackChunkName: "layers" */ "@/views/Layer.vue"), + }, + { + path: "/general/tab/:activeTabIndex", + name: "GeneralServicesActiveTabIndex", + meta: { exact: true, }, component: () => diff --git a/src/router/index.ts b/src/router/index.ts index da15693d..b4a57531 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -20,7 +20,6 @@ import { routesMesh } from "./serviceMesh"; import { routesDatabase } from "./database"; import { routesInfra } from "./infrastructure"; import { routesDashboard } from "./dashboard"; -import { routesEvent } from "./event"; import { routesSetting } from "./setting"; import { routesAlarm } from "./alarm"; import { routesSelf } from "./selfObservability"; @@ -39,7 +38,6 @@ const routes: Array = [ ...routesSelf, ...routesDashboard, ...routesAlarm, - ...routesEvent, ...routesSetting, ]; diff --git a/src/router/infrastructure.ts b/src/router/infrastructure.ts index 86bb55ee..fbd38580 100644 --- a/src/router/infrastructure.ts +++ b/src/router/infrastructure.ts @@ -39,6 +39,16 @@ export const routesInfra: Array = [ component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/linux/tab/:activeTabIndex", + name: "LinuxActiveTabIndex", + meta: { + title: "linux", + notShow: true, + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, // { // path: "/infrastructure/vm", // name: "VirtualMachine", diff --git a/src/router/k8s.ts b/src/router/k8s.ts index 38adf3f7..a9390bd8 100644 --- a/src/router/k8s.ts +++ b/src/router/k8s.ts @@ -33,20 +33,42 @@ export const routesK8s: Array = [ path: "/kubernetes/cluster", name: "KubernetesCluster", meta: { + notShow: false, title: "kubernetesCluster", }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/kubernetes/cluster/tab/:activeTabIndex", + name: "KubernetesClusterActiveTabIndex", + meta: { + notShow: true, + title: "kubernetesClusterActiveTabIndex", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, { path: "/kubernetes/service", name: "KubernetesService", meta: { + notShow: false, title: "kubernetesService", }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, + { + path: "/kubernetes/service/tab/:activeTabIndex", + name: "KubernetesServiceActiveTabIndex", + meta: { + notShow: true, + title: "kubernetesServiceActiveTabIndex", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, ], }, ]; diff --git a/src/router/selfObservability.ts b/src/router/selfObservability.ts index 4174e1bb..b2e610b1 100644 --- a/src/router/selfObservability.ts +++ b/src/router/selfObservability.ts @@ -34,7 +34,15 @@ export const routesSelf: Array = [ name: "SkyWalkingServer", meta: { title: "skyWalkingServer", - headPath: "/mesh/services", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, + { + path: "/self/skyWalkingServer/tab/:activeTabIndex", + name: "SkyWalkingServerActiveTabIndex", + meta: { + notShow: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), @@ -44,7 +52,15 @@ export const routesSelf: Array = [ name: "Satellite", meta: { title: "satellite", - headPath: "/mesh/controlPanel", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, + { + path: "/self/satellite/tab/:activeTabIndex", + name: "SatelliteActiveTabIndex", + meta: { + notShow: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), diff --git a/src/router/serviceMesh.ts b/src/router/serviceMesh.ts index 719fae43..04df1bb2 100644 --- a/src/router/serviceMesh.ts +++ b/src/router/serviceMesh.ts @@ -33,8 +33,17 @@ export const routesMesh: Array = [ path: "/mesh/services", name: "MeshServices", meta: { + notShow: false, title: "services", - headPath: "/mesh/services", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, + { + path: "/mesh/services/tab/:activeTabIndex", + name: "MeshServicesActiveTabIndex", + meta: { + notShow: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), @@ -43,8 +52,17 @@ export const routesMesh: Array = [ path: "/mesh/controlPanel", name: "ControlPanel", meta: { + notShow: false, title: "controlPanel", - headPath: "/mesh/controlPanel", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, + { + path: "/mesh/controlPanel/tab/:activeTabIndex", + name: "ControlPanelActiveTabIndex", + meta: { + notShow: true, }, component: () => import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), @@ -53,10 +71,21 @@ export const routesMesh: Array = [ path: "/mesh/dataPanel", name: "DataPanel", meta: { + notShow: false, title: "dataPanel", - headPath: "/mesh/dataPanel", }, - component: () => import("@/views/Layer.vue"), + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), + }, + { + path: "/mesh/dataPanel/tab/:activeTabIndex", + name: "DataPanelActiveTabIndex", + meta: { + notShow: true, + title: "dataPanelActiveTabIndex", + }, + component: () => + import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"), }, ], }, diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index e3121c0a..4fd8fe82 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -34,6 +34,7 @@ interface AppState { pageTitle: string; version: string; isMobile: boolean; + reloadTimer: Nullable; } export const appStore = defineStore({ @@ -53,6 +54,7 @@ export const appStore = defineStore({ pageTitle: "", version: "", isMobile: false, + reloadTimer: null, }), getters: { duration(): Duration { @@ -173,6 +175,9 @@ export const appStore = defineStore({ this.version = res.data.data.version; return res.data; }, + setReloadTimer(timer: any): void { + this.reloadTimer = timer; + }, }, }); export function useAppStoreWithOut(): any { diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts index 2ed20f17..d324b4c8 100644 --- a/src/store/modules/dashboard.ts +++ b/src/store/modules/dashboard.ts @@ -110,12 +110,7 @@ export const dashboardStore = defineStore({ : 3, }; } - if ( - type === "Trace" || - type === "Profile" || - type === "Log" || - type === "Ebpf" - ) { + if (["Trace", "Profile", "Log", "DemandLog", "Ebpf"].includes(type)) { newItem.h = 36; } if (type === "Text") { @@ -170,7 +165,7 @@ export const dashboardStore = defineStore({ showDepth: true, }; } - if (type === "Trace" || type === "Profile" || type === "Log") { + if (["Trace", "Profile", "Log", "DemandLog", "Ebpf"].includes(type)) { newItem.h = 32; } if (type === "Text") { diff --git a/src/store/modules/demand-log.ts b/src/store/modules/demand-log.ts new file mode 100644 index 00000000..3aa37ac7 --- /dev/null +++ b/src/store/modules/demand-log.ts @@ -0,0 +1,126 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { defineStore } from "pinia"; +import { Instance } from "@/types/selector"; +import { store } from "@/store"; +import graphql from "@/graphql"; +import { AxiosResponse } from "axios"; +import { useAppStoreWithOut } from "@/store/modules/app"; +import { useSelectorStore } from "@/store/modules/selectors"; +import { Conditions, Log } from "@/types/demand-log"; + +interface DemandLogState { + containers: Instance[]; + instances: Instance[]; + conditions: Conditions; + selectorStore: any; + logs: Log[]; + loadLogs: boolean; + message: string; + total: number; +} + +export const demandLogStore = defineStore({ + id: "demandLog", + state: (): DemandLogState => ({ + containers: [{ label: "", value: "" }], + instances: [{ value: "", label: "" }], + conditions: { + container: "", + serviceInstanceId: "", + duration: useAppStoreWithOut().durationTime, + }, + selectorStore: useSelectorStore(), + logs: [], + loadLogs: false, + message: "", + total: 0, + }), + actions: { + setLogCondition(data: Conditions) { + this.conditions = { ...this.conditions, ...data }; + }, + setLogs(logs: Log[], message?: string) { + this.logs = logs; + this.message = message || ""; + }, + async getInstances(id: string) { + const serviceId = this.selectorStore.currentService + ? this.selectorStore.currentService.id + : id; + const res: AxiosResponse = await graphql.query("queryInstances").params({ + serviceId, + duration: useAppStoreWithOut().durationTime, + }); + + if (res.data.errors) { + return res.data; + } + this.instances = res.data.data.pods || []; + return res.data; + }, + async getContainers(serviceInstanceId: string) { + if (!serviceInstanceId) { + return new Promise((resolve) => + resolve({ errors: "No service instance" }) + ); + } + const condition = { + serviceInstanceId, + }; + const res: AxiosResponse = await graphql + .query("fetchContainers") + .params({ condition }); + + if (res.data.errors) { + return res.data; + } + if (res.data.data.containers.errorReason) { + this.containers = [{ label: "", value: "" }]; + return res.data; + } + this.containers = res.data.data.containers.containers.map((d: string) => { + return { label: d, value: d }; + }); + return res.data; + }, + async getDemandLogs() { + this.loadLogs = true; + const res: AxiosResponse = await graphql + .query("fetchDemandPodLogs") + .params({ condition: this.conditions }); + this.loadLogs = false; + if (res.data.errors) { + return res.data; + } + if (res.data.data.logs.errorReason) { + this.setLogs("", res.data.data.logs.errorReason); + return res.data; + } + this.total = res.data.data.logs.logs.length; + const logs = res.data.data.logs.logs + .map((d: Log) => d.content) + .join("\n"); + this.setLogs(logs); + return res.data; + }, + }, +}); + +export function useDemandLogStore(): any { + return demandLogStore(store); +} diff --git a/src/store/modules/ebpf.ts b/src/store/modules/ebpf.ts index f43c649f..987422b8 100644 --- a/src/store/modules/ebpf.ts +++ b/src/store/modules/ebpf.ts @@ -35,6 +35,7 @@ interface EbpfStore { couldProfiling: boolean; tip: string; selectedTask: Recordable; + aggregateType: string; } export const ebpfStore = defineStore({ @@ -48,6 +49,7 @@ export const ebpfStore = defineStore({ couldProfiling: false, tip: "", selectedTask: {}, + aggregateType: "COUNT", }), actions: { setSelectedTask(task: EBPFTaskList) { @@ -131,6 +133,7 @@ export const ebpfStore = defineStore({ timeRanges: Array<{ start: number; end: number }>; aggregateType: string; }) { + this.aggregateType = params.aggregateType; if (!params.scheduleIdList.length) { return new Promise((resolve) => resolve({})); } diff --git a/src/store/modules/event.ts b/src/store/modules/event.ts index 01b6788a..fed1fa74 100644 --- a/src/store/modules/event.ts +++ b/src/store/modules/event.ts @@ -19,16 +19,16 @@ import { store } from "@/store"; import graphql from "@/graphql"; import { AxiosResponse } from "axios"; import { Event, QueryEventCondition } from "@/types/events"; -import { Instance, Endpoint, Service } from "@/types/selector"; +import { Instance, Endpoint } from "@/types/selector"; import { useAppStoreWithOut } from "@/store/modules/app"; +import { useSelectorStore } from "@/store/modules/selectors"; interface eventState { loading: boolean; events: Event[]; - services: Service[]; instances: Instance[]; endpoints: Endpoint[]; - condition: QueryEventCondition | any; + condition: Nullable; } export const eventStore = defineStore({ @@ -36,32 +36,18 @@ export const eventStore = defineStore({ state: (): eventState => ({ loading: false, events: [], - services: [{ value: "", label: "All" }], instances: [{ value: "", label: "All" }], endpoints: [{ value: "", label: "All" }], - condition: { - paging: { pageNum: 1, pageSize: 15 }, - }, + condition: null, }), actions: { - setEventCondition(data: any) { - this.condition = { ...this.condition, ...data }; + setEventCondition(data: QueryEventCondition) { + this.condition = data; }, - async getServices(layer: string) { - if (!layer) { - this.services = [{ value: "", label: "All" }]; - return new Promise((resolve) => resolve([])); - } - const res: AxiosResponse = await graphql.query("queryServices").params({ - layer, - }); - if (res.data.errors) { - return res.data; - } - this.services = res.data.data.services; - return res.data; - }, - async getInstances(serviceId: string) { + async getInstances() { + const serviceId = useSelectorStore().currentService + ? useSelectorStore().currentService.id + : ""; const res: AxiosResponse = await graphql.query("queryInstances").params({ serviceId, duration: useAppStoreWithOut().durationTime, @@ -75,7 +61,13 @@ export const eventStore = defineStore({ ]; return res.data; }, - async getEndpoints(serviceId: string) { + async getEndpoints() { + const serviceId = useSelectorStore().currentService + ? useSelectorStore().currentService.id + : ""; + if (!serviceId) { + return; + } const res: AxiosResponse = await graphql.query("queryEndpoints").params({ serviceId, duration: useAppStoreWithOut().durationTime, diff --git a/src/store/modules/log.ts b/src/store/modules/log.ts index ce1674d1..241297de 100644 --- a/src/store/modules/log.ts +++ b/src/store/modules/log.ts @@ -53,6 +53,12 @@ export const logStore = defineStore({ setLogCondition(data: any) { this.conditions = { ...this.conditions, ...data }; }, + resetCondition() { + this.conditions = { + queryDuration: useAppStoreWithOut().durationTime, + paging: { pageNum: 1, pageSize: 15 }, + }; + }, async getServices(layer: string) { const res: AxiosResponse = await graphql.query("queryServices").params({ layer, diff --git a/src/styles/reset.scss b/src/styles/reset.scss index 9a95d713..5d732b30 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss @@ -154,3 +154,38 @@ pre { .switch { margin: 0 5px; } + +div.vis-tooltip { + max-width: 600px; + overflow: hidden; + background-color: #fff !important; + white-space: normal !important; + font-size: 12px !important; +} + +.vis-item { + cursor: pointer; + height: 17px; +} + +.vis-item.Error { + background-color: #e66; + opacity: 0.8; + border-color: #e66; + color: #fff !important; +} + +.vis-item.Normal { + background-color: #fac858; + border-color: #fac858; + color: #666 !important; +} + +.vis-item .vis-item-content { + padding: 0 5px !important; +} + +.vis-item.vis-selected.Error, +.vis-item.vis-selected.Normal { + color: #1a1a1a !important; +} diff --git a/src/types/app.d.ts b/src/types/app.d.ts index 74e69c32..ee35299a 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -28,3 +28,7 @@ export interface DurationTime { end: string; step: string; } +export type Paging = { + pageNum: number; + pageSize: number; +}; diff --git a/src/types/demand-log.ts b/src/types/demand-log.ts new file mode 100644 index 00000000..44a24ab7 --- /dev/null +++ b/src/types/demand-log.ts @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { DurationTime } from "./app"; + +export interface Conditions { + container: string; + serviceInstanceId: string; + duration: DurationTime; + keywordsOfContent?: string[]; + excludingKeywordsOfContent?: string; +} + +export interface Log { + content: string; + timestamp: number; + contentType: string; +} diff --git a/src/types/ebpf.d.ts b/src/types/ebpf.d.ts index 4598528e..40852074 100644 --- a/src/types/ebpf.d.ts +++ b/src/types/ebpf.d.ts @@ -65,6 +65,8 @@ export type StackElement = { stackType: string; value: number; children?: StackElement[]; + rateOfRoot?: string; + rateOfParent: string; }; export type AnalyzationTrees = { id: string; diff --git a/src/types/monaco-editor.ts b/src/types/monaco-editor.ts new file mode 100644 index 00000000..0e7645a5 --- /dev/null +++ b/src/types/monaco-editor.ts @@ -0,0 +1,17 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +declare module "monaco-editor"; diff --git a/src/types/trace.d.ts b/src/types/trace.d.ts index 82e0f669..569e7173 100644 --- a/src/types/trace.d.ts +++ b/src/types/trace.d.ts @@ -46,8 +46,15 @@ export interface Span { children?: Span[]; tags?: Array>; logs?: log[]; + parentSegmentId?: string; + refs?: Ref[]; } - +export type Ref = { + type: string; + parentSegmentId: string; + parentSpanId: number; + traceId: string; +}; export interface log { time: number; data: Map; diff --git a/src/views/Alarm.vue b/src/views/Alarm.vue index 87a33ef5..88c00fe9 100644 --- a/src/views/Alarm.vue +++ b/src/views/Alarm.vue @@ -24,7 +24,7 @@ import Header from "./alarm/Header.vue"; import Content from "./alarm/Content.vue"; const appStore = useAppStoreWithOut(); -appStore.setPageTitle("Alarm"); +appStore.setPageTitle("Alerting"); diff --git a/src/views/dashboard/controls/Ebpf.vue b/src/views/dashboard/controls/Ebpf.vue index 78f67ef7..2f4f53e2 100644 --- a/src/views/dashboard/controls/Ebpf.vue +++ b/src/views/dashboard/controls/Ebpf.vue @@ -29,7 +29,7 @@ limitations under the License. --> {{ t("delete") }} -
+
@@ -47,6 +47,7 @@ const props = defineProps({ default: () => ({ graph: {} }), }, activeIndex: { type: String, default: "" }, + needQuery: { type: Boolean, default: true }, }); const { t } = useI18n(); const dashboardStore = useDashboardStore(); diff --git a/src/views/dashboard/controls/Event.vue b/src/views/dashboard/controls/Event.vue new file mode 100644 index 00000000..e510a138 --- /dev/null +++ b/src/views/dashboard/controls/Event.vue @@ -0,0 +1,102 @@ + + + + diff --git a/src/views/dashboard/controls/Log.vue b/src/views/dashboard/controls/Log.vue index ea80a786..0d6708ef 100644 --- a/src/views/dashboard/controls/Log.vue +++ b/src/views/dashboard/controls/Log.vue @@ -30,7 +30,7 @@ limitations under the License. -->
-
+
@@ -50,6 +50,7 @@ const props = defineProps({ default: () => ({}), }, activeIndex: { type: String, default: "" }, + needQuery: { type: Boolean, default: true }, }); const { t } = useI18n(); const dashboardStore = useDashboardStore(); diff --git a/src/views/dashboard/controls/Profile.vue b/src/views/dashboard/controls/Profile.vue index 1faca451..8a1aa366 100644 --- a/src/views/dashboard/controls/Profile.vue +++ b/src/views/dashboard/controls/Profile.vue @@ -29,7 +29,7 @@ limitations under the License. --> {{ t("delete") }}
-
+
@@ -47,6 +47,7 @@ const props = defineProps({ default: () => ({ graph: {} }), }, activeIndex: { type: String, default: "" }, + needQuery: { type: Boolean, default: true }, }); const { t } = useI18n(); const dashboardStore = useDashboardStore(); diff --git a/src/views/dashboard/controls/Tab.vue b/src/views/dashboard/controls/Tab.vue index 524e9f7e..8c353993 100644 --- a/src/views/dashboard/controls/Tab.vue +++ b/src/views/dashboard/controls/Tab.vue @@ -37,10 +37,17 @@ limitations under the License. --> v-if="dashboardStore.editMode && canEditTabName" /> + + + + + + + - + @@ -99,6 +106,7 @@ limitations under the License. --> + diff --git a/src/views/dashboard/related/demand-log/Header.vue b/src/views/dashboard/related/demand-log/Header.vue new file mode 100644 index 00000000..3e25b193 --- /dev/null +++ b/src/views/dashboard/related/demand-log/Header.vue @@ -0,0 +1,433 @@ + + + + diff --git a/src/views/dashboard/related/demand-log/data.ts b/src/views/dashboard/related/demand-log/data.ts new file mode 100644 index 00000000..0ef8c235 --- /dev/null +++ b/src/views/dashboard/related/demand-log/data.ts @@ -0,0 +1,37 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const TimeRanges = [ + { label: "From 5 seconds ago -- Now", value: 5 }, + { label: "From 10 seconds ago -- Now", value: 10 }, + { label: "From 15 seconds ago -- Now", value: 15 }, + { label: "From 30 seconds ago -- Now", value: 30 }, + { label: "From 45 seconds ago -- Now", value: 45 }, + { label: "From 1 minute ago -- Now", value: 60 }, + { label: "From 5 minutes ago -- Now", value: 300 }, + { label: "From 15 minutes ago -- Now", value: 900 }, + { label: "From 30 minutes ago -- Now", value: 1800 }, +]; +export const IntervalOpts = [ + { label: "None", value: 0 }, + { label: "5 seconds", value: 5 }, + { label: "10 seconds", value: 10 }, + { label: "15 seconds", value: 15 }, + { label: "30 seconds", value: 30 }, + { label: "45 seconds", value: 45 }, + { label: "1 minute", value: 60 }, +]; diff --git a/src/views/dashboard/related/ebpf/Content.vue b/src/views/dashboard/related/ebpf/Content.vue index 019a20c4..f308004e 100644 --- a/src/views/dashboard/related/ebpf/Content.vue +++ b/src/views/dashboard/related/ebpf/Content.vue @@ -38,7 +38,7 @@ import EBPFStack from "./components/EBPFStack.vue"; .vis-graph { height: 100%; - width: calc(100% - 300px); + flex-grow: 2; min-width: 700px; overflow: auto; } diff --git a/src/views/dashboard/related/ebpf/Header.vue b/src/views/dashboard/related/ebpf/Header.vue index da7a809f..24fa9bb4 100644 --- a/src/views/dashboard/related/ebpf/Header.vue +++ b/src/views/dashboard/related/ebpf/Header.vue @@ -39,6 +39,10 @@ import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; import { EntityType } from "../../data"; +/*global defineProps */ +const props = defineProps({ + needQuery: { type: Boolean, default: true }, +}); const ebpfStore = useEbpfStore(); const appStore = useAppStoreWithOut(); const selectorStore = useSelectorStore(); @@ -46,7 +50,9 @@ const dashboardStore = useDashboardStore(); const { t } = useI18n(); const newTask = ref(false); -searchTasks(); +if (props.needQuery) { + searchTasks(); +} async function searchTasks() { const serviceId = diff --git a/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue b/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue index 191b0097..0cd8f9d0 100644 --- a/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue +++ b/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue @@ -40,7 +40,12 @@ limitations under the License. --> @change="changeAggregateType" class="selector mr-10" /> - + - diff --git a/src/views/event/Header.vue b/src/views/event/Header.vue deleted file mode 100644 index 3b2da10f..00000000 --- a/src/views/event/Header.vue +++ /dev/null @@ -1,251 +0,0 @@ - - - - diff --git a/vue.config.js b/vue.config.js index 0f494b02..e7753763 100644 --- a/vue.config.js +++ b/vue.config.js @@ -15,6 +15,7 @@ * limitations under the License. */ +const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin"); const AutoImport = require("unplugin-auto-import/webpack"); const Components = require("unplugin-vue-components/webpack"); const { ElementPlusResolver } = require("unplugin-vue-components/resolvers"); @@ -66,6 +67,11 @@ module.exports = { test: /[\\/]node_modules[\\/]echarts|zrender[\\/]/, priority: 30, }, + monacoEditor: { + name: "monaco-editor", + test: /[\\/]node_modules[\\/]monaco-editor[\\/]/, + priority: 40, + }, elementPlus: { name: "element-plus", test: /[\\/]node_modules[\\/]element-plus|@element-plus[\\/]/, @@ -100,7 +106,8 @@ module.exports = { Components({ resolvers: [ElementPlusResolver({ importStyle: "css" })], dts: "./src/types/components.d.ts", - }) + }), + new MonacoWebpackPlugin() ); }, };