diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 9c731c21..3003504b 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -49,6 +49,7 @@ jobs: npm ci npm run lint npm run build --if-present + npm run check-components-types npm run test:unit env: CI: true diff --git a/package-lock.json b/package-lock.json index ebf1e905..22647189 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "d3-flame-graph": "^4.1.3", "d3-tip": "^0.9.1", "echarts": "^5.2.2", - "element-plus": "^2.0.2", + "element-plus": "^2.1.0", "lodash": "^4.17.21", "monaco-editor": "^0.34.1", "pinia": "^2.0.28", @@ -48,7 +48,7 @@ "eslint-plugin-vue": "^9.3.0", "husky": "^8.0.2", "jsdom": "^20.0.3", - "lint-staged": "^12.1.3", + "lint-staged": "^13.2.1", "mockjs": "^1.1.0", "node-sass": "^8.0.0", "npm-run-all": "^4.1.5", @@ -57,15 +57,15 @@ "prettier": "^2.7.1", "sass": "^1.56.1", "start-server-and-test": "^1.15.2", - "stylelint": "^14.1.0", + "stylelint": "^15.6.0", "stylelint-config-html": "^1.0.0", "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^24.0.0", - "stylelint-order": "^5.0.0", + "stylelint-config-standard": "^33.0.0", + "stylelint-order": "^6.0.3", "typescript": "~4.7.4", "unplugin-auto-import": "^0.7.0", "unplugin-vue-components": "^0.19.2", - "vite": "^4.0.0", + "vite": "^4.0.5", "vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-svg-icons": "^2.0.1", "vitest": "^0.25.6", @@ -624,12 +624,12 @@ } }, "node_modules/@commitlint/config-validator": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.1.0.tgz", - "integrity": "sha512-Q1rRRSU09ngrTgeTXHq6ePJs2KrI+axPTgkNYDWSJIuS1Op4w3J30vUfSXjwn5YEJHklK3fSqWNHmBhmTR7Vdg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", + "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.0.0", + "@commitlint/types": "^17.4.4", "ajv": "^8.11.0" }, "engines": { @@ -637,9 +637,9 @@ } }, "node_modules/@commitlint/config-validator/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -676,9 +676,9 @@ } }, "node_modules/@commitlint/execute-rule": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.0.0.tgz", - "integrity": "sha512-nVjL/w/zuqjCqSJm8UfpNaw66V9WzuJtQvEnCrK4jDw6qKTmZB+1JQ8m6BQVZbNBcwfYdDNKnhIhqI0Rk7lgpQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", + "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", "dev": true, "engines": { "node": ">=v14" @@ -823,36 +823,30 @@ } }, "node_modules/@commitlint/load": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.3.0.tgz", - "integrity": "sha512-u/pV6rCAJrCUN+HylBHLzZ4qj1Ew3+eN9GBPhNi9otGxtOfA8b+8nJSxaNbcC23Ins/kcpjGf9zPSVW7628Umw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz", + "integrity": "sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.1.0", - "@commitlint/execute-rule": "^17.0.0", - "@commitlint/resolve-extends": "^17.3.0", - "@commitlint/types": "^17.0.0", - "@types/node": "^14.0.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/execute-rule": "^17.4.0", + "@commitlint/resolve-extends": "^17.4.4", + "@commitlint/types": "^17.4.4", + "@types/node": "*", "chalk": "^4.1.0", - "cosmiconfig": "^7.0.0", + "cosmiconfig": "^8.0.0", "cosmiconfig-typescript-loader": "^4.0.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0", "resolve-from": "^5.0.0", "ts-node": "^10.8.1", - "typescript": "^4.6.4" + "typescript": "^4.6.4 || ^5.0.0" }, "engines": { "node": ">=v14" } }, - "node_modules/@commitlint/load/node_modules/@types/node": { - "version": "14.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.34.tgz", - "integrity": "sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA==", - "dev": true - }, "node_modules/@commitlint/load/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -986,13 +980,13 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.3.0.tgz", - "integrity": "sha512-Lf3JufJlc5yVEtJWC8o4IAZaB8FQAUaVlhlAHRACd0TTFizV2Lk2VH70et23KgvbQNf7kQzHs/2B4QZalBv6Cg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", + "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.1.0", - "@commitlint/types": "^17.0.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/types": "^17.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", @@ -1093,9 +1087,9 @@ } }, "node_modules/@commitlint/types": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.0.0.tgz", - "integrity": "sha512-hBAw6U+SkAT5h47zDMeOu3HSiD0SODw4Aq7rRNh1ceUmL7GyLKYhPbUvlRWqZ65XjBLPHZhFyQlRaPNz8qvUyQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", "dev": true, "dependencies": { "chalk": "^4.1.0" @@ -1196,20 +1190,65 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz", + "integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==", "dev": true, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", + "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz", + "integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", "postcss-selector-parser": "^6.0.10" } }, @@ -1282,9 +1321,9 @@ } }, "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", - "integrity": "sha512-S8kDbfVaWkQvbUYQE1ui448tzaHfUvyESCep9J6uPRlViyQPXjdIfwLBhV6AmQSOfFS8rL+xehJGhvzPXLrSBg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz", + "integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==", "peerDependencies": { "vue": "^3.2.0" } @@ -2554,12 +2593,6 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -4621,19 +4654,21 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" } }, "node_modules/cosmiconfig-typescript-loader": { @@ -5781,19 +5816,20 @@ "dev": true }, "node_modules/element-plus": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.0.2.tgz", - "integrity": "sha512-URjC0HwwiqtlLxqTmHXQ31WXrdAq4ChWyyn52OcQs3PRsnMPfahGVq2AWnfzzlzlhVeI5lY3HQiuB1zDathS+g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.1.0.tgz", + "integrity": "sha512-PQM3LMv5qKf0sS/k+PXuBcmKl1Eb3b7fxKPyFHZ6eodZcNykbEMcpLZefQkvmDr6calVnuQ7TUnTm7Tm9LJXvg==", "dependencies": { "@ctrl/tinycolor": "^3.4.0", - "@element-plus/icons-vue": "^0.2.6", + "@element-plus/icons-vue": "^1.0.1", "@popperjs/core": "^2.11.2", - "@vueuse/core": "^7.6.0", + "@vueuse/core": "^7.7.1", "async-validator": "^4.0.7", - "dayjs": "^1.10.7", + "dayjs": "^1.10.8", + "escape-html": "^1.0.3", "lodash": "^4.17.21", "lodash-es": "^4.17.21", - "lodash-unified": "^1.0.1", + "lodash-unified": "^1.0.2", "memoize-one": "^6.0.0", "normalize-wheel-es": "^1.1.1" }, @@ -6405,6 +6441,11 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -8083,9 +8124,9 @@ } }, "node_modules/html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, "engines": { "node": ">=8" @@ -8225,9 +8266,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", - "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -9050,9 +9091,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", - "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", "dev": true }, "node_modules/lazy-ass": { @@ -9078,9 +9119,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, "engines": { "node": ">=10" @@ -9093,31 +9134,30 @@ "dev": true }, "node_modules/lint-staged": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.5.0.tgz", - "integrity": "sha512-BKLUjWDsKquV/JuIcoQW4MSAI3ggwEImF1+sB4zaKvyVx1wBk3FsG7UK9bpnmBTN1pm7EH2BBcMwINJzCRv12g==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.1.tgz", + "integrity": "sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==", "dev": true, "dependencies": { + "chalk": "5.2.0", "cli-truncate": "^3.1.0", - "colorette": "^2.0.16", - "commander": "^9.3.0", + "commander": "^10.0.0", "debug": "^4.3.4", - "execa": "^5.1.1", - "lilconfig": "2.0.5", - "listr2": "^4.0.5", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", - "pidtree": "^0.5.0", + "object-inspect": "^1.12.3", + "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "supports-color": "^9.2.2", - "yaml": "^1.10.2" + "yaml": "^2.2.1" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/lint-staged" @@ -9138,6 +9178,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/lint-staged/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -9157,32 +9209,32 @@ "dev": true }, "node_modules/lint-staged/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, "engines": { - "node": "^12.20.0 || >=14" + "node": ">=14" } }, "node_modules/lint-staged/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" @@ -9201,12 +9253,12 @@ } }, "node_modules/lint-staged/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, "engines": { - "node": ">=10.17.0" + "node": ">=14.18.0" } }, "node_modules/lint-staged/node_modules/is-fullwidth-code-point": { @@ -9218,23 +9270,35 @@ "node": ">=8" } }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lint-staged/node_modules/listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", + "colorette": "^2.0.19", "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.5", + "rxjs": "^7.8.0", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=12" + "node": "^14.13.1 || >=16.0.0" }, "peerDependencies": { "enquirer": ">= 2.3.0 < 3" @@ -9261,6 +9325,60 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lint-staged/node_modules/slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", @@ -9275,16 +9393,25 @@ "node": ">=8" } }, - "node_modules/lint-staged/node_modules/supports-color": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.3.0.tgz", - "integrity": "sha512-hJ6RYjNbcBFkpHi+ykjar+7GgHs+65Kxyw940nBLOSjaWZ13acq4A5f+gWiV5w+xfsg5MbnjDxTigLcUuljerw==", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", + "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==", + "dev": true, + "engines": { + "node": ">= 14" } }, "node_modules/listr2": { @@ -10214,9 +10341,15 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10967,9 +11100,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11287,9 +11420,9 @@ } }, "node_modules/pidtree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", - "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, "bin": { "pidtree": "bin/pidtree.js" @@ -11367,9 +11500,9 @@ } }, "node_modules/postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "funding": [ { "type": "opencollective", @@ -11378,10 +11511,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -11483,12 +11620,12 @@ } }, "node_modules/postcss-sorting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", - "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", + "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", "dev": true, "peerDependencies": { - "postcss": "^8.3.9" + "postcss": "^8.4.20" } }, "node_modules/postcss-value-parser": { @@ -12383,9 +12520,9 @@ "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/rxjs": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz", - "integrity": "sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -13432,16 +13569,20 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", - "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.0.tgz", + "integrity": "sha512-Cqzpc8tvJm77KaM8qUbhpJ/UYK55Ia0whQXj4b9IId9dlPICO7J8Lyo15SZWiHxKjlvy3p5FQor/3n6i8ignXg==", "dev": true, "dependencies": { - "@csstools/selector-specificity": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.0.4", + "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.1.0", + "cosmiconfig": "^8.1.3", "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", @@ -13449,18 +13590,18 @@ "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.2.0", - "ignore": "^5.2.1", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.26.0", + "known-css-properties": "^0.27.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.19", + "postcss": "^8.4.22", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -13470,17 +13611,17 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", + "supports-hyperlinks": "^3.0.0", "svg-tags": "^1.0.0", "table": "^6.8.1", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.0" }, "bin": { "stylelint": "bin/stylelint.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -13520,37 +13661,37 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz", - "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz", + "integrity": "sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==", "dev": true, "peerDependencies": { - "stylelint": "^14.0.0" + "stylelint": "^15.5.0" } }, "node_modules/stylelint-config-standard": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz", - "integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==", + "version": "33.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz", + "integrity": "sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==", "dev": true, "dependencies": { - "stylelint-config-recommended": "^6.0.0" + "stylelint-config-recommended": "^12.0.0" }, "peerDependencies": { - "stylelint": "^14.0.0" + "stylelint": "^15.5.0" } }, "node_modules/stylelint-order": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", - "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz", + "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==", "dev": true, "dependencies": { - "postcss": "^8.3.11", - "postcss-sorting": "^7.0.1" + "postcss": "^8.4.21", + "postcss-sorting": "^8.0.2" }, "peerDependencies": { - "stylelint": "^14.0.0" + "stylelint": "^14.0.0 || ^15.0.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -13559,6 +13700,25 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, + "node_modules/stylelint/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/stylelint/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -13581,16 +13741,16 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.18" } }, "node_modules/supports-hyperlinks/node_modules/has-flag": { @@ -15470,13 +15630,13 @@ } }, "node_modules/vite": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.0.tgz", - "integrity": "sha512-ynad+4kYs8Jcnn8J7SacS9vAbk7eMy0xWg6E7bAhS1s79TK+D7tVFGXVZ55S7RNLRROU1rxoKlvZ/qjaB41DGA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.5.tgz", + "integrity": "sha512-7m87RC+caiAxG+8j3jObveRLqaWA/neAdCat6JAZwMkSWqFHOvg8MYe5fAQxVBRAuKAQ1S6XDh3CBQuLNbY33w==", "dev": true, "dependencies": { "esbuild": "^0.16.3", - "postcss": "^8.4.19", + "postcss": "^8.4.20", "resolve": "^1.22.1", "rollup": "^3.7.0" }, @@ -15989,16 +16149,16 @@ "dev": true }, "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/ws": { @@ -16074,15 +16234,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "17.6.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", @@ -16565,19 +16716,19 @@ } }, "@commitlint/config-validator": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.1.0.tgz", - "integrity": "sha512-Q1rRRSU09ngrTgeTXHq6ePJs2KrI+axPTgkNYDWSJIuS1Op4w3J30vUfSXjwn5YEJHklK3fSqWNHmBhmTR7Vdg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", + "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", "dev": true, "requires": { - "@commitlint/types": "^17.0.0", + "@commitlint/types": "^17.4.4", "ajv": "^8.11.0" }, "dependencies": { "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -16609,9 +16760,9 @@ } }, "@commitlint/execute-rule": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.0.0.tgz", - "integrity": "sha512-nVjL/w/zuqjCqSJm8UfpNaw66V9WzuJtQvEnCrK4jDw6qKTmZB+1JQ8m6BQVZbNBcwfYdDNKnhIhqI0Rk7lgpQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", + "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", "dev": true }, "@commitlint/format": { @@ -16718,33 +16869,27 @@ } }, "@commitlint/load": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.3.0.tgz", - "integrity": "sha512-u/pV6rCAJrCUN+HylBHLzZ4qj1Ew3+eN9GBPhNi9otGxtOfA8b+8nJSxaNbcC23Ins/kcpjGf9zPSVW7628Umw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz", + "integrity": "sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.1.0", - "@commitlint/execute-rule": "^17.0.0", - "@commitlint/resolve-extends": "^17.3.0", - "@commitlint/types": "^17.0.0", - "@types/node": "^14.0.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/execute-rule": "^17.4.0", + "@commitlint/resolve-extends": "^17.4.4", + "@commitlint/types": "^17.4.4", + "@types/node": "*", "chalk": "^4.1.0", - "cosmiconfig": "^7.0.0", + "cosmiconfig": "^8.0.0", "cosmiconfig-typescript-loader": "^4.0.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0", "resolve-from": "^5.0.0", "ts-node": "^10.8.1", - "typescript": "^4.6.4" + "typescript": "^4.6.4 || ^5.0.0" }, "dependencies": { - "@types/node": { - "version": "14.18.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.34.tgz", - "integrity": "sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16846,13 +16991,13 @@ } }, "@commitlint/resolve-extends": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.3.0.tgz", - "integrity": "sha512-Lf3JufJlc5yVEtJWC8o4IAZaB8FQAUaVlhlAHRACd0TTFizV2Lk2VH70et23KgvbQNf7kQzHs/2B4QZalBv6Cg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", + "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.1.0", - "@commitlint/types": "^17.0.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/types": "^17.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", @@ -16927,9 +17072,9 @@ } }, "@commitlint/types": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.0.0.tgz", - "integrity": "sha512-hBAw6U+SkAT5h47zDMeOu3HSiD0SODw4Aq7rRNh1ceUmL7GyLKYhPbUvlRWqZ65XjBLPHZhFyQlRaPNz8qvUyQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", "dev": true, "requires": { "chalk": "^4.1.0" @@ -17007,10 +17152,30 @@ } } }, + "@csstools/css-parser-algorithms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz", + "integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==", + "dev": true, + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", + "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", + "dev": true + }, + "@csstools/media-query-list-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz", + "integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==", + "dev": true, + "requires": {} + }, "@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "dev": true, "requires": {} }, @@ -17076,9 +17241,9 @@ } }, "@element-plus/icons-vue": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-0.2.7.tgz", - "integrity": "sha512-S8kDbfVaWkQvbUYQE1ui448tzaHfUvyESCep9J6uPRlViyQPXjdIfwLBhV6AmQSOfFS8rL+xehJGhvzPXLrSBg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-1.1.4.tgz", + "integrity": "sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==", "requires": {} }, "@esbuild/android-arm": { @@ -18019,12 +18184,6 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -19551,16 +19710,15 @@ } }, "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", "dev": true, "requires": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "path-type": "^4.0.0" }, "dependencies": { "parse-json": { @@ -20425,19 +20583,20 @@ "dev": true }, "element-plus": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.0.2.tgz", - "integrity": "sha512-URjC0HwwiqtlLxqTmHXQ31WXrdAq4ChWyyn52OcQs3PRsnMPfahGVq2AWnfzzlzlhVeI5lY3HQiuB1zDathS+g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.1.0.tgz", + "integrity": "sha512-PQM3LMv5qKf0sS/k+PXuBcmKl1Eb3b7fxKPyFHZ6eodZcNykbEMcpLZefQkvmDr6calVnuQ7TUnTm7Tm9LJXvg==", "requires": { "@ctrl/tinycolor": "^3.4.0", - "@element-plus/icons-vue": "^0.2.6", + "@element-plus/icons-vue": "^1.0.1", "@popperjs/core": "^2.11.2", - "@vueuse/core": "^7.6.0", + "@vueuse/core": "^7.7.1", "async-validator": "^4.0.7", - "dayjs": "^1.10.7", + "dayjs": "^1.10.8", + "escape-html": "^1.0.3", "lodash": "^4.17.21", "lodash-es": "^4.17.21", - "lodash-unified": "^1.0.1", + "lodash-unified": "^1.0.2", "memoize-one": "^6.0.0", "normalize-wheel-es": "^1.1.1" }, @@ -20784,6 +20943,11 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -22037,9 +22201,9 @@ } }, "html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true }, "htmlparser2": { @@ -22128,9 +22292,9 @@ "dev": true }, "ignore": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", - "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "image-size": { @@ -22734,9 +22898,9 @@ "dev": true }, "known-css-properties": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", - "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", "dev": true }, "lazy-ass": { @@ -22756,9 +22920,9 @@ } }, "lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true }, "lines-and-columns": { @@ -22768,25 +22932,24 @@ "dev": true }, "lint-staged": { - "version": "12.5.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.5.0.tgz", - "integrity": "sha512-BKLUjWDsKquV/JuIcoQW4MSAI3ggwEImF1+sB4zaKvyVx1wBk3FsG7UK9bpnmBTN1pm7EH2BBcMwINJzCRv12g==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.1.tgz", + "integrity": "sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==", "dev": true, "requires": { + "chalk": "5.2.0", "cli-truncate": "^3.1.0", - "colorette": "^2.0.16", - "commander": "^9.3.0", + "commander": "^10.0.0", "debug": "^4.3.4", - "execa": "^5.1.1", - "lilconfig": "2.0.5", - "listr2": "^4.0.5", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", - "pidtree": "^0.5.0", + "object-inspect": "^1.12.3", + "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "supports-color": "^9.2.2", - "yaml": "^1.10.2" + "yaml": "^2.2.1" }, "dependencies": { "ansi-styles": { @@ -22798,6 +22961,12 @@ "color-convert": "^2.0.1" } }, + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -22814,26 +22983,26 @@ "dev": true }, "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true }, "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "requires": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" } }, "get-stream": { @@ -22843,9 +23012,9 @@ "dev": true }, "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true }, "is-fullwidth-code-point": { @@ -22854,18 +23023,24 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, "listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "requires": { "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", + "colorette": "^2.0.19", "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.5", + "rxjs": "^7.8.0", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -22882,6 +23057,36 @@ } } }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, "slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", @@ -22893,10 +23098,16 @@ "is-fullwidth-code-point": "^3.0.0" } }, - "supports-color": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.3.0.tgz", - "integrity": "sha512-hJ6RYjNbcBFkpHi+ykjar+7GgHs+65Kxyw940nBLOSjaWZ13acq4A5f+gWiV5w+xfsg5MbnjDxTigLcUuljerw==", + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + }, + "yaml": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", + "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==", "dev": true } } @@ -23611,9 +23822,9 @@ "dev": true }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "nanomatch": { "version": "1.2.13", @@ -24195,9 +24406,9 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, "object-keys": { @@ -24432,9 +24643,9 @@ "dev": true }, "pidtree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", - "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true }, "pify": { @@ -24467,11 +24678,11 @@ "dev": true }, "postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -24540,9 +24751,9 @@ } }, "postcss-sorting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", - "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", + "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", "dev": true, "requires": {} }, @@ -25220,9 +25431,9 @@ "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "rxjs": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz", - "integrity": "sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -26044,16 +26255,20 @@ "dev": true }, "stylelint": { - "version": "14.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", - "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.0.tgz", + "integrity": "sha512-Cqzpc8tvJm77KaM8qUbhpJ/UYK55Ia0whQXj4b9IId9dlPICO7J8Lyo15SZWiHxKjlvy3p5FQor/3n6i8ignXg==", "dev": true, "requires": { - "@csstools/selector-specificity": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.0.4", + "@csstools/selector-specificity": "^2.2.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.1.0", + "cosmiconfig": "^8.1.3", "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", @@ -26061,18 +26276,18 @@ "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.2.0", - "ignore": "^5.2.1", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.26.0", + "known-css-properties": "^0.27.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.19", + "postcss": "^8.4.22", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -26082,11 +26297,11 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", + "supports-hyperlinks": "^3.0.0", "svg-tags": "^1.0.0", "table": "^6.8.1", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.0" }, "dependencies": { "balanced-match": { @@ -26095,6 +26310,22 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -26118,29 +26349,29 @@ "requires": {} }, "stylelint-config-recommended": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz", - "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz", + "integrity": "sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==", "dev": true, "requires": {} }, "stylelint-config-standard": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz", - "integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==", + "version": "33.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz", + "integrity": "sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==", "dev": true, "requires": { - "stylelint-config-recommended": "^6.0.0" + "stylelint-config-recommended": "^12.0.0" } }, "stylelint-order": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", - "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz", + "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==", "dev": true, "requires": { - "postcss": "^8.3.11", - "postcss-sorting": "^7.0.1" + "postcss": "^8.4.21", + "postcss-sorting": "^8.0.2" } }, "supports-color": { @@ -26153,9 +26384,9 @@ } }, "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -27394,14 +27625,14 @@ "requires": {} }, "vite": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.0.tgz", - "integrity": "sha512-ynad+4kYs8Jcnn8J7SacS9vAbk7eMy0xWg6E7bAhS1s79TK+D7tVFGXVZ55S7RNLRROU1rxoKlvZ/qjaB41DGA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.5.tgz", + "integrity": "sha512-7m87RC+caiAxG+8j3jObveRLqaWA/neAdCat6JAZwMkSWqFHOvg8MYe5fAQxVBRAuKAQ1S6XDh3CBQuLNbY33w==", "dev": true, "requires": { "esbuild": "^0.16.3", "fsevents": "~2.3.2", - "postcss": "^8.4.19", + "postcss": "^8.4.20", "resolve": "^1.22.1", "rollup": "^3.7.0" } @@ -27745,9 +27976,9 @@ "dev": true }, "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", "dev": true, "requires": { "imurmurhash": "^0.1.4", @@ -27803,12 +28034,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { "version": "17.6.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", diff --git a/package.json b/package.json index 87fb1477..bd873a2e 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", "lint:lint-staged": "lint-staged", - "prepare": "husky install" + "prepare": "husky install", + "check-components-types": "if (! git diff --quiet -U0 ./src/types); then echo 'type files are not updated correctly'; git diff -U0 ./src/types; exit 1; fi" }, "dependencies": { "axios": "^0.24.0", @@ -22,7 +23,7 @@ "d3-flame-graph": "^4.1.3", "d3-tip": "^0.9.1", "echarts": "^5.2.2", - "element-plus": "^2.0.2", + "element-plus": "^2.1.0", "lodash": "^4.17.21", "monaco-editor": "^0.34.1", "pinia": "^2.0.28", @@ -57,7 +58,7 @@ "eslint-plugin-vue": "^9.3.0", "husky": "^8.0.2", "jsdom": "^20.0.3", - "lint-staged": "^12.1.3", + "lint-staged": "^13.2.1", "mockjs": "^1.1.0", "node-sass": "^8.0.0", "npm-run-all": "^4.1.5", @@ -66,15 +67,15 @@ "prettier": "^2.7.1", "sass": "^1.56.1", "start-server-and-test": "^1.15.2", - "stylelint": "^14.1.0", + "stylelint": "^15.6.0", "stylelint-config-html": "^1.0.0", "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^24.0.0", - "stylelint-order": "^5.0.0", + "stylelint-config-standard": "^33.0.0", + "stylelint-order": "^6.0.3", "typescript": "~4.7.4", "unplugin-auto-import": "^0.7.0", "unplugin-vue-components": "^0.19.2", - "vite": "^4.0.0", + "vite": "^4.0.5", "vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-svg-icons": "^2.0.1", "vitest": "^0.25.6", diff --git a/src/assets/icons/all_inbox.svg b/src/assets/icons/all_inbox.svg index cf38fc98..07330101 100644 --- a/src/assets/icons/all_inbox.svg +++ b/src/assets/icons/all_inbox.svg @@ -12,6 +12,6 @@ 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. --> - - + + diff --git a/src/assets/icons/continuous_profiling.svg b/src/assets/icons/continuous_profiling.svg new file mode 100644 index 00000000..fec271e6 --- /dev/null +++ b/src/assets/icons/continuous_profiling.svg @@ -0,0 +1,17 @@ + + + + diff --git a/src/assets/icons/edit.svg b/src/assets/icons/edit.svg new file mode 100644 index 00000000..3610dedb --- /dev/null +++ b/src/assets/icons/edit.svg @@ -0,0 +1,17 @@ + + + + diff --git a/src/assets/icons/mq.svg b/src/assets/icons/mq.svg new file mode 100644 index 00000000..55640d31 --- /dev/null +++ b/src/assets/icons/mq.svg @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/assets/icons/settings.svg b/src/assets/icons/settings.svg index f394ff29..7b18be5f 100644 --- a/src/assets/icons/settings.svg +++ b/src/assets/icons/settings.svg @@ -12,6 +12,6 @@ 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. --> - + diff --git a/src/assets/icons/task_timeline.svg b/src/assets/icons/task_timeline.svg new file mode 100644 index 00000000..4ea31234 --- /dev/null +++ b/src/assets/icons/task_timeline.svg @@ -0,0 +1,17 @@ + + + + diff --git a/src/assets/img/technologies/GRIZZLY.png b/src/assets/img/technologies/GRIZZLY.png new file mode 100644 index 00000000..eaec3cc7 Binary files /dev/null and b/src/assets/img/technologies/GRIZZLY.png differ diff --git a/src/assets/img/technologies/JERSEY.png b/src/assets/img/technologies/JERSEY.png new file mode 100644 index 00000000..02e001c9 Binary files /dev/null and b/src/assets/img/technologies/JERSEY.png differ diff --git a/src/components/Selector.vue b/src/components/Selector.vue index 5c2d9ca6..30be63bc 100644 --- a/src/components/Selector.vue +++ b/src/components/Selector.vue @@ -27,7 +27,13 @@ limitations under the License. --> :remote-method="remoteMethod" :filterable="filterable" > - + diff --git a/src/graphql/fragments/ebpf.ts b/src/graphql/fragments/ebpf.ts index b32333f7..7f635650 100644 --- a/src/graphql/fragments/ebpf.ts +++ b/src/graphql/fragments/ebpf.ts @@ -33,20 +33,37 @@ export const createEBPFTask = { }`, }; export const queryEBPFTasks = { - variable: "$serviceId: ID, $serviceInstanceId: ID, $targets: [EBPFProfilingTargetType!]", + variable: + "$serviceId: ID, $serviceInstanceId: ID, $targets: [EBPFProfilingTargetType!], $triggerType: EBPFProfilingTriggerType", query: ` - queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId, serviceInstanceId: $serviceInstanceId, targets: $targets) { + queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId, serviceInstanceId: $serviceInstanceId, targets: $targets, triggerType: $triggerType) { taskId serviceName serviceId serviceInstanceId serviceInstanceName processLabels + processName + processId taskStartTime triggerType fixedTriggerDuration targetType createTime + continuousProfilingCauses { + type + singleValue { + threshold + current + } + uri { + uriRegex + uriPath + threshold + current + } + message + } }`, }; export const queryEBPFSchedules = { @@ -111,3 +128,26 @@ export const keepNetworkProfiling = { errorReason }`, }; + +export const monitoringInstances = { + variable: "$serviceId: ID!, $target: ContinuousProfilingTargetType!", + query: ` + instances: queryContinuousProfilingMonitoringInstances(serviceId: $serviceId, target: $target) { + id + name + attributes { + name + value + } + triggeredCount + lastTriggerTimestamp + processes { + id + name + detectType + labels + lastTriggerTimestamp + triggeredCount + } + }`, +}; diff --git a/src/graphql/fragments/profile.ts b/src/graphql/fragments/profile.ts index 01744eea..0e6fdca8 100644 --- a/src/graphql/fragments/profile.ts +++ b/src/graphql/fragments/profile.ts @@ -123,3 +123,29 @@ export const GetProfileTaskLogs = { } `, }; +export const GetStrategyList = { + variable: "$serviceId: ID!", + query: ` + strategyList: queryContinuousProfilingServiceTargets(serviceId: $serviceId) { + type + checkItems { + type + threshold + period + count + uriList + uriRegex + } + } + `, +}; + +export const EditStrategy = { + variable: "$request: ContinuousProfilingPolicyCreation!", + query: ` + strategy: setContinuousProfilingPolicy(request: $request) { + errorReason + status + } + `, +}; diff --git a/src/graphql/query/ebpf.ts b/src/graphql/query/ebpf.ts index 052fc7af..65a3eac0 100644 --- a/src/graphql/query/ebpf.ts +++ b/src/graphql/query/ebpf.ts @@ -23,6 +23,7 @@ import { analysisEBPFResult, createNetworkProfiling, keepNetworkProfiling, + monitoringInstances, } from "../fragments/ebpf"; export const getCreateTaskData = `query queryCreateTaskData(${queryCreateTaskData.variable}) {${queryCreateTaskData.query}}`; @@ -38,3 +39,5 @@ export const getEBPFResult = `query analysisEBPFResult(${analysisEBPFResult.vari export const newNetworkProfiling = `mutation createNetworkProfiling(${createNetworkProfiling.variable}) {${createNetworkProfiling.query}}`; export const aliveNetworkProfiling = `mutation keepNetworkProfiling(${keepNetworkProfiling.variable}) {${keepNetworkProfiling.query}}`; + +export const getMonitoringInstances = `query continuousProfilingMonitoringInstances(${monitoringInstances.variable}) {${monitoringInstances.query}}`; diff --git a/src/graphql/query/profile.ts b/src/graphql/query/profile.ts index 6b762f02..044ffe0f 100644 --- a/src/graphql/query/profile.ts +++ b/src/graphql/query/profile.ts @@ -21,6 +21,8 @@ import { GetProfileTaskSegmentList, GetProfileAnalyze, GetProfileTaskLogs, + GetStrategyList, + EditStrategy, } from "../fragments/profile"; export const saveProfileTask = `mutation createProfileTask(${CreateProfileTask.variable}) {${CreateProfileTask.query}}`; @@ -34,3 +36,7 @@ export const getProfileTaskSegmentList = `query getProfileTaskSegmentList(${GetP export const getProfileAnalyze = `query getProfileAnalyze(${GetProfileAnalyze.variable}) {${GetProfileAnalyze.query}}`; export const getProfileTaskLogs = `query profileTaskLogs(${GetProfileTaskLogs.variable}) {${GetProfileTaskLogs.query}}`; + +export const getStrategyList = `query getStrategyList(${GetStrategyList.variable}) {${GetStrategyList.query}}`; + +export const editStrategy = `mutation editStrategy(${EditStrategy.variable}) {${EditStrategy.query}}`; diff --git a/src/hooks/data.ts b/src/hooks/data.ts index 0484aca0..8d88e076 100644 --- a/src/hooks/data.ts +++ b/src/hooks/data.ts @@ -22,6 +22,7 @@ export enum MetricQueryTypes { READHEATMAP = "readHeatMap", ReadSampledRecords = "readSampledRecords", ReadRecords = "readRecords", + ReadNullableMetricsValue = "readNullableMetricsValue", } export enum Calculations { @@ -70,10 +71,14 @@ export const RespFields: Indexable = { readMetricsValues: `{ label values { - values {value} + values {value isEmptyValue} } }`, - readMetricsValue: "", + readMetricsValue: ``, + readNullableMetricsValue: `{ + value + isEmptyValue + }`, sortMetrics: `{ name id @@ -83,7 +88,7 @@ export const RespFields: Indexable = { readLabeledMetricsValues: `{ label values { - values {value} + values {value isEmptyValue} } }`, readHeatMap: `{ @@ -107,4 +112,21 @@ export const RespFields: Indexable = { value refId }`, + execExpression: `{ + type + results { + metric { + labels { + key + value + } + } + values { + name: id + value + refId: traceID + } + } + error + }`, }; diff --git a/src/hooks/useExpressionsProcessor.ts b/src/hooks/useExpressionsProcessor.ts new file mode 100644 index 00000000..d3ee7ee7 --- /dev/null +++ b/src/hooks/useExpressionsProcessor.ts @@ -0,0 +1,313 @@ +/** + * 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 { RespFields } from "./data"; +import { ExpressionResultType } from "@/views/dashboard/data"; +import { ElMessage } from "element-plus"; +import { useDashboardStore } from "@/store/modules/dashboard"; +import { useSelectorStore } from "@/store/modules/selectors"; +import { useAppStoreWithOut } from "@/store/modules/app"; +import type { MetricConfigOpt } from "@/types/dashboard"; +import type { Instance, Endpoint, Service } from "@/types/selector"; + +export async function useExpressionsQueryProcessor(config: Indexable) { + function expressionsGraphqlPods() { + if (!(config.metrics && config.metrics[0])) { + return; + } + const appStore = useAppStoreWithOut(); + const dashboardStore = useDashboardStore(); + const selectorStore = useSelectorStore(); + + if (!selectorStore.currentService && dashboardStore.entity !== "All") { + return; + } + const conditions: Recordable = { + duration: appStore.durationTime, + }; + const variables: string[] = [`$duration: Duration!`]; + const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes( + dashboardStore.entity, + ); + if (isRelation && !selectorStore.currentDestService) { + return; + } + const fragment = config.metrics.map((name: string, index: number) => { + variables.push(`$expression${index}: String!`, `$entity${index}: Entity!`); + conditions[`expression${index}`] = name; + const entity = { + serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value, + normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal, + serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", "ProcessRelation", "Process"].includes( + dashboardStore.entity, + ) + ? selectorStore.currentPod && selectorStore.currentPod.value + : undefined, + endpointName: dashboardStore.entity.includes("Endpoint") + ? selectorStore.currentPod && selectorStore.currentPod.value + : undefined, + processName: dashboardStore.entity.includes("Process") + ? selectorStore.currentProcess && selectorStore.currentProcess.value + : undefined, + destNormal: isRelation ? selectorStore.currentDestService.normal : undefined, + destServiceName: isRelation ? selectorStore.currentDestService.value : undefined, + destServiceInstanceName: ["ServiceInstanceRelation", "ProcessRelation"].includes(dashboardStore.entity) + ? selectorStore.currentDestPod && selectorStore.currentDestPod.value + : undefined, + destEndpointName: + dashboardStore.entity === "EndpointRelation" + ? selectorStore.currentDestPod && selectorStore.currentDestPod.value + : undefined, + destProcessName: dashboardStore.entity.includes("ProcessRelation") + ? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value + : undefined, + }; + conditions[`entity${index}`] = entity; + + return `expression${index}: execExpression(expression: $expression${index}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`; + }); + const queryStr = `query queryData(${variables}) {${fragment}}`; + + return { + queryStr, + conditions, + }; + } + + function expressionsSource(resp: { errors: string; data: Indexable }) { + if (resp.errors) { + ElMessage.error(resp.errors); + return { source: {}, tips: [], typesOfMQE: [] }; + } + if (!resp.data) { + ElMessage.error("The query is wrong"); + return { source: {}, tips: [], typesOfMQE: [] }; + } + const tips: string[] = []; + const source: { [key: string]: unknown } = {}; + const keys = Object.keys(resp.data); + const typesOfMQE: string[] = []; + + for (let i = 0; i < config.metrics.length; i++) { + const c: MetricConfigOpt = (config.metricConfig && config.metricConfig[i]) || {}; + const obj = resp.data[keys[i]] || {}; + const results = obj.results || []; + const name = config.metrics[i]; + const type = obj.type; + + tips.push(obj.error); + typesOfMQE.push(type); + if (!obj.error) { + if (type === ExpressionResultType.TIME_SERIES_VALUES) { + if (results.length === 1) { + source[c.label || name] = results[0].values.map((d: { value: unknown }) => d.value) || []; + } else { + const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); + for (const item of results) { + const values = item.values.map((d: { value: unknown }) => d.value) || []; + const index = item.metric.labels[0].value; + const indexNum = labels.findIndex((_, i: number) => i === Number(index)); + if (labels[indexNum] && indexNum > -1) { + source[labels[indexNum]] = values; + } else { + source[index] = values; + } + } + } + } + if (type === ExpressionResultType.SINGLE_VALUE) { + source[c.label || name] = (results[0].values[0] || {}).value; + } + if (([ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST] as string[]).includes(type)) { + source[name] = results[0].values; + } + } + } + + return { source, tips, typesOfMQE }; + } + const params = await expressionsGraphqlPods(); + if (!params) { + return { source: {}, tips: [], typesOfMQE: [] }; + } + + const dashboardStore = useDashboardStore(); + const json = await dashboardStore.fetchMetricValue(params); + if (json.errors) { + ElMessage.error(json.errors); + return { source: {}, tips: [], typesOfMQE: [] }; + } + const data = expressionsSource(json); + + return data; +} + +export async function useExpressionsQueryPodsMetrics( + pods: Array<(Instance | Endpoint | Service) & Indexable>, + config: { + expressions: string[]; + subExpressions: string[]; + metricConfig: MetricConfigOpt[]; + }, + scope: string, +) { + function expressionsGraphqlPods() { + const metrics: string[] = []; + const subMetrics: string[] = []; + config.expressions = config.expressions || []; + config.subExpressions = config.subExpressions || []; + + for (let i = 0; i < config.expressions.length; i++) { + if (config.expressions[i]) { + metrics.push(config.expressions[i]); + subMetrics.push(config.subExpressions[i]); + } + } + if (!metrics.length) { + return; + } + const appStore = useAppStoreWithOut(); + const selectorStore = useSelectorStore(); + const conditions: { [key: string]: unknown } = { + duration: appStore.durationTime, + }; + const variables: string[] = [`$duration: Duration!`]; + const currentService = selectorStore.currentService || {}; + const fragmentList = pods.map((d: (Instance | Endpoint | Service) & Indexable, index: number) => { + const entity = { + serviceName: scope === "Service" ? d.label : currentService.label, + serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined, + endpointName: scope === "Endpoint" ? d.label : undefined, + normal: scope === "Service" ? d.normal : currentService.normal, + }; + variables.push(`$entity${index}: Entity!`); + conditions[`entity${index}`] = entity; + const f = metrics.map((name: string, idx: number) => { + variables.push(`$expression${index}${idx}: String!`); + conditions[`expression${index}${idx}`] = name; + let str = ""; + if (config.subExpressions[idx]) { + variables.push(`$subExpression${index}${idx}: String!`); + conditions[`subExpression${index}${idx}`] = config.subExpressions[idx]; + str = `subexpression${index}${idx}: execExpression(expression: $subExpression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`; + } + + return ( + str + + `expression${index}${idx}: execExpression(expression: $expression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}` + ); + }); + return f; + }); + const fragment = fragmentList.flat(1).join(" "); + const queryStr = `query queryData(${variables}) {${fragment}}`; + + return { queryStr, conditions }; + } + + function expressionsPodsSource(resp: { errors: string; data: Indexable }): Indexable { + if (resp.errors) { + ElMessage.error(resp.errors); + return {}; + } + const names: string[] = []; + const subNames: string[] = []; + const metricConfigArr: MetricConfigOpt[] = []; + const metricTypesArr: string[] = []; + const expressionsTips: string[] = []; + const subExpressionsTips: string[] = []; + const data = pods.map((d: any, idx: number) => { + for (let index = 0; index < config.expressions.length; index++) { + const c: MetricConfigOpt = (config.metricConfig && config.metricConfig[index]) || {}; + const k = "expression" + idx + index; + const sub = "subexpression" + idx + index; + const obj = resp.data[k] || {}; + const results = obj.results || []; + const typesOfMQE = obj.type || ""; + const subObj = resp.data[sub] || {}; + const subResults = subObj.results || []; + + expressionsTips.push(obj.error); + subExpressionsTips.push(subObj.error); + if (results.length > 1) { + const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); + const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); + for (let i = 0; i < results.length; i++) { + let name = results[i].metric.labels[0].value || ""; + const subValues = subResults[i] && subResults[i].values.map((d: { value: unknown }) => d.value); + const num = labelsIdx.findIndex((d: string) => d === results[i].metric.labels[0].value); + + if (labels[num]) { + name = labels[num]; + } + if (!d[name]) { + d[name] = {}; + } + if (subValues) { + d[name]["values"] = subValues; + } + d[name]["avg"] = (results[i].values[0] || {}).value; + + const j = names.find((d: string) => d === name); + + if (!j) { + names.push(name); + metricConfigArr.push({ ...c, index: i }); + metricTypesArr.push(typesOfMQE); + } + } + } else { + if (!results[0]) { + return d; + } + const name = config.expressions[index] || ""; + const subName = config.subExpressions[index] || ""; + if (!d[name]) { + d[name] = {}; + } + d[name]["avg"] = [(results[0].values[0] || {}).value]; + if (subResults[0]) { + if (!d[subName]) { + d[subName] = {}; + } + d[subName]["values"] = subResults[0].values.map((d: { value: number }) => d.value); + } + const j = names.find((d: string) => d === name); + if (!j) { + names.push(name); + subNames.push(subName); + metricConfigArr.push(c); + metricTypesArr.push(typesOfMQE); + } + } + } + return d; + }); + + return { data, names, subNames, metricConfigArr, metricTypesArr, expressionsTips, subExpressionsTips }; + } + const dashboardStore = useDashboardStore(); + const params = await expressionsGraphqlPods(); + const json = await dashboardStore.fetchMetricValue(params); + + if (json.errors) { + ElMessage.error(json.errors); + return {}; + } + const expressionParams = expressionsPodsSource(json); + + return expressionParams; +} diff --git a/src/hooks/useListConfig.ts b/src/hooks/useListConfig.ts index 8c199a07..d0705b5d 100644 --- a/src/hooks/useListConfig.ts +++ b/src/hooks/useListConfig.ts @@ -15,7 +15,15 @@ * limitations under the License. */ import { MetricQueryTypes, Calculations } from "./data"; -export function useListConfig(config: Indexable, index: string) { +import { MetricModes } from "@/views/dashboard/data"; + +export function useListConfig(config: Indexable, index: number) { + if (config.metricModes === MetricModes.Expression) { + return { + isLinear: false, + isAvg: true, + }; + } const i = Number(index); const types = [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg]; const calculation = config.metricConfig && config.metricConfig[i] && config.metricConfig[i].calculation; @@ -25,6 +33,7 @@ export function useListConfig(config: Indexable, index: string) { const isAvg = [MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) && types.includes(calculation); + return { isLinear, isAvg, diff --git a/src/hooks/useMetricsProcessor.ts b/src/hooks/useMetricsProcessor.ts index dbea34bf..b8ecc895 100644 --- a/src/hooks/useMetricsProcessor.ts +++ b/src/hooks/useMetricsProcessor.ts @@ -22,7 +22,6 @@ import { useSelectorStore } from "@/store/modules/selectors"; import { useAppStoreWithOut } from "@/store/modules/app"; import type { Instance, Endpoint, Service } from "@/types/selector"; import type { MetricConfigOpt } from "@/types/dashboard"; -import { MetricCatalog } from "@/views/dashboard/data"; export function useQueryProcessor(config: Indexable) { if (!(config.metrics && config.metrics[0])) { @@ -57,13 +56,11 @@ export function useQueryProcessor(config: Indexable) { name, parentService: ["All"].includes(dashboardStore.entity) ? null : selectorStore.currentService.value, normal: selectorStore.currentService ? selectorStore.currentService.normal : true, - scope: config.catalog, - topN: c.topN || 10, + topN: Number(c.topN) || 10, order: c.sortOrder || "DES", }; } else { const entity = { - scope: config.catalog, serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value, normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal, serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", "ProcessRelation"].includes( @@ -95,11 +92,10 @@ export function useQueryProcessor(config: Indexable) { conditions[`condition${index}`] = { name, parentEntity: entity, - topN: c.topN || 10, + topN: Number(c.topN) || 10, order: c.sortOrder || "DES", }; } else { - entity.scope = dashboardStore.entity; if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); variables.push(`$labels${index}: [String!]!`); @@ -114,9 +110,10 @@ export function useQueryProcessor(config: Indexable) { } if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { return `${name}${index}: ${metricType}(condition: $condition${index}, labels: $labels${index}, duration: $duration)${RespFields[metricType]}`; - } else { - return `${name}${index}: ${metricType}(condition: $condition${index}, duration: $duration)${RespFields[metricType]}`; } + const t = metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType; + + return `${name}${index}: ${t}(condition: $condition${index}, duration: $duration)${RespFields[t]}`; }); const queryStr = `query queryData(${variables}) {${fragment}}`; @@ -156,7 +153,9 @@ export function useSourceProcessor( const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); for (const item of resVal) { - const values = item.values.values.map((d: { value: number }) => aggregation(Number(d.value), c)); + const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) => + d.isEmptyValue ? NaN : aggregation(Number(d.value), c), + ); const indexNum = labelsIdx.findIndex((d: string) => d === item.label); if (labels[indexNum] && indexNum > -1) { source[labels[indexNum]] = values; @@ -166,7 +165,8 @@ export function useSourceProcessor( } } if (type === MetricQueryTypes.ReadMetricsValue) { - source[m] = aggregation(Number(Object.values(resp.data)[0]), c); + const v = Object.values(resp.data)[0] || {}; + source[m] = v.isEmptyValue ? NaN : aggregation(Number(v.value), c); } if ( ( @@ -229,7 +229,6 @@ export function useQueryPodsMetrics( const currentService = selectorStore.currentService || {}; const fragmentList = pods.map((d: (Instance | Endpoint | Service) & Indexable, index: number) => { const param = { - scope, serviceName: scope === "Service" ? d.label : currentService.label, serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined, endpointName: scope === "Endpoint" ? d.label : undefined, @@ -250,7 +249,9 @@ export function useQueryPodsMetrics( const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); conditions[`labels${index}${idx}`] = labels; } - return `${name}${index}${idx}: ${metricType}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[metricType]}`; + const t = + metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType; + return `${name}${index}${idx}: ${t}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[t]}`; }); return f; }); @@ -276,12 +277,13 @@ export function usePodsSource( const names: string[] = []; const metricConfigArr: MetricConfigOpt[] = []; const metricTypesArr: string[] = []; - const data = pods.map((d: Instance & Indexable, idx: number) => { + const data = pods.map((d: any, idx: number) => { config.metrics.map((name: string, index: number) => { const c: any = (config.metricConfig && config.metricConfig[index]) || {}; const key = name + idx + index; if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValue) { - d[name] = aggregation(resp.data[key], c); + const v = resp.data[key]; + d[name] = v.isEmptyValue ? NaN : aggregation(v.value, c); if (idx === 0) { names.push(name); metricConfigArr.push(c); @@ -293,7 +295,9 @@ export function usePodsSource( if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) { d[name]["avg"] = calculateExp(resp.data[key].values.values, c); } - d[name]["values"] = resp.data[key].values.values.map((val: { value: number }) => aggregation(val.value, c)); + d[name]["values"] = resp.data[key].values.values.map((val: { value: number; isEmptyValue: boolean }) => + val.isEmptyValue ? NaN : aggregation(val.value, c), + ); if (idx === 0) { names.push(name); metricConfigArr.push(c); @@ -306,7 +310,9 @@ export function usePodsSource( const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); for (let i = 0; i < resVal.length; i++) { const item = resVal[i]; - const values = item.values.values.map((d: { value: number }) => aggregation(Number(d.value), c)); + const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) => + d.isEmptyValue ? NaN : aggregation(Number(d.value), c), + ); const indexNum = labelsIdx.findIndex((d: string) => d === item.label); let key = item.label; if (labels[indexNum] && indexNum > -1) { @@ -356,8 +362,12 @@ export function useQueryTopologyMetrics(metrics: string[], ids: string[]) { return { queryStr, conditions }; } -function calculateExp(arr: { value: number }[], config: { calculation?: string }): (number | string)[] { - const sum = arr.map((d: { value: number }) => d.value).reduce((a, b) => a + b); +export function calculateExp( + list: { value: number; isEmptyValue: boolean }[], + config: { calculation?: string }, +): (number | string)[] { + const arr = list.filter((d: { value: number; isEmptyValue: boolean }) => !d.isEmptyValue); + const sum = arr.length ? arr.map((d: { value: number }) => Number(d.value)).reduce((a, b) => a + b) : 0; let data: (number | string)[] = []; switch (config.calculation) { case Calculations.Average: @@ -370,7 +380,9 @@ function calculateExp(arr: { value: number }[], config: { calculation?: string } data = [(sum / arr.length / 10000).toFixed(2)]; break; default: - data = arr.map((d) => aggregation(d.value, config)); + data = list.map((d: { value: number; isEmptyValue: boolean }) => + d.isEmptyValue ? NaN : aggregation(d.value, config), + ); break; } return data; @@ -423,26 +435,3 @@ export function aggregation(val: number, config: { calculation?: string }): numb return data; } - -export async function useGetMetricEntity(metric: string, metricType: string) { - if (!metric || !metricType) { - return; - } - let catalog = ""; - const dashboardStore = useDashboardStore(); - if ( - ([MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics, MetricQueryTypes.ReadRecords] as any).includes( - metricType, - ) - ) { - const res = await dashboardStore.fetchMetricList(metric); - if (res.errors) { - ElMessage.error(res.errors); - return; - } - const c: string = res.data.metrics[0].catalog; - catalog = (MetricCatalog as Indexable)[c]; - } - - return catalog; -} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 119cbe34..6bc4cacf 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -323,6 +323,7 @@ const msg = { keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this.", setEvent: "Set Event", viewAttributes: "View", + attributes: "Attributes", serviceEvents: "Service Events", select: "Select", eventID: "Event ID", @@ -385,5 +386,24 @@ const msg = { AWSGateway: "AWS API Gateway", APIGateway: "API Gateway", redis: "Redis", + elasticsearch: "Elasticsearch", + mq: "MQ", + rabbitMQ: "RabbitMQ", + save: "Save", + editStrategy: "Edit Policies", + policyList: "Policy List", + targetTypes: "Target Type", + monitorType: "Monitor Type", + count: "Count", + threshold: "Threshold", + uriRegex: "URI Regex", + uriList: "URI List", + processes: "Processes", + monitorInstances: "Monitor Instances", + processDashboards: "Process Dashboards", + instanceDashboards: "Instance Dashboards", + detailLabel: "Detail Label", + summary: "Summary", + detail: "Detail", }; export default msg; diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts index 2e69f8fd..2f5637e9 100644 --- a/src/locales/lang/es.ts +++ b/src/locales/lang/es.ts @@ -384,5 +384,25 @@ const msg = { AWSGateway: "AWS API Gateway", APIGateway: "API Gateway", redis: "Redis", + elasticsearch: "Elasticsearch", + mq: "MQ", + rabbitMQ: "RabbitMQ", + save: "Salvar", + editStrategy: "Estrategia editorial", + policyList: "Lista de políticas", + targetTypes: "Tipo de objetivo", + monitorType: "Tipo de Monitor", + count: "Contar", + threshold: "Umbral", + uriRegex: "Lista URI", + uriList: "Lista URI", + processes: "Proceso", + attributes: "Atributos", + monitorInstances: "Ejemplo de Monitor", + processDashboards: "Tablero de proceso", + instanceDashboards: "Tablero de ejemplo", + detailLabel: "Detail Label", + summary: "Summary", + detail: "Detail", }; export default msg; diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index 1dfd5aff..4bf623b8 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -382,5 +382,25 @@ const msg = { AWSGateway: "AWS API Gateway", APIGateway: "API Gateway", redis: "Redis", + elasticsearch: "Elasticsearch", + mq: "消息队列", + rabbitMQ: "RabbitMQ", + save: "保存", + editStrategy: "编辑策略", + policyList: "策略列表", + targetTypes: "目标类型", + monitorType: "监视器类型", + count: "总数", + threshold: "阈值", + uriRegex: "URI规则", + uriList: "URI列表", + processes: "进程", + attributes: "属性", + monitorInstances: "监视实例", + processDashboards: "进程仪表板", + instanceDashboards: "实例仪表板", + detailLabel: "详细标签", + summary: "概括", + detail: "详细", }; export default msg; diff --git a/src/router/dashboard.ts b/src/router/dashboard.ts index f4f799ce..32be6261 100644 --- a/src/router/dashboard.ts +++ b/src/router/dashboard.ts @@ -128,6 +128,27 @@ export const routesDashboard: Array = [ }, ], }, + { + path: "", + redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name", + component: () => import("@/views/dashboard/Edit.vue"), + name: "ViewProcess", + meta: { + notShow: true, + }, + children: [ + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name", + component: () => import("@/views/dashboard/Edit.vue"), + name: "ViewProcess", + }, + { + path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name/tab/:activeTabIndex", + component: () => import("@/views/dashboard/Edit.vue"), + name: "ViewProcessActiveTabIndex", + }, + ], + }, { path: "", redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", diff --git a/src/router/data/database.ts b/src/router/data/database.ts index 57a9d8b4..f95c500c 100644 --- a/src/router/data/database.ts +++ b/src/router/data/database.ts @@ -90,6 +90,22 @@ export default [ layer: "REDIS", }, }, + { + path: "/elasticsearch", + name: "Elasticsearch", + meta: { + title: "elasticsearch", + layer: "ELASTICSEARCH", + }, + }, + { + path: "/elasticsearch/tab/:activeTabIndex", + name: "ElasticsearchActiveTabIndex", + meta: { + notShow: true, + layer: "ELASTICSEARCH", + }, + }, ], }, ]; diff --git a/src/router/data/index.ts b/src/router/data/index.ts index f9a44212..94a8de71 100644 --- a/src/router/data/index.ts +++ b/src/router/data/index.ts @@ -24,6 +24,7 @@ import browser from "./browser"; import k8s from "./k8s"; import gateway from "./gateway"; import aws from "./aws"; +import mq from "./mq"; export default [ ...general, @@ -35,5 +36,6 @@ export default [ ...browser, ...gateway, ...database, + ...mq, ...selfObservability, ]; diff --git a/src/router/data/mq.ts b/src/router/data/mq.ts new file mode 100644 index 00000000..1286a4fc --- /dev/null +++ b/src/router/data/mq.ts @@ -0,0 +1,47 @@ +/** + * 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 default [ + { + path: "", + name: "MQ", + meta: { + title: "mq", + icon: "mq", + hasGroup: true, + }, + redirect: "/rabbitMQ", + children: [ + { + path: "/rabbitMQ", + name: "RabbitMQ", + meta: { + title: "rabbitMQ", + layer: "RABBITMQ", + }, + }, + { + path: "/rabbitMQ/tab/:activeTabIndex", + name: "RabbitMQActiveTabIndex", + meta: { + notShow: true, + layer: "RABBITMQ", + }, + }, + ], + }, +]; diff --git a/src/store/data.ts b/src/store/data.ts index 04a51f52..43d0d4d2 100644 --- a/src/store/data.ts +++ b/src/store/data.ts @@ -38,4 +38,18 @@ export const TimeRangeConfig = { text: "text", }; -export const ControlsTypes = ["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling", "ThirdPartyApp"]; +export const ControlsTypes = [ + "Trace", + "Profile", + "Log", + "DemandLog", + "Ebpf", + "NetworkProfiling", + "ThirdPartyApp", + "ContinuousProfiling", + "TaskTimeline", +]; +export enum EBPFProfilingTriggerType { + FIXED_TIME = "FIXED_TIME", + CONTINUOUS_PROFILING = "CONTINUOUS_PROFILING", +} diff --git a/src/store/modules/continous-profiling.ts b/src/store/modules/continous-profiling.ts new file mode 100644 index 00000000..2c6bc58a --- /dev/null +++ b/src/store/modules/continous-profiling.ts @@ -0,0 +1,171 @@ +/** + * 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 type { StrategyItem, CheckItems } from "@/types/continous-profiling"; +import type { EBPFTaskList, EBPFProfilingSchedule, AnalyzationTrees } from "@/types/ebpf"; +import type { Instance } from "@/types/selector"; +import { store } from "@/store"; +import graphql from "@/graphql"; +import type { MonitorInstance, MonitorProcess } from "@/types/continous-profiling"; +import type { AxiosResponse } from "axios"; +import { dateFormat } from "@/utils/dateFormat"; + +interface ContinousProfilingState { + strategyList: Array>; + selectedStrategy: Recordable; + taskList: Array>; + selectedTask: Recordable; + errorTip: string; + errorReason: string; + instances: Instance[]; + instance: Nullable; + eBPFSchedules: EBPFProfilingSchedule[]; + currentSchedule: EBPFProfilingSchedule | Record; + analyzeTrees: AnalyzationTrees[]; + ebpfTips: string; + aggregateType: string; + instancesLoading: boolean; + policyLoading: boolean; +} + +export const continousProfilingStore = defineStore({ + id: "continousProfiling", + state: (): ContinousProfilingState => ({ + strategyList: [], + selectedStrategy: {}, + taskList: [], + selectedTask: {}, + errorReason: "", + errorTip: "", + ebpfTips: "", + instances: [], + eBPFSchedules: [], + currentSchedule: {}, + analyzeTrees: [], + aggregateType: "COUNT", + instance: null, + instancesLoading: false, + policyLoading: false, + }), + actions: { + setSelectedStrategy(task: Recordable) { + this.selectedStrategy = task || {}; + }, + setselectedTask(task: Recordable) { + this.selectedTask = task || {}; + }, + setCurrentSchedule(s: EBPFProfilingSchedule) { + this.currentSchedule = s; + }, + setAnalyzeTrees(tree: AnalyzationTrees[]) { + this.analyzeTrees = tree; + }, + setCurrentInstance(instance: Nullable) { + this.instance = instance; + }, + async setContinuousProfilingPolicy( + serviceId: string, + targets: { + targetType: string; + checkItems: CheckItems[]; + }[], + ) { + const res: AxiosResponse = await graphql.query("editStrategy").params({ + request: { + serviceId, + targets, + }, + }); + + if (res.data.errors) { + return res.data; + } + + return res.data; + }, + async getStrategyList(params: { serviceId: string }) { + if (!params.serviceId) { + return new Promise((resolve) => resolve({})); + } + this.policyLoading = true; + const res: AxiosResponse = await graphql.query("getStrategyList").params(params); + + this.policyLoading = false; + if (res.data.errors) { + return res.data; + } + const list = res.data.data.strategyList || []; + if (!list.length) { + this.taskList = []; + this.instances = []; + this.instance = null; + } + const arr = list.length ? res.data.data.strategyList : [{ type: "", checkItems: [{ type: "" }] }]; + this.strategyList = arr.map((d: StrategyItem, index: number) => { + return { + ...d, + id: index, + }; + }); + this.setSelectedStrategy(this.strategyList[0]); + if (!this.selectedStrategy.type) { + return res.data; + } + this.getMonitoringInstances(params.serviceId); + return res.data; + }, + async getMonitoringInstances(serviceId: string): Promise> { + this.instancesLoading = true; + if (!serviceId) { + return null; + } + const res: AxiosResponse = await graphql.query("getMonitoringInstances").params({ + serviceId, + target: this.selectedStrategy.type, + }); + this.instancesLoading = false; + if (res.data.errors) { + return res.data; + } + this.instances = (res.data.data.instances || []) + .map((d: MonitorInstance) => { + const processes = (d.processes || []) + .sort((c: MonitorProcess, d: MonitorProcess) => d.lastTriggerTimestamp - c.lastTriggerTimestamp) + .map((p: MonitorProcess) => { + return { + ...p, + lastTriggerTime: d.lastTriggerTimestamp ? dateFormat(d.lastTriggerTimestamp) : "", + labels: p.labels.join("; "), + }; + }); + + return { + ...d, + processes, + lastTriggerTime: d.lastTriggerTimestamp ? dateFormat(d.lastTriggerTimestamp) : "", + }; + }) + .sort((a: MonitorInstance, b: MonitorInstance) => b.lastTriggerTimestamp - a.lastTriggerTimestamp); + this.instance = this.instances[0] || null; + return res.data; + }, + }, +}); + +export function useContinousProfilingStore(): Recordable { + return continousProfilingStore(store); +} diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts index 47051f30..c2c32da5 100644 --- a/src/store/modules/dashboard.ts +++ b/src/store/modules/dashboard.ts @@ -25,7 +25,7 @@ import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data" import type { AxiosResponse } from "axios"; import { ElMessage } from "element-plus"; import { useI18n } from "vue-i18n"; -import { EntityType } from "@/views/dashboard/data"; +import { EntityType, MetricModes } from "@/views/dashboard/data"; interface DashboardState { showConfig: boolean; layout: LayoutConfig[]; @@ -92,6 +92,10 @@ export const dashboardStore = defineStore({ metricTypes: [""], metrics: [""], }; + + if (type === "Widget") { + newItem.metricMode = MetricModes.Expression; + } if (type === "Tab") { newItem.h = 36; newItem.activedTabIndex = 0; @@ -167,6 +171,9 @@ export const dashboardStore = defineStore({ metricTypes: [""], metrics: [""], }; + if (type === "Widget") { + newItem.metricMode = MetricModes.Expression; + } if (type === "Topology") { newItem.h = 32; newItem.graph = { @@ -309,6 +316,11 @@ export const dashboardStore = defineStore({ return res.data; }, + async getTypeOfMQE(expression: string) { + const res: AxiosResponse = await graphql.query("getTypeOfMQE").params({ expression }); + + return res.data; + }, async fetchMetricList(regex: string) { const res: AxiosResponse = await graphql.query("queryMetrics").params({ regex }); diff --git a/src/store/modules/ebpf.ts b/src/store/modules/ebpf.ts index 7bc26a46..69f90ecb 100644 --- a/src/store/modules/ebpf.ts +++ b/src/store/modules/ebpf.ts @@ -20,6 +20,7 @@ import type { EBPFTaskCreationRequest, EBPFProfilingSchedule, EBPFTaskList, Anal import { store } from "@/store"; import graphql from "@/graphql"; import type { AxiosResponse } from "axios"; +import { EBPFProfilingTriggerType } from "../data"; interface EbpfState { taskList: Array>; eBPFSchedules: EBPFProfilingSchedule[]; @@ -27,7 +28,7 @@ interface EbpfState { analyzeTrees: AnalyzationTrees[]; labels: Option[]; couldProfiling: boolean; - tip: string; + ebpfTips: string; selectedTask: Recordable; aggregateType: string; } @@ -41,7 +42,7 @@ export const ebpfStore = defineStore({ analyzeTrees: [], labels: [{ value: "", label: "" }], couldProfiling: false, - tip: "", + ebpfTips: "", selectedTask: {}, aggregateType: "COUNT", }), @@ -77,6 +78,7 @@ export const ebpfStore = defineStore({ this.getTaskList({ serviceId: param.serviceId, targets: ["ON_CPU", "OFF_CPU"], + triggerType: EBPFProfilingTriggerType.FIXED_TIME, }); return res.data; }, @@ -86,7 +88,7 @@ export const ebpfStore = defineStore({ } const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params); - this.tip = ""; + this.ebpfTips = ""; if (res.data.errors) { return res.data; } @@ -103,13 +105,14 @@ export const ebpfStore = defineStore({ if (!params.taskId) { return new Promise((resolve) => resolve({})); } + const res: AxiosResponse = await graphql.query("getEBPFSchedules").params({ ...params }); if (res.data.errors) { this.eBPFSchedules = []; return res.data; } - this.tip = ""; + this.ebpfTips = ""; const { eBPFSchedules } = res.data.data; this.eBPFSchedules = eBPFSchedules; @@ -138,7 +141,7 @@ export const ebpfStore = defineStore({ return res.data; } const { analysisEBPFResult } = res.data.data; - this.tip = analysisEBPFResult.tip; + this.ebpfTips = analysisEBPFResult.tip; if (!analysisEBPFResult) { this.analyzeTrees = []; return res.data; diff --git a/src/store/modules/network-profiling.ts b/src/store/modules/network-profiling.ts index 071bfa57..5a6d6ce8 100644 --- a/src/store/modules/network-profiling.ts +++ b/src/store/modules/network-profiling.ts @@ -65,6 +65,12 @@ export const networkProfilingStore = defineStore({ setLink(link: Call) { this.call = link; }, + seNodes(nodes: Node[]) { + this.nodes = nodes; + }, + setLinks(links: Call[]) { + this.calls = links; + }, setMetricsLayout(layout: LayoutConfig[]) { this.metricsLayout = layout; }, diff --git a/src/store/modules/task-timeline.ts b/src/store/modules/task-timeline.ts new file mode 100644 index 00000000..25a411a7 --- /dev/null +++ b/src/store/modules/task-timeline.ts @@ -0,0 +1,134 @@ +/** + * 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 { ElMessage } from "element-plus"; +import { store } from "@/store"; +import graphql from "@/graphql"; +import type { AxiosResponse } from "axios"; +import { useAppStoreWithOut } from "@/store/modules/app"; +import type { EBPFTaskList } from "@/types/ebpf"; +import { useNetworkProfilingStore } from "@/store/modules/network-profiling"; +import { useSelectorStore } from "@/store/modules/selectors"; +import { useEbpfStore } from "@/store/modules/ebpf"; +import dateFormatStep from "@/utils/dateFormat"; +import getLocalTime from "@/utils/localtime"; +import { TargetTypes } from "@/views/dashboard/related/continuous-profiling/data"; +interface taskTimelineState { + loading: boolean; + taskList: EBPFTaskList[]; + selectedTask: Recordable; +} + +export const taskTimelineStore = defineStore({ + id: "taskTimeline", + state: (): taskTimelineState => ({ + loading: false, + taskList: [], + selectedTask: {}, + }), + actions: { + setSelectedTask(task: Recordable) { + this.selectedTask = task || {}; + }, + setTaskList(list: EBPFTaskList[]) { + this.taskList = list; + }, + async getContinousTaskList(params: { + serviceId: string; + serviceInstanceId: string; + targets: string[]; + triggerType: string; + }) { + if (!params.serviceId) { + return new Promise((resolve) => resolve({})); + } + this.loading = true; + const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params); + + this.loading = false; + this.errorTip = ""; + if (res.data.errors) { + return res.data; + } + const selectorStore = useSelectorStore(); + this.taskList = (res.data.data.queryEBPFTasks || []).filter( + (d: EBPFTaskList) => selectorStore.currentProcess && d.processId === selectorStore.currentProcess.id, + ); + // this.selectedTask = this.taskList[0] || {}; + // await this.getGraphData(); + return res.data; + }, + async getGraphData() { + let res: any = {}; + + if (this.selectedTask.targetType === TargetTypes[2].value) { + res = await this.getTopology(); + } else { + const ebpfStore = useEbpfStore(); + res = await ebpfStore.getEBPFSchedules({ + taskId: this.selectedTask.taskId, + }); + } + + if (res.errors) { + ElMessage.error(res.errors); + } + }, + async getTopology() { + const networkProfilingStore = useNetworkProfilingStore(); + const appStore = useAppStoreWithOut(); + const selectorStore = useSelectorStore(); + networkProfilingStore.setSelectedNetworkTask(this.selectedTask); + const { taskStartTime, fixedTriggerDuration } = this.selectedTask; + const startTime = + fixedTriggerDuration > 1800 ? taskStartTime + fixedTriggerDuration * 1000 - 30 * 60 * 1000 : taskStartTime; + let endTime = taskStartTime + fixedTriggerDuration * 1000; + if (taskStartTime + fixedTriggerDuration * 1000 > new Date().getTime()) { + endTime = new Date().getTime(); + } + const resp = await networkProfilingStore.getProcessTopology({ + serviceInstanceId: (selectorStore.currentPod || {}).id || "", + duration: { + start: dateFormatStep(getLocalTime(appStore.utc, new Date(startTime)), appStore.duration.step, true), + end: dateFormatStep(getLocalTime(appStore.utc, new Date(endTime)), appStore.duration.step, true), + step: appStore.duration.step, + }, + }); + if (resp.errors) { + ElMessage.error(resp.errors); + } + return resp; + }, + async preAnalyzeTask() { + if (this.selectedStrategy.type === "NETWORK") { + const networkProfilingStore = useNetworkProfilingStore(); + await networkProfilingStore.setSelectedNetworkTask(this.selectedTask); + return; + } + const res = await this.getEBPFSchedules({ + taskId: this.selectedTask.taskId, + }); + if (res.errors) { + ElMessage.error(res.errors); + } + }, + }, +}); + +export function useTaskTimelineStore(): Recordable { + return taskTimelineStore(store); +} diff --git a/src/styles/reset.scss b/src/styles/reset.scss index a24a4253..8c403e1f 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss @@ -216,3 +216,6 @@ div:has(> a.menu-title) { .el-breadcrumb { line-height: 28px; } +.el-input-number .el-input__inner { + text-align: left !important; +} diff --git a/src/types/app.d.ts b/src/types/app.d.ts index fee0d80d..479cdb8e 100644 --- a/src/types/app.d.ts +++ b/src/types/app.d.ts @@ -42,8 +42,9 @@ export type EventParams = { dataIndex: number; data: unknown; dataType: string; - value: number | Array; + value: number | any[]; color: string; event: Record; dataIndex: number; + event: any; }; diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 39dccc21..fc65710a 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -24,7 +24,6 @@ declare module '@vue/runtime-core' { ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] ElOption: typeof import('element-plus/es')['ElOption'] ElPagination: typeof import('element-plus/es')['ElPagination'] - ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm'] ElPopover: typeof import('element-plus/es')['ElPopover'] ElProgress: typeof import('element-plus/es')['ElProgress'] ElRadio: typeof import('element-plus/es')['ElRadio'] diff --git a/src/types/continous-profiling.d.ts b/src/types/continous-profiling.d.ts new file mode 100644 index 00000000..98c5b121 --- /dev/null +++ b/src/types/continous-profiling.d.ts @@ -0,0 +1,45 @@ +/** + * 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 interface StrategyItem { + type: string; + checkItems: CheckItems[]; +} +export type CheckItems = { + type: string; + threshold: string; + period: number; + count: number; + uriList?: string[]; + uriRegex?: string; +}; +export interface MonitorInstance { + id: string; + name: string; + attributes: { name: string; value: string }[]; + triggeredCount: number; + lastTriggerTimestamp: number; + processes: MonitorProcess[]; +} +interface MonitorProcess { + id: string; + name: string; + detectType: string; + labels: string[]; + lastTriggerTimestamp: number; + triggeredCount: number; +} diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts index b4c151ef..8612c10e 100644 --- a/src/types/dashboard.d.ts +++ b/src/types/dashboard.d.ts @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { DurationTime } from "./app"; export type DashboardItem = { id?: string; entity: string; @@ -28,11 +28,14 @@ export interface LayoutConfig { w: number; h: number; i: string; + type: string; + metricMode?: string; widget?: WidgetConfig; graph?: GraphConfig; metrics?: string[]; - type: string; + expressions?: string[]; metricTypes?: string[]; + typesOfMQE?: string[]; children?: { name: string; children: LayoutConfig[] }[]; activedTabIndex?: number; metricConfig?: MetricConfigOpt[]; @@ -41,6 +44,8 @@ export interface LayoutConfig { eventAssociate?: boolean; filters?: Filters; relatedTrace?: RelatedTrace; + subExpressions?: string[]; + subTypesOfMQE?: string[]; } export type RelatedTrace = { duration: DurationTime; @@ -70,10 +75,11 @@ export type MetricConfigOpt = { unit?: string; label?: string; calculation?: string; - labelsIndex: string; - sortOrder: string; + labelsIndex?: string; + sortOrder?: string; topN?: number; index?: number; + detailLabel?: string; }; export interface WidgetConfig { diff --git a/src/types/ebpf.d.ts b/src/types/ebpf.d.ts index 9a4e524a..36ed2082 100644 --- a/src/types/ebpf.d.ts +++ b/src/types/ebpf.d.ts @@ -28,12 +28,31 @@ export interface EBPFTaskList { taskId: string; serviceName: string; serviceId: string; + serviceInstanceId: string; + serviceInstanceName: string; + processId: string; + processName: string; processLabels: string[]; taskStartTime: number; fixedTriggerDuration: number; targetType: string; createTime: number; triggerType: string; + continuousProfilingCauses: ProfilingCause[]; +} + +interface ProfilingCause { + type: string; + singleValue: { + threshold: number; + current: number; + }; + uri: { + uriRegex: string; + uriPath: string; + threshold: number; + current: number; + }; } export interface EBPFProfilingSchedule { diff --git a/src/types/selector.d.ts b/src/types/selector.d.ts index f4a63a28..f1b4a3f4 100644 --- a/src/types/selector.d.ts +++ b/src/types/selector.d.ts @@ -21,6 +21,7 @@ export type Service = { layers?: string[]; normal?: boolean; group?: string; + merge?: string; }; export type Instance = { @@ -30,12 +31,14 @@ export type Instance = { instanceUUID?: string; attributes?: { name: string; value: string }[]; id?: string; + merge?: boolean; }; export type Endpoint = { id?: string; label: string; value: string; + merge?: string; }; export type Service = { diff --git a/src/views/dashboard/Widget.vue b/src/views/dashboard/Widget.vue index e3f480bb..44ee041f 100644 --- a/src/views/dashboard/Widget.vue +++ b/src/views/dashboard/Widget.vue @@ -35,6 +35,11 @@ limitations under the License. --> metrics: config.metrics, metricTypes: config.metricTypes, metricConfig: config.metricConfig, + metricMode: config.metricMode, + expressions: config.expressions || [], + typesOfMQE: typesOfMQE || [], + subExpressions: config.subExpressions || [], + subTypesOfMQE: config.subTypesOfMQE || [], }" :needQuery="true" /> @@ -51,10 +56,12 @@ limitations under the License. --> import { useRoute } from "vue-router"; import { useSelectorStore } from "@/store/modules/selectors"; import { useDashboardStore } from "@/store/modules/dashboard"; - import { useQueryProcessor, useSourceProcessor, useGetMetricEntity } from "@/hooks/useMetricsProcessor"; + import { useQueryProcessor, useSourceProcessor } from "@/hooks/useMetricsProcessor"; + import { useExpressionsQueryProcessor } from "@/hooks/useExpressionsProcessor"; import graphs from "./graphs"; import { EntityType } from "./data"; import timeFormat from "@/utils/timeFormat"; + import { MetricModes } from "./data"; export default defineComponent({ name: "WidgetPage", @@ -73,6 +80,7 @@ limitations under the License. --> const dashboardStore = useDashboardStore(); const title = computed(() => (config.value.widget && config.value.widget.title) || ""); const tips = computed(() => (config.value.widget && config.value.widget.tips) || ""); + const typesOfMQE = ref([]); init(); async function init() { @@ -122,10 +130,21 @@ limitations under the License. --> } } async function queryMetrics() { - const metricTypes = config.value.metricTypes || []; - const metrics = config.value.metrics || []; - const catalog = await useGetMetricEntity(metrics[0], metricTypes[0]); - const params = await useQueryProcessor({ ...config.value, catalog }); + const isExpression = config.value.metricMode === MetricModes.Expression; + if (isExpression) { + loading.value = true; + const params = await useExpressionsQueryProcessor({ + metrics: config.value.expressions || [], + metricConfig: config.value.metricConfig || [], + subExpressions: config.value.subExpressions || [], + }); + + loading.value = false; + source.value = params.source || {}; + typesOfMQE.value = params.typesOfMQE; + return; + } + const params = await useQueryProcessor({ ...config.value }); if (!params) { source.value = {}; return; @@ -141,7 +160,7 @@ limitations under the License. --> metricTypes: config.value.metricTypes || [], metricConfig: config.value.metricConfig || [], }; - source.value = useSourceProcessor(json, d); + source.value = await useSourceProcessor(json, d); } watch( () => appStoreWithOut.durationTime, @@ -157,6 +176,7 @@ limitations under the License. --> config, title, tips, + typesOfMQE, }; }, }); @@ -171,7 +191,7 @@ limitations under the License. --> .widget-chart { background: #fff; - box-shadow: 0px 1px 4px 0px #00000029; + box-shadow: 0 1px 4px 0 #00000029; border-radius: 3px; padding: 5px; width: 100%; diff --git a/src/views/dashboard/components/WidgetLink.vue b/src/views/dashboard/components/WidgetLink.vue index 584c24a4..c92d4411 100644 --- a/src/views/dashboard/components/WidgetLink.vue +++ b/src/views/dashboard/components/WidgetLink.vue @@ -59,6 +59,7 @@ limitations under the License. --> import copy from "@/utils/copy"; import { RefreshOptions } from "@/views/dashboard/data"; import { TimeType } from "@/constants/data"; + import { MetricModes } from "../data"; const { t } = useI18n(); const appStore = useAppStoreWithOut(); @@ -91,7 +92,8 @@ limitations under the License. --> step: appStore.durationRow.step, utc: appStore.utc, }); - const { widget, graph, metrics, metricTypes, metricConfig } = dashboardStore.selectedGrid; + const { widget, graph, metrics, metricTypes, metricConfig, metricMode, expressions, typesOfMQE, subExpressions } = + dashboardStore.selectedGrid; const c = (metricConfig || []).map((d: any) => { const t: any = {}; if (d.label) { @@ -105,11 +107,20 @@ limitations under the License. --> const opt: any = { type: dashboardStore.selectedGrid.type, graph: graph, - metrics: metrics, - metricTypes: metricTypes, + metricMode, metricConfig: c, height: dashboardStore.selectedGrid.h * 20 + 60, }; + if (metricMode === MetricModes.Expression) { + opt.expressions = expressions; + opt.typesOfMQE = typesOfMQE; + if (subExpressions && subExpressions.length) { + opt.subExpressions = subExpressions; + } + } else { + opt.metrics = metrics; + opt.metricTypes = metricTypes; + } if (widget) { opt.widget = { title: encodeURIComponent(widget.title || ""), diff --git a/src/views/dashboard/configuration/ContinuousProfiling.vue b/src/views/dashboard/configuration/ContinuousProfiling.vue new file mode 100644 index 00000000..77b77846 --- /dev/null +++ b/src/views/dashboard/configuration/ContinuousProfiling.vue @@ -0,0 +1,108 @@ + +
+
{{ t("instanceDashboards") }}
+ +
+
+
{{ t("processDashboards") }}
+ +
+ + + + diff --git a/src/views/dashboard/configuration/Widget.vue b/src/views/dashboard/configuration/Widget.vue index 812b4128..63c3f4f3 100644 --- a/src/views/dashboard/configuration/Widget.vue +++ b/src/views/dashboard/configuration/Widget.vue @@ -38,8 +38,14 @@ limitations under the License. --> metricTypes: dashboardStore.selectedGrid.metricTypes, metricConfig: dashboardStore.selectedGrid.metricConfig, relatedTrace: dashboardStore.selectedGrid.relatedTrace, + metricMode: dashboardStore.selectedGrid.metricMode, + expressions: dashboardStore.selectedGrid.expressions || [], + typesOfMQE: dashboardStore.selectedGrid.typesOfMQE || [], + subExpressions: dashboardStore.selectedGrid.subExpressions || [], + subTypesOfMQE: dashboardStore.selectedGrid.subTypesOfMQE || [], }" :needQuery="true" + @expressionTips="getErrors" />
{{ t("noData") }} @@ -49,7 +55,7 @@ limitations under the License. -->
- + @@ -83,6 +89,7 @@ limitations under the License. --> import type { Option } from "@/types/app"; import graphs from "../graphs"; import CustomOptions from "./widget/index"; + import { MetricModes } from "../data"; export default defineComponent({ name: "WidgetEdit", @@ -96,6 +103,8 @@ limitations under the License. --> const dashboardStore = useDashboardStore(); const appStoreWithOut = useAppStoreWithOut(); const loading = ref(false); + const errors = ref([]); + const subErrors = ref([]); const states = reactive<{ activeNames: string; source: unknown; @@ -122,12 +131,34 @@ limitations under the License. --> states.source = source; } + function getErrors(params: { tips: string[]; subTips: string[] }) { + errors.value = params.tips; + subErrors.value = params.subTips; + } + function setLoading(load: boolean) { loading.value = load; } function applyConfig() { dashboardStore.setConfigPanel(false); + const { metricMode } = dashboardStore.selectedGrid; + let p = {}; + if (metricMode === MetricModes.Expression) { + p = { + metrics: [], + metricTypes: [], + }; + } else { + p = { + expressions: [], + typesOfMQE: [], + }; + } + dashboardStore.selectWidget({ + ...dashboardStore.selectedGrid, + ...p, + }); dashboardStore.setConfigs(dashboardStore.selectedGrid); } @@ -146,12 +177,15 @@ limitations under the License. --> applyConfig, cancelConfig, getSource, + getErrors, setLoading, widget, graph, title, tips, hasAssociate, + errors, + subErrors, }; }, }); @@ -188,7 +222,7 @@ limitations under the License. --> .render-chart { padding: 5px; - height: 400px; + height: 420px; width: 100%; } diff --git a/src/views/dashboard/configuration/index.ts b/src/views/dashboard/configuration/index.ts index 1fb47e4f..aadb8f33 100644 --- a/src/views/dashboard/configuration/index.ts +++ b/src/views/dashboard/configuration/index.ts @@ -21,6 +21,7 @@ import Topology from "./Topology.vue"; import Event from "./Event.vue"; import TimeRange from "./TimeRange.vue"; import ThirdPartyApp from "./ThirdPartyApp.vue"; +import ContinuousProfiling from "./ContinuousProfiling.vue"; export default { Text, @@ -29,4 +30,5 @@ export default { Event, TimeRange, ThirdPartyApp, + ContinuousProfiling, }; diff --git a/src/views/dashboard/configuration/widget/graph-styles/Line.vue b/src/views/dashboard/configuration/widget/graph-styles/Line.vue index ff92b8ce..5f421eb3 100644 --- a/src/views/dashboard/configuration/widget/graph-styles/Line.vue +++ b/src/views/dashboard/configuration/widget/graph-styles/Line.vue @@ -50,12 +50,13 @@ limitations under the License. --> import { useI18n } from "vue-i18n"; import { useDashboardStore } from "@/store/modules/dashboard"; import Legend from "./components/Legend.vue"; + import { isDef } from "@/utils/is"; const { t } = useI18n(); const dashboardStore = useDashboardStore(); const graph = computed(() => dashboardStore.selectedGrid.graph || {}); const smooth = ref(graph.value.smooth); - const showSymbol = ref(graph.value.showSymbol); + const showSymbol = ref(isDef(graph.value.showSymbol) ? graph.value.showSymbol : true); const step = ref(graph.value.step); function updateConfig(param: { [key: string]: unknown }) { diff --git a/src/views/dashboard/configuration/widget/metric/Index.vue b/src/views/dashboard/configuration/widget/metric/Index.vue index c88b25be..9a6e486b 100644 --- a/src/views/dashboard/configuration/widget/metric/Index.vue +++ b/src/views/dashboard/configuration/widget/metric/Index.vue @@ -26,23 +26,50 @@ limitations under the License. --> />
{{ t("metrics") }}
-
- - + +
+ {{ t("summary") }} + {{ t("detail") }} +
+
+ +
+ {{ metric }} +
+
+ {{ states.subMetrics[index] }} +
+
+ + + + - + /> +
+ {{ states.tips[index] }} +
+
+ {{ (errors || [])[index] }} +
+
+ {{ (subErrors || [])[index] }} +
{{ t("visualization") }}
@@ -68,9 +109,7 @@ limitations under the License. --> v-for="(type, index) in setVisTypes" :key="index" @click="changeChartType(type)" - :class="{ - active: type.value === graph.type, - }" + :class="{ active: type.value === graph.type }" > {{ type.label }} @@ -78,6 +117,7 @@ limitations under the License. --> diff --git a/src/views/dashboard/configuration/widget/metric/Standard.vue b/src/views/dashboard/configuration/widget/metric/Standard.vue index 3381bb27..4e7ad7ec 100644 --- a/src/views/dashboard/configuration/widget/metric/Standard.vue +++ b/src/views/dashboard/configuration/widget/metric/Standard.vue @@ -28,13 +28,13 @@ limitations under the License. --> " />
-
+
{{ t("labels") }}
-
+
+ {{ t("detailLabel") }} + +
+
{{ t("labelsIndex") }} placeholder="auto" @change=" updateConfig(index, { - labelsIndex: encodeURIComponent(currentMetric.labelsIndex), + labelsIndex: encodeURIComponent(currentMetric.labelsIndex || ''), }) " />
-
+
{{ t("aggregation") }} type="number" :min="1" :max="100" - @change="changeConfigs(index, { topN: currentMetric.topN || 10 })" + @change="changeConfigs(index, { topN: Number(currentMetric.topN) || 10 })" />
@@ -94,7 +108,7 @@ limitations under the License. --> import { ref, watch, computed } from "vue"; import type { PropType } from "vue"; import { useI18n } from "vue-i18n"; - import { SortOrder, CalculationOpts } from "../../../data"; + import { SortOrder, CalculationOpts, MetricModes } from "../../../data"; import { useDashboardStore } from "@/store/modules/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard"; import { ListChartTypes, ProtocolTypes } from "../../../data"; @@ -110,12 +124,15 @@ limitations under the License. --> const { t } = useI18n(); const emit = defineEmits(["update"]); const dashboardStore = useDashboardStore(); + const isExpression = ref(dashboardStore.selectedGrid.metricMode === MetricModes.Expression); const currentMetric = ref({ ...props.currentMetricConfig, topN: props.currentMetricConfig.topN || 10, }); - const metricTypes = dashboardStore.selectedGrid.metricTypes || []; - const metricType = computed(() => (dashboardStore.selectedGrid.metricTypes || [])[props.index]); + const metricTypes = computed( + () => (isExpression.value ? dashboardStore.selectedGrid.typesOfMQE : dashboardStore.selectedGrid.metricTypes) || [], + ); + const metricType = computed(() => metricTypes.value[props.index]); const hasLabel = computed(() => { const graph = dashboardStore.selectedGrid.graph || {}; return ( @@ -123,11 +140,16 @@ limitations under the License. --> [ProtocolTypes.ReadLabeledMetricsValues, ProtocolTypes.ReadMetricsValues].includes(metricType.value) ); }); + const isList = computed(() => { + const graph = dashboardStore.selectedGrid.graph || {}; + return ListChartTypes.includes(graph.type); + }); const isTopn = computed(() => [ProtocolTypes.SortMetrics, ProtocolTypes.ReadSampledRecords, ProtocolTypes.ReadRecords].includes( - metricTypes[props.index], + metricTypes.value[props.index], ), ); + function updateConfig(index: number, param: { [key: string]: string }) { const key = Object.keys(param)[0]; if (!key) { @@ -148,9 +170,10 @@ limitations under the License. --> watch( () => props.currentMetricConfig, () => { + isExpression.value = dashboardStore.selectedGrid.metricMode === MetricModes.Expression; currentMetric.value = { ...props.currentMetricConfig, - topN: props.currentMetricConfig.topN || 10, + topN: Number(props.currentMetricConfig.topN) || 10, }; }, ); diff --git a/src/views/dashboard/controls/ContinuousProfiling.vue b/src/views/dashboard/controls/ContinuousProfiling.vue new file mode 100644 index 00000000..ee1c1650 --- /dev/null +++ b/src/views/dashboard/controls/ContinuousProfiling.vue @@ -0,0 +1,100 @@ + + + + diff --git a/src/views/dashboard/controls/Tab.vue b/src/views/dashboard/controls/Tab.vue index 2fdbfd69..6f7f807d 100644 --- a/src/views/dashboard/controls/Tab.vue +++ b/src/views/dashboard/controls/Tab.vue @@ -285,7 +285,7 @@ limitations under the License. --> } .tab-name { - max-width: 110px; + max-width: 130px; height: 20px; line-height: 20px; outline: none; @@ -348,7 +348,7 @@ limitations under the License. --> .vue-grid-item:not(.vue-grid-placeholder) { background: #fff; - box-shadow: 0px 1px 4px 0px #00000029; + box-shadow: 0 1px 4px 0 #00000029; border-radius: 3px; } diff --git a/src/views/dashboard/controls/TaskTimeline.vue b/src/views/dashboard/controls/TaskTimeline.vue new file mode 100644 index 00000000..4651abe6 --- /dev/null +++ b/src/views/dashboard/controls/TaskTimeline.vue @@ -0,0 +1,92 @@ + + + + diff --git a/src/views/dashboard/controls/Widget.vue b/src/views/dashboard/controls/Widget.vue index d52ebc96..c13f90fa 100644 --- a/src/views/dashboard/controls/Widget.vue +++ b/src/views/dashboard/controls/Widget.vue @@ -59,6 +59,11 @@ limitations under the License. --> filters: data.filters || {}, relatedTrace: data.relatedTrace || {}, associate: data.associate || [], + metricMode: data.metricMode, + expressions: data.expressions || [], + typesOfMQE: typesOfMQE || [], + subExpressions: data.subExpressions || [], + subTypesOfMQE: data.subTypesOfMQE || [], }" :needQuery="needQuery" @click="clickHandle" @@ -76,10 +81,12 @@ limitations under the License. --> import { useSelectorStore } from "@/store/modules/selectors"; import graphs from "../graphs"; import { useI18n } from "vue-i18n"; - import { useQueryProcessor, useSourceProcessor, useGetMetricEntity } from "@/hooks/useMetricsProcessor"; + import { useQueryProcessor, useSourceProcessor } from "@/hooks/useMetricsProcessor"; + import { useExpressionsQueryProcessor } from "@/hooks/useExpressionsProcessor"; import { EntityType, ListChartTypes } from "../data"; import type { EventParams } from "@/types/dashboard"; import getDashboard from "@/hooks/useDashboardsSession"; + import { MetricModes } from "../data"; const props = { data: { @@ -107,16 +114,28 @@ limitations under the License. --> const graph = computed(() => props.data.graph || {}); const widget = computed(() => props.data.widget || {}); const isList = computed(() => ListChartTypes.includes((props.data.graph && props.data.graph.type) || "")); + const typesOfMQE = ref([]); if ((props.needQuery || !dashboardStore.currentDashboard.id) && !isList.value) { queryMetrics(); } async function queryMetrics() { - const metricTypes: string[] = props.data.metricTypes || []; - const metrics = props.data.metrics || []; - const catalog = await useGetMetricEntity(metrics[0], metricTypes[0]); - const params = await useQueryProcessor({ ...props.data, catalog }); + const isExpression = props.data.metricMode === MetricModes.Expression; + + if (isExpression) { + loading.value = true; + const e = { + metrics: props.data.expressions || [], + metricConfig: props.data.metricConfig || [], + }; + const params = (await useExpressionsQueryProcessor(e)) || {}; + loading.value = false; + state.source = params.source || {}; + typesOfMQE.value = params.typesOfMQE; + return; + } + const params = await useQueryProcessor({ ...props.data }); if (!params) { state.source = {}; @@ -133,7 +152,7 @@ limitations under the License. --> metricTypes: props.data.metricTypes || [], metricConfig: props.data.metricConfig || [], }; - state.source = useSourceProcessor(json, d); + state.source = await useSourceProcessor(json, d); } function removeWidget() { @@ -169,7 +188,7 @@ limitations under the License. --> dashboardStore.selectWidget(props.data); } watch( - () => [props.data.metricTypes, props.data.metrics], + () => [props.data.metricTypes, props.data.metrics, props.data.expressions], () => { if (!dashboardStore.selectedGrid) { return; @@ -190,7 +209,7 @@ limitations under the License. --> if (isList.value) { return; } - if (dashboardStore.entity === EntityType[0].value || dashboardStore.entity === EntityType[4].value) { + if ([EntityType[0].value, EntityType[4].value].includes(dashboardStore.entity)) { queryMetrics(); } }, @@ -198,7 +217,7 @@ limitations under the License. --> watch( () => [selectorStore.currentPod, selectorStore.currentDestPod], () => { - if (dashboardStore.entity === EntityType[0].value || dashboardStore.entity === EntityType[7].value) { + if ([EntityType[0].value, EntityType[7].value, EntityType[8].value].includes(dashboardStore.entity)) { return; } if (isList.value) { @@ -210,10 +229,10 @@ limitations under the License. --> watch( () => [selectorStore.currentProcess, selectorStore.currentDestProcess], () => { - if (!(selectorStore.currentDestProcess && selectorStore.currentProcess)) { + if (isList.value) { return; } - if (dashboardStore.entity === EntityType[7].value) { + if ([EntityType[7].value, EntityType[8].value].includes(dashboardStore.entity)) { queryMetrics(); } }, @@ -242,6 +261,7 @@ limitations under the License. --> t, graph, widget, + typesOfMQE, clickHandle, }; }, diff --git a/src/views/dashboard/controls/index.ts b/src/views/dashboard/controls/index.ts index 6b4c5fde..01329d33 100644 --- a/src/views/dashboard/controls/index.ts +++ b/src/views/dashboard/controls/index.ts @@ -25,8 +25,10 @@ import Ebpf from "./Ebpf.vue"; import DemandLog from "./DemandLog.vue"; import Event from "./Event.vue"; import NetworkProfiling from "./NetworkProfiling.vue"; +import ContinuousProfiling from "./ContinuousProfiling.vue"; import TimeRange from "./TimeRange.vue"; import ThirdPartyApp from "./ThirdPartyApp.vue"; +import TaskTimeline from "./TaskTimeline.vue"; export default { Tab, @@ -40,6 +42,8 @@ export default { DemandLog, Event, NetworkProfiling, + ContinuousProfiling, TimeRange, ThirdPartyApp, + TaskTimeline, }; diff --git a/src/views/dashboard/controls/tab.ts b/src/views/dashboard/controls/tab.ts index b6194609..008c8081 100644 --- a/src/views/dashboard/controls/tab.ts +++ b/src/views/dashboard/controls/tab.ts @@ -24,8 +24,10 @@ import Ebpf from "./Ebpf.vue"; import DemandLog from "./DemandLog.vue"; import Event from "./Event.vue"; import NetworkProfiling from "./NetworkProfiling.vue"; +import ContinuousProfiling from "./ContinuousProfiling.vue"; import TimeRange from "./TimeRange.vue"; import ThirdPartyApp from "./ThirdPartyApp.vue"; +import TaskTimeline from "./TaskTimeline.vue"; export default { Widget, @@ -40,4 +42,6 @@ export default { NetworkProfiling, TimeRange, ThirdPartyApp, + ContinuousProfiling, + TaskTimeline, }; diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts index 2ab85dce..28c0affb 100644 --- a/src/views/dashboard/data.ts +++ b/src/views/dashboard/data.ts @@ -56,6 +56,15 @@ export enum ProtocolTypes { ReadMetricsValues = "readMetricsValues", ReadMetricsValue = "readMetricsValue", } + +export enum ExpressionResultType { + UNKNOWN = "UNKNOWN", + SINGLE_VALUE = "SINGLE_VALUE", + TIME_SERIES_VALUES = "TIME_SERIES_VALUES", + SORTED_LIST = "SORTED_LIST", + RECORD_LIST = "RECORD_LIST", +} + export const DefaultGraphConfig: { [key: string]: any } = { Bar: { type: "Bar", @@ -65,7 +74,7 @@ export const DefaultGraphConfig: { [key: string]: any } = { type: "Line", step: false, smooth: false, - showSymbol: false, + showSymbol: true, showXAxis: true, showYAxis: true, }, @@ -167,6 +176,7 @@ export const EntityType = [ }, { value: "EndpointRelation", label: "Endpoint Relation", key: 4 }, { value: "ProcessRelation", label: "Process Relation", key: 5 }, + { value: "Process", label: "Process", key: 6 }, ]; export const ListEntity: any = { InstanceList: EntityType[3].value, @@ -194,6 +204,7 @@ export const ServiceTools = [ { name: "merge", content: "Add Trace", id: "addTrace" }, { name: "timeline", content: "Add Trace Profiling", id: "addProfile" }, { name: "insert_chart", content: "Add eBPF Profiling", id: "addEbpf" }, + { name: "continuous_profiling", content: "Add Continuous Profiling", id: "addContinuousProfiling" }, { name: "assignment", content: "Add Log", id: "addLog" }, { name: "demand", content: "Add On Demand Log", id: "addDemandLog" }, { name: "event", content: "Add Event", id: "addEvent" }, @@ -225,10 +236,16 @@ export const EndpointTools = [ { name: "add_iframe", content: "Add Iframe", id: "addIframe" }, ]; export const ProcessTools = [ + { name: "playlist_add", content: "Add Widget", id: "addWidget" }, + { name: "all_inbox", content: "Add Tabs", id: "addTab" }, + { name: "task_timeline", content: "Add Task Timeline", id: "addTaskTimeline" }, + { name: "library_books", content: "Add Text", id: "addText" }, + { name: "add_iframe", content: "Add Iframe", id: "addIframe" }, +]; +export const ProcessRelationTools = [ { name: "playlist_add", content: "Add Widget", id: "addWidget" }, { name: "all_inbox", content: "Add Tabs", id: "addTab" }, { name: "library_books", content: "Add Text", id: "addText" }, - { name: "time_range", content: "Add Time Range Text", id: "addTimeRange" }, { name: "add_iframe", content: "Add Iframe", id: "addIframe" }, ]; export const ServiceRelationTools = [ @@ -322,3 +339,8 @@ export const RefreshOptions = [ { label: "Last 8 hours", value: "8", step: "HOUR" }, { label: "Last 7 days", value: "7", step: "DAY" }, ]; + +export enum MetricModes { + Expression = "Expression", + General = "General", +} diff --git a/src/views/dashboard/graphs/Bar.vue b/src/views/dashboard/graphs/Bar.vue index 302c4c69..98c2bd02 100644 --- a/src/views/dashboard/graphs/Bar.vue +++ b/src/views/dashboard/graphs/Bar.vue @@ -23,6 +23,7 @@ limitations under the License. --> import type { PropType } from "vue"; import type { BarConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard"; import useLegendProcess from "@/hooks/useLegendProcessor"; + import Legend from "./components/Legend.vue"; /*global defineProps, defineEmits */ const emits = defineEmits(["click"]); diff --git a/src/views/dashboard/graphs/Card.vue b/src/views/dashboard/graphs/Card.vue index 56c63c2e..b9670cd4 100644 --- a/src/views/dashboard/graphs/Card.vue +++ b/src/views/dashboard/graphs/Card.vue @@ -15,7 +15,7 @@ limitations under the License. --> diff --git a/src/views/dashboard/graphs/InstanceList.vue b/src/views/dashboard/graphs/InstanceList.vue index a3915b5c..d04d47ff 100644 --- a/src/views/dashboard/graphs/InstanceList.vue +++ b/src/views/dashboard/graphs/InstanceList.vue @@ -17,7 +17,7 @@ limitations under the License. -->