bump vite to 4.x

This commit is contained in:
Fine 2022-12-12 16:51:38 +08:00
parent f1ed9c7bd5
commit 2c8b2b9e1e
194 changed files with 20657 additions and 37164 deletions

34
.eslintrc.cjs Normal file
View File

@ -0,0 +1,34 @@
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier",
],
overrides: [
{
files: ["cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}"],
extends: ["plugin:cypress/recommended"],
},
],
parserOptions: {
ecmaVersion: "latest",
},
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"vue/script-setup-uses-vars": "error",
"@typescript-eslint/ban-ts-ignore'": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-this-alias": "off",
"vue/multi-word-component-names": "off",
"@typescript-eslint/consistent-type-imports": "error",
},
};

View File

@ -1,53 +0,0 @@
/**
* 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.
*/
const { defineConfig } = require('eslint-define-config');
module.exports = defineConfig({
root: true,
env: {
browser: true,
node: true,
es6: true,
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
},
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
'plugin:jest/recommended',
],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"vue/script-setup-uses-vars": "error",
"@typescript-eslint/ban-ts-ignore'": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-this-alias": "off"
}
});

11
.gitignore vendored
View File

@ -31,23 +31,25 @@ pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
node_modules node_modules
.DS_Store
dist dist
node
dist-ssr dist-ssr
coverage
*.local *.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files # Editor directories and files
.vscode/* .vscode/*
!.vscode/extensions.json !.vscode/extensions.json
.idea .idea
.DS_Store
*.suo *.suo
*.ntvs* *.ntvs*
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
# Editor directories and files # Editor directories and files
.idea .idea
.vscode .vscode
@ -56,6 +58,3 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
/tests/e2e/videos/
/tests/e2e/screenshots/

View File

@ -1,32 +1,32 @@
module.exports = { module.exports = {
ignores: [(commit) => commit.includes('init')], ignores: [(commit) => commit.includes("init")],
extends: ['@commitlint/config-conventional'], extends: ["@commitlint/config-conventional"],
rules: { rules: {
'body-leading-blank': [2, 'always'], "body-leading-blank": [2, "always"],
'footer-leading-blank': [1, 'always'], "footer-leading-blank": [1, "always"],
'header-max-length': [2, 'always', 108], "header-max-length": [2, "always", 108],
'subject-empty': [2, 'never'], "subject-empty": [2, "never"],
'type-empty': [2, 'never'], "type-empty": [2, "never"],
'subject-case': [0], "subject-case": [0],
'type-enum': [ "type-enum": [
2, 2,
'always', "always",
[ [
'feat', "feat",
'fix', "fix",
'perf', "perf",
'style', "style",
'docs', "docs",
'test', "test",
'refactor', "refactor",
'build', "build",
'ci', "ci",
'chore', "chore",
'revert', "revert",
'wip', "wip",
'workflow', "workflow",
'types', "types",
'release', "release",
], ],
], ],
}, },

8
cypress.config.ts Normal file
View File

@ -0,0 +1,8 @@
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
specPattern: "cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}",
baseUrl: "http://localhost:4173",
},
});

View File

@ -0,0 +1,8 @@
// https://docs.cypress.io/api/introduction/api.html
describe("My First Test", () => {
it("visits the app root url", () => {
cy.visit("/");
cy.contains("h1", "You did it!");
});
});

10
cypress/e2e/tsconfig.json Normal file
View File

@ -0,0 +1,10 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["./**/*", "../support/**/*"],
"compilerOptions": {
"isolatedModules": false,
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
}
}

View File

@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@ -0,0 +1,39 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
export {};

20
cypress/support/e2e.ts Normal file
View File

@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./commands";
// Alternatively you can use CommonJS syntax:
// require('./commands')

35049
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,16 @@
"version": "9.3.0", "version": "9.3.0",
"private": true, "private": true,
"scripts": { "scripts": {
"prepare": "husky install",
"dev": "vite", "dev": "vite",
"build": "vue-tsc && vite build", "build": "run-p type-check build-only",
"preview": "vite preview", "preview": "vite preview",
"prepare": "husky install" "test:unit": "vitest --environment jsdom --root src/",
"test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
}, },
"dependencies": { "dependencies": {
"axios": "^0.24.0", "axios": "^0.24.0",
@ -17,52 +23,55 @@
"element-plus": "^2.0.2", "element-plus": "^2.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"monaco-editor": "^0.34.1", "monaco-editor": "^0.34.1",
"pinia": "^2.0.5",
"vis-timeline": "^7.5.1", "vis-timeline": "^7.5.1",
"vue": "^3.0.0", "pinia": "^2.0.28",
"vue": "^3.2.45",
"vue-router": "^4.1.6",
"vue-grid-layout": "^3.0.0-beta1", "vue-grid-layout": "^3.0.0-beta1",
"vue-i18n": "^9.1.9", "vue-i18n": "^9.1.9",
"vue-router": "^4.0.0-0",
"vue-types": "^4.1.1" "vue-types": "^4.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/d3": "^7.1.0", "@types/d3": "^7.1.0",
"@types/d3-tip": "^3.5.5", "@types/d3-tip": "^3.5.5",
"@types/echarts": "^4.9.12", "@types/echarts": "^4.9.12",
"@types/jest": "^24.0.19",
"@types/lodash": "^4.14.179", "@types/lodash": "^4.14.179",
"@types/three": "^0.131.0", "@types/three": "^0.131.0",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vitejs/plugin-vue": "^3.2.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^2.0.0-0",
"babel-jest": "^24.9.0",
"eslint": "^6.8.0",
"eslint-define-config": "^1.12.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.20.0",
"husky": "^7.0.4", "husky": "^7.0.4",
"lint-staged": "^12.1.3", "lint-staged": "^12.1.3",
"node-sass": "^8.0.0", "node-sass": "^8.0.0",
"postcss-html": "^1.3.0", "postcss-html": "^1.3.0",
"postcss-scss": "^4.0.2", "postcss-scss": "^4.0.2",
"prettier": "^2.2.1",
"sass": "^1.56.1", "sass": "^1.56.1",
"stylelint": "^14.1.0", "stylelint": "^14.1.0",
"stylelint-config-html": "^1.0.0", "stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3", "stylelint-config-prettier": "^9.0.3",
"stylelint-config-standard": "^24.0.0", "stylelint-config-standard": "^24.0.0",
"stylelint-order": "^5.0.0", "stylelint-order": "^5.0.0",
"typescript": "~4.4.4",
"unplugin-auto-import": "^0.7.0", "unplugin-auto-import": "^0.7.0",
"unplugin-vue-components": "^0.19.2", "unplugin-vue-components": "^0.19.2",
"vite": "^3.2.3",
"vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-monaco-editor": "^1.1.0",
"vue-jest": "^5.0.0-0", "@rushstack/eslint-patch": "^1.1.4",
"vue-tsc": "^1.0.9" "@types/jsdom": "^20.0.1",
"@types/node": "^18.11.12",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0",
"@vue/test-utils": "^2.2.6",
"@vue/tsconfig": "^0.1.3",
"cypress": "^12.0.2",
"eslint": "^8.22.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-vue": "^9.3.0",
"jsdom": "^20.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"start-server-and-test": "^1.15.2",
"typescript": "~4.7.4",
"vite": "^4.0.0",
"vitest": "^0.25.6",
"vue-tsc": "^1.0.12"
}, },
"browserslist": [ "browserslist": [
"> 1%", "> 1%",

View File

@ -2,8 +2,8 @@ module.exports = {
printWidth: 100, printWidth: 100,
semi: true, semi: true,
vueIndentScriptAndStyle: true, vueIndentScriptAndStyle: true,
trailingComma: 'all', trailingComma: "all",
proseWrap: 'never', proseWrap: "never",
htmlWhitespaceSensitivity: 'strict', htmlWhitespaceSensitivity: "strict",
endOfLine: 'auto', endOfLine: "auto",
}; };

View File

@ -24,9 +24,7 @@ function capitalizeFirstLetter(str: string) {
} }
function validateFileName(str: string): string | undefined { function validateFileName(str: string): string | undefined {
if (/^\S+\.png$/.test(str)) { if (/^\S+\.png$/.test(str)) {
return str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => return str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => capitalizeFirstLetter($1));
capitalizeFirstLetter($1)
);
} }
} }
Object.keys(requireComponent).forEach((filePath: string) => { Object.keys(requireComponent).forEach((filePath: string) => {

View File

@ -15,18 +15,10 @@ limitations under the License. -->
<template> <template>
<div :class="`${state.pre}`"> <div :class="`${state.pre}`">
<div :class="`${state.pre}-head`"> <div :class="`${state.pre}-head`">
<a <a :class="`${state.pre}-prev-decade-btn`" v-show="state.showYears" @click="state.year -= 10">
:class="`${state.pre}-prev-decade-btn`"
v-show="state.showYears"
@click="state.year -= 10"
>
<Icon size="sm" iconName="angle-double-left" /> <Icon size="sm" iconName="angle-double-left" />
</a> </a>
<a <a :class="`${state.pre}-prev-year-btn`" v-show="!state.showYears" @click="state.year--">
:class="`${state.pre}-prev-year-btn`"
v-show="!state.showYears"
@click="state.year--"
>
<Icon size="sm" iconName="angle-double-left" /> <Icon size="sm" iconName="angle-double-left" />
</a> </a>
<a <a
@ -36,9 +28,7 @@ limitations under the License. -->
> >
<Icon size="middle" iconName="chevron-left" /> <Icon size="middle" iconName="chevron-left" />
</a> </a>
<a :class="`${state.pre}-year-select`" v-show="state.showYears">{{ <a :class="`${state.pre}-year-select`" v-show="state.showYears">{{ ys + "-" + ye }}</a>
ys + "-" + ye
}}</a>
<template v-if="local.yearSuffix"> <template v-if="local.yearSuffix">
<a <a
:class="`${state.pre}-year-select`" :class="`${state.pre}-year-select`"
@ -74,40 +64,22 @@ limitations under the License. -->
> >
<Icon size="middle" iconName="chevron-right" /> <Icon size="middle" iconName="chevron-right" />
</a> </a>
<a <a :class="`${state.pre}-next-year-btn`" v-show="!state.showYears" @click="state.year++">
:class="`${state.pre}-next-year-btn`"
v-show="!state.showYears"
@click="state.year++"
>
<Icon size="sm" iconName="angle-double-right" /> <Icon size="sm" iconName="angle-double-right" />
</a> </a>
<a <a :class="`${state.pre}-next-decade-btn`" v-show="state.showYears" @click="state.year += 10">
:class="`${state.pre}-next-decade-btn`"
v-show="state.showYears"
@click="state.year += 10"
>
<Icon size="sm" iconName="angle-double-right" /> <Icon size="sm" iconName="angle-double-right" />
</a> </a>
</div> </div>
<div :class="`${state.pre}-body`"> <div :class="`${state.pre}-body`">
<div :class="`${state.pre}-days`"> <div :class="`${state.pre}-days`">
<a :class="`${state.pre}-week`" v-for="i in local.weeks" :key="i">{{ <a :class="`${state.pre}-week`" v-for="i in local.weeks" :key="i">{{ i }}</a>
i
}}</a>
<a <a
v-for="(j, i) in days" v-for="(j, i) in days"
@click="is($event) && ((state.day = j.i), ok(j))" @click="is($event) && ((state.day = j.i), ok(j))"
:class="[ :class="[
j.p || j.n ? `${state.pre}-date-out` : '', j.p || j.n ? `${state.pre}-date-out` : '',
status( status(j.y, j.m, j.i, state.hour, state.minute, state.second, 'YYYYMMDD'),
j.y,
j.m,
j.i,
state.hour,
state.minute,
state.second,
'YYYYMMDD'
),
]" ]"
:key="i" :key="i"
>{{ j.i }}</a >{{ j.i }}</a
@ -118,20 +90,10 @@ limitations under the License. -->
v-for="(i, j) in local.months" v-for="(i, j) in local.months"
@click=" @click="
is($event) && is($event) &&
((state.showMonths = state.m === 'M'), ((state.showMonths = state.m === 'M'), (state.month = j), state.m === 'M' && ok('m'))
(state.month = j),
state.m === 'M' && ok('m'))
" "
:class="[ :class="[
status( status(state.year, j, state.day, state.hour, state.minute, state.second, 'YYYYMM'),
state.year,
j,
state.day,
state.hour,
state.minute,
state.second,
'YYYYMM'
),
]" ]"
:key="j" :key="j"
>{{ i }}</a >{{ i }}</a
@ -142,21 +104,11 @@ limitations under the License. -->
v-for="(i, j) in years" v-for="(i, j) in years"
@click=" @click="
is($event) && is($event) &&
((state.showYears = state.m === 'Y'), ((state.showYears = state.m === 'Y'), (state.year = i), state.m === 'Y' && ok('y'))
(state.year = i),
state.m === 'Y' && ok('y'))
" "
:class="[ :class="[
j === 0 || j === 11 ? `${state.pre}-date-out` : '', j === 0 || j === 11 ? `${state.pre}-date-out` : '',
status( status(i, state.month, state.day, state.hour, state.minute, state.second, 'YYYY'),
i,
state.month,
state.day,
state.hour,
state.minute,
state.second,
'YYYY'
),
]" ]"
:key="j" :key="j"
>{{ i }}</a >{{ i }}</a
@ -167,10 +119,7 @@ limitations under the License. -->
<div class="scroll_hide calendar-overflow"> <div class="scroll_hide calendar-overflow">
<a <a
v-for="(j, i) in 24" v-for="(j, i) in 24"
@click=" @click="is($event) && ((state.showHours = false), (state.hour = i), ok('h'))"
is($event) &&
((state.showHours = false), (state.hour = i), ok('h'))
"
:class="[ :class="[
status( status(
state.year, state.year,
@ -179,7 +128,7 @@ limitations under the License. -->
i, i,
state.minute, state.minute,
state.second, state.second,
'YYYYMMDDHH' 'YYYYMMDDHH',
), ),
]" ]"
:key="i" :key="i"
@ -192,10 +141,7 @@ limitations under the License. -->
<div class="scroll_hide calendar-overflow"> <div class="scroll_hide calendar-overflow">
<a <a
v-for="(j, i) in 60" v-for="(j, i) in 60"
@click=" @click="is($event) && ((state.showMinutes = false), (state.minute = i), ok('h'))"
is($event) &&
((state.showMinutes = false), (state.minute = i), ok('h'))
"
:class="[ :class="[
status( status(
state.year, state.year,
@ -204,7 +150,7 @@ limitations under the License. -->
state.hour, state.hour,
i, i,
state.second, state.second,
'YYYYMMDDHHmm' 'YYYYMMDDHHmm',
), ),
]" ]"
:key="i" :key="i"
@ -217,10 +163,7 @@ limitations under the License. -->
<div class="scroll_hide calendar-overflow"> <div class="scroll_hide calendar-overflow">
<a <a
v-for="(j, i) in 60" v-for="(j, i) in 60"
@click=" @click="is($event) && ((state.showSeconds = false), (state.second = i), ok('h'))"
is($event) &&
((state.showSeconds = false), (state.second = i), ok('h'))
"
:class="[ :class="[
status( status(
state.year, state.year,
@ -229,7 +172,7 @@ limitations under the License. -->
state.hour, state.hour,
state.minute, state.minute,
i, i,
'YYYYMMDDHHmmss' 'YYYYMMDDHHmmss',
), ),
]" ]"
:key="i" :key="i"
@ -243,8 +186,7 @@ limitations under the License. -->
<a <a
:title="local.hourTip" :title="local.hourTip"
@click=" @click="
(state.showHours = !state.showHours), (state.showHours = !state.showHours), (state.showMinutes = state.showSeconds = false)
(state.showMinutes = state.showSeconds = false)
" "
:class="{ on: state.showHours }" :class="{ on: state.showHours }"
>{{ dd(state.hour) }}</a >{{ dd(state.hour) }}</a
@ -253,8 +195,7 @@ limitations under the License. -->
<a <a
:title="local.minuteTip" :title="local.minuteTip"
@click=" @click="
(state.showMinutes = !state.showMinutes), (state.showMinutes = !state.showMinutes), (state.showHours = state.showSeconds = false)
(state.showHours = state.showSeconds = false)
" "
:class="{ on: state.showMinutes }" :class="{ on: state.showMinutes }"
>{{ dd(state.minute) }}</a >{{ dd(state.minute) }}</a
@ -348,7 +289,7 @@ watch(
state.hour = time.hour; state.hour = time.hour;
state.minute = time.minute; state.minute = time.minute;
state.second = time.second; state.second = time.second;
} },
); );
const parse = (num: number): number => { const parse = (num: number): number => {
return num / 100000; return num / 100000;
@ -440,17 +381,10 @@ const status = (
hour: number, hour: number,
minute: number, minute: number,
second: number, second: number,
format: string format: string,
) => { ) => {
const maxDay = new Date(year, month + 1, 0).getDate(); const maxDay = new Date(year, month + 1, 0).getDate();
const time: any = new Date( const time: any = new Date(year, month, day > maxDay ? maxDay : day, hour, minute, second);
year,
month,
day > maxDay ? maxDay : day,
hour,
minute,
second
);
const t = parse(time); const t = parse(time);
const tf = (time?: Date, format?: any): string => { const tf = (time?: Date, format?: any): string => {
if (!time) { if (!time) {
@ -484,7 +418,7 @@ const status = (
}; };
return (format || props.format).replace( return (format || props.format).replace(
/Y+|M+|D+|H+|h+|m+|s+|S+/g, /Y+|M+|D+|H+|h+|m+|s+|S+/g,
(str: string) => map[str] (str: string) => map[str],
); );
}; };
const classObj: any = {}; const classObj: any = {};
@ -544,7 +478,7 @@ const ok = (info: any) => {
day ? Number(day) : state.day, day ? Number(day) : state.day,
state.hour, state.hour,
state.minute, state.minute,
state.second state.second,
); );
if (props.left && _time.getTime() / 100000 < end.value) { if (props.left && _time.getTime() / 100000 < end.value) {
emit("setDates", _time, "left"); emit("setDates", _time, "left");

View File

@ -19,11 +19,7 @@ limitations under the License. -->
<div class="tools" @click="associateMetrics" v-if="associate.length"> <div class="tools" @click="associateMetrics" v-if="associate.length">
{{ t("associateMetrics") }} {{ t("associateMetrics") }}
</div> </div>
<div <div class="tools" @click="viewTrace" v-if="relatedTrace && relatedTrace.enableRelate">
class="tools"
@click="viewTrace"
v-if="relatedTrace && relatedTrace.enableRelate"
>
{{ t("viewTrace") }} {{ t("viewTrace") }}
</div> </div>
</div> </div>
@ -40,19 +36,11 @@ limitations under the License. -->
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { import { watch, ref, onMounted, onBeforeUnmount, unref, computed } from "vue";
watch, import type { PropType, Ref } from "vue";
ref,
Ref,
onMounted,
onBeforeUnmount,
unref,
computed,
} from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { EventParams } from "@/types/app"; import type { EventParams } from "@/types/app";
import { Filters, RelatedTrace } from "@/types/dashboard"; import type { Filters, RelatedTrace } from "@/types/dashboard";
import { useECharts } from "@/hooks/useEcharts"; import { useECharts } from "@/hooks/useEcharts";
import { addResizeListener, removeResizeListener } from "@/utils/event"; import { addResizeListener, removeResizeListener } from "@/utils/event";
import Trace from "@/views/dashboard/related/trace/Index.vue"; import Trace from "@/views/dashboard/related/trace/Index.vue";
@ -64,9 +52,7 @@ const { t } = useI18n();
const chartRef = ref<Nullable<HTMLDivElement>>(null); const chartRef = ref<Nullable<HTMLDivElement>>(null);
const menus = ref<Nullable<HTMLDivElement>>(null); const menus = ref<Nullable<HTMLDivElement>>(null);
const visMenus = ref<boolean>(false); const visMenus = ref<boolean>(false);
const { setOptions, resize, getInstance } = useECharts( const { setOptions, resize, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>);
chartRef as Ref<HTMLDivElement>
);
const currentParams = ref<Nullable<EventParams>>(null); const currentParams = ref<Nullable<EventParams>>(null);
const showTrace = ref<boolean>(false); const showTrace = ref<boolean>(false);
const traceOptions = ref<{ type: string; filters?: unknown }>({ const traceOptions = ref<{ type: string; filters?: unknown }>({
@ -95,7 +81,7 @@ const available = computed(
(Array.isArray(props.option.series) && (Array.isArray(props.option.series) &&
props.option.series[0] && props.option.series[0] &&
props.option.series[0].data) || props.option.series[0].data) ||
(Array.isArray(props.option.series.data) && props.option.series.data[0]) (Array.isArray(props.option.series.data) && props.option.series.data[0]),
); );
onMounted(async () => { onMounted(async () => {
await setOptions(props.option); await setOptions(props.option);
@ -141,7 +127,7 @@ function instanceEvent() {
currTrigger: "leave", currTrigger: "leave",
}); });
}, },
true true,
); );
}, 1000); }, 1000);
} }
@ -207,13 +193,13 @@ watch(
options = eventAssociate(); options = eventAssociate();
} }
setOptions(options || props.option); setOptions(options || props.option);
} },
); );
watch( watch(
() => props.filters, () => props.filters,
() => { () => {
updateOptions(); updateOptions();
} },
); );
onBeforeUnmount(() => { onBeforeUnmount(() => {

View File

@ -19,9 +19,7 @@ limitations under the License. -->
{{ selected.label }} {{ selected.label }}
</span> </span>
<span class="no-data" v-else>Please select a option</span> <span class="no-data" v-else>Please select a option</span>
<span class="remove-icon" @click="removeSelected" v-if="clearable"> <span class="remove-icon" @click="removeSelected" v-if="clearable"> × </span>
×
</span>
</div> </div>
<div class="opt-wrapper" v-show="visible"> <div class="opt-wrapper" v-show="visible">
<div <div
@ -39,7 +37,7 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
/*global defineProps, defineEmits*/ /*global defineProps, defineEmits*/
const emit = defineEmits(["change"]); const emit = defineEmits(["change"]);
@ -71,7 +69,7 @@ watch(
(data) => { (data) => {
const opt = props.options.find((d: Option) => data === d.value); const opt = props.options.find((d: Option) => data === d.value);
selected.value = opt || { label: "", value: "" }; selected.value = opt || { label: "", value: "" };
} },
); );
document.body.addEventListener("click", handleClick, false); document.body.addEventListener("click", handleClick, false);

View File

@ -72,9 +72,7 @@ const props = defineProps({
const selected = ref<string[] | string>(props.value); const selected = ref<string[] | string>(props.value);
function changeSelected() { function changeSelected() {
const options = props.options.filter((d: any) => const options = props.options.filter((d: any) =>
props.multiple props.multiple ? selected.value.includes(d.value) : selected.value === d.value,
? selected.value.includes(d.value)
: selected.value === d.value
); );
emit("change", options); emit("change", options);
} }
@ -89,7 +87,7 @@ watch(
() => props.value, () => props.value,
(data) => { (data) => {
selected.value = data; selected.value = data;
} },
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -35,56 +35,28 @@ limitations under the License. -->
<transition name="datepicker-anim"> <transition name="datepicker-anim">
<div <div
class="datepicker-popup" class="datepicker-popup"
:class="[ :class="[popupClass, { 'datepicker-inline': type === 'inline' }, position]"
popupClass,
{ 'datepicker-inline': type === 'inline' },
position,
]"
tabindex="-1" tabindex="-1"
v-if="show || type === 'inline'" v-if="show || type === 'inline'"
> >
<template v-if="range"> <template v-if="range">
<div class="datepicker-popup__sidebar"> <div class="datepicker-popup__sidebar">
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('quarter')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('quarter')"
>
{{ local.quarterHourCutTip }} {{ local.quarterHourCutTip }}
</button> </button>
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('half')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('half')"
>
{{ local.halfHourCutTip }} {{ local.halfHourCutTip }}
</button> </button>
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('hour')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('hour')"
>
{{ local.hourCutTip }} {{ local.hourCutTip }}
</button> </button>
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('day')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('day')"
>
{{ local.dayCutTip }} {{ local.dayCutTip }}
</button> </button>
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('week')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('week')"
>
{{ local.weekCutTip }} {{ local.weekCutTip }}
</button> </button>
<button <button type="button" class="datepicker-popup__shortcut" @click="quickPick('month')">
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('month')"
>
{{ local.monthCutTip }} {{ local.monthCutTip }}
</button> </button>
</div> </div>
@ -123,16 +95,10 @@ limitations under the License. -->
/> />
</template> </template>
<div v-if="showButtons" class="datepicker__buttons"> <div v-if="showButtons" class="datepicker__buttons">
<button <button @click.prevent.stop="cancel" class="datepicker__button-cancel">
@click.prevent.stop="cancel"
class="datepicker__button-cancel"
>
{{ local.cancelTip }} {{ local.cancelTip }}
</button> </button>
<button <button @click.prevent.stop="submit" class="datepicker__button-select">
@click.prevent.stop="submit"
class="datepicker__button-select"
>
{{ local.submitTip }} {{ local.submitTip }}
</button> </button>
</div> </div>
@ -234,19 +200,14 @@ const tf = (time: Date, format?: any): string => {
s: seconds, s: seconds,
S: milliseconds, S: milliseconds,
}; };
return (format || props.format).replace( return (format || props.format).replace(/Y+|M+|D+|H+|h+|m+|s+|S+/g, (str: string) => map[str]);
/Y+|M+|D+|H+|h+|m+|s+|S+/g,
(str: string) => map[str]
);
}; };
const range = computed(() => { const range = computed(() => {
return dates.value.length === 2; return dates.value.length === 2;
}); });
const text = computed(() => { const text = computed(() => {
const val = props.value; const val = props.value;
const txt = dates.value const txt = dates.value.map((date: Date) => tf(date)).join(` ${props.rangeSeparator} `);
.map((date: Date) => tf(date))
.join(` ${props.rangeSeparator} `);
if (Array.isArray(val)) { if (Array.isArray(val)) {
return val.length > 1 ? txt : ""; return val.length > 1 ? txt : "";
} }
@ -261,9 +222,7 @@ const cls = () => {
}; };
const vi = (val: any) => { const vi = (val: any) => {
if (Array.isArray(val)) { if (Array.isArray(val)) {
return val.length > 1 return val.length > 1 ? val.map((item) => new Date(item)) : [new Date(), new Date()];
? val.map((item) => new Date(item))
: [new Date(), new Date()];
} }
return val ? [new Date(val)] : [new Date()]; return val ? [new Date(val)] : [new Date()];
}; };
@ -332,7 +291,7 @@ watch(
() => props.value, () => props.value,
(val: unknown) => { (val: unknown) => {
dates.value = vi(val); dates.value = vi(val);
} },
); );
</script> </script>

View File

@ -14,22 +14,18 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import axios, { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import axios from "axios";
import { cancelToken } from "@/utils/cancelToken"; import { cancelToken } from "@/utils/cancelToken";
async function query(param: { async function query(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
queryStr: string;
conditions: { [key: string]: unknown };
}) {
const res: AxiosResponse = await axios.post( const res: AxiosResponse = await axios.post(
"/graphql", "/graphql",
{ query: param.queryStr, variables: { ...param.conditions } }, { query: param.queryStr, variables: { ...param.conditions } },
{ cancelToken: cancelToken() } { cancelToken: cancelToken() },
); );
if (res.data.errors) { if (res.data.errors) {
res.data.errors = res.data.errors res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
.map((e: { message: string }) => e.message)
.join(" ");
} }
return res; return res;
} }

View File

@ -33,8 +33,7 @@ export const createEBPFTask = {
}`, }`,
}; };
export const queryEBPFTasks = { export const queryEBPFTasks = {
variable: variable: "$serviceId: ID, $serviceInstanceId: ID, $targets: [EBPFProfilingTargetType!]",
"$serviceId: ID, $serviceInstanceId: ID, $targets: [EBPFProfilingTargetType!]",
query: ` query: `
queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId, serviceInstanceId: $serviceInstanceId, targets: $targets) { queryEBPFTasks: queryEBPFProfilingTasks(serviceId: $serviceId, serviceInstanceId: $serviceInstanceId, targets: $targets) {
taskId taskId

View File

@ -53,8 +53,7 @@ export const EndpointTopology = {
}`, }`,
}; };
export const InstanceTopology = { export const InstanceTopology = {
variable: variable: "$clientServiceId: ID!, $serverServiceId: ID!, $duration: Duration!",
"$clientServiceId: ID!, $serverServiceId: ID!, $duration: Duration!",
query: ` query: `
topology: getServiceInstanceTopology(clientServiceId: $clientServiceId, topology: getServiceInstanceTopology(clientServiceId: $clientServiceId,
serverServiceId: $serverServiceId, duration: $duration) { serverServiceId: $serverServiceId, duration: $duration) {

View File

@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import axios, { AxiosPromise, AxiosResponse } from "axios"; import type { AxiosPromise, AxiosResponse } from "axios";
import axios from "axios";
import { cancelToken } from "@/utils/cancelToken"; import { cancelToken } from "@/utils/cancelToken";
import * as app from "./query/app"; import * as app from "./query/app";
import * as selector from "./query/selector"; import * as selector from "./query/selector";
@ -55,13 +56,11 @@ class Graphql {
query: query[this.queryData], query: query[this.queryData],
variables: variablesData, variables: variablesData,
}, },
{ cancelToken: cancelToken() } { cancelToken: cancelToken() },
) )
.then((res: AxiosResponse) => { .then((res: AxiosResponse) => {
if (res.data.errors) { if (res.data.errors) {
res.data.errors = res.data.errors res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
.map((e: { message: string }) => e.message)
.join(" ");
} }
return res; return res;
}) })

View File

@ -15,12 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { import { Traces, TraceSpans, TraceTagKeys, TraceTagValues } from "../fragments/trace";
Traces,
TraceSpans,
TraceTagKeys,
TraceTagValues,
} from "../fragments/trace";
export const queryTraces = `query queryTraces(${Traces.variable}) {${Traces.query}}`; export const queryTraces = `query queryTraces(${Traces.variable}) {${Traces.query}}`;

View File

@ -17,7 +17,7 @@
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import dateFormatStep from "@/utils/dateFormat"; import dateFormatStep from "@/utils/dateFormat";
import getLocalTime from "@/utils/localtime"; import getLocalTime from "@/utils/localtime";
import { EventParams } from "@/types/app"; import type { EventParams } from "@/types/app";
export default function associateProcessor(props: any) { export default function associateProcessor(props: any) {
function eventAssociate() { function eventAssociate() {
@ -30,9 +30,7 @@ export default function associateProcessor(props: any) {
if (!props.option.series[0]) { if (!props.option.series[0]) {
return; return;
} }
const list = props.option.series[0].data.map( const list = props.option.series[0].data.map((d: (number | string)[]) => d[0]);
(d: (number | string)[]) => d[0]
);
if (!list.includes(props.filters.duration.endTime)) { if (!list.includes(props.filters.duration.endTime)) {
return; return;
} }
@ -77,16 +75,8 @@ export default function associateProcessor(props: any) {
if (start) { if (start) {
const end = start; const end = start;
duration = { duration = {
start: dateFormatStep( start: dateFormatStep(getLocalTime(appStore.utc, new Date(start)), step, true),
getLocalTime(appStore.utc, new Date(start)), end: dateFormatStep(getLocalTime(appStore.utc, new Date(end)), step, true),
step,
true
),
end: dateFormatStep(
getLocalTime(appStore.utc, new Date(end)),
step,
true
),
step, step,
}; };
} }
@ -101,36 +91,27 @@ export default function associateProcessor(props: any) {
status, status,
}; };
if (latency) { if (latency) {
const latencyList = series.map( const latencyList = series.map((d: { name: string; data: number[][] }, index: number) => {
(d: { name: string; data: number[][] }, index: number) => {
const data = [ const data = [
d.data[currentParams.dataIndex][1], d.data[currentParams.dataIndex][1],
series[index + 1] series[index + 1] ? series[index + 1].data[currentParams.dataIndex][1] : Infinity,
? series[index + 1].data[currentParams.dataIndex][1]
: Infinity,
]; ];
return { return {
label: label: d.name + "--" + (series[index + 1] ? series[index + 1].name : "Infinity"),
d.name +
"--" +
(series[index + 1] ? series[index + 1].name : "Infinity"),
value: String(index), value: String(index),
data, data,
}; };
} });
);
item.latency = latencyList; item.latency = latencyList;
} }
const value = series.map( const value = series.map((d: { name: string; data: number[][] }, index: number) => {
(d: { name: string; data: number[][] }, index: number) => {
return { return {
label: d.name, label: d.name,
value: String(index), value: String(index),
data: d.data[currentParams.dataIndex][1], data: d.data[currentParams.dataIndex][1],
date: d.data[currentParams.dataIndex][0], date: d.data[currentParams.dataIndex][0],
}; };
} });
);
item.metricValue = value; item.metricValue = value;
return item; return item;
} }

View File

@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { ref, computed, ComputedRef, unref } from "vue"; import type { ComputedRef } from "vue";
import { ref, computed, unref } from "vue";
import { useEventListener } from "./useEventListener"; import { useEventListener } from "./useEventListener";
import { screenMap, sizeEnum, screenEnum } from "./data"; import { screenMap, sizeEnum, screenEnum } from "./data";
@ -40,9 +41,7 @@ export function useBreakpoint(): any {
}; };
} }
export function createBreakpointListen( export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void): any {
fn?: (opt: CreateCallbackParams) => void
): any {
const screenRef = ref<sizeEnum>(sizeEnum.XL || ""); const screenRef = ref<sizeEnum>(sizeEnum.XL || "");
const realWidthRef = ref(window.innerWidth); const realWidthRef = ref(window.innerWidth);

View File

@ -16,19 +16,15 @@
*/ */
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
export default function getDashboard(param?: { export default function getDashboard(param?: { name: string; layer: string; entity: string }) {
name: string;
layer: string;
entity: string;
}) {
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const opt = param || dashboardStore.currentDashboard; const opt = param || dashboardStore.currentDashboard;
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const dashboard = list.find( const dashboard = list.find(
(d: { name: string; layer: string; entity: string }) => (d: { name: string; layer: string; entity: string }) =>
d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer,
); );
const all = dashboardStore.layout; const all = dashboardStore.layout;
const widgets: LayoutConfig[] = []; const widgets: LayoutConfig[] = [];

View File

@ -14,13 +14,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { import type {
BarSeriesOption, BarSeriesOption,
LineSeriesOption, LineSeriesOption,
HeatmapSeriesOption, HeatmapSeriesOption,
SankeySeriesOption, SankeySeriesOption,
} from "echarts/charts"; } from "echarts/charts";
import { import type {
TitleComponentOption, TitleComponentOption,
TooltipComponentOption, TooltipComponentOption,
GridComponentOption, GridComponentOption,
@ -50,7 +50,7 @@ export type ECOption = echarts.ComposeOption<
export function useECharts( export function useECharts(
elRef: Ref<HTMLDivElement>, elRef: Ref<HTMLDivElement>,
theme: "light" | "dark" | "default" = "default" theme: "light" | "dark" | "default" = "default",
): any { ): any {
const getDarkMode = computed(() => { const getDarkMode = computed(() => {
return theme === "default" ? "light" : theme; return theme === "default" ? "light" : theme;
@ -131,7 +131,7 @@ export function useECharts(
initCharts(theme as "default"); initCharts(theme as "default");
setOptions(cacheOptions.value); setOptions(cacheOptions.value);
} }
} },
); );
tryOnUnmounted(() => { tryOnUnmounted(() => {

View File

@ -43,16 +43,13 @@ export function useEventListener({
if (el) { if (el) {
const element = ref(el as Element) as Ref<Element>; const element = ref(el as Element) as Ref<Element>;
const handler = isDebounce const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait);
? useDebounceFn(listener, wait)
: useThrottleFn(listener, wait);
const realHandler = wait ? handler : listener; const realHandler = wait ? handler : listener;
const removeEventListener = (e: Element) => { const removeEventListener = (e: Element) => {
isAddRef.value = true; isAddRef.value = true;
e.removeEventListener(name, realHandler, options); e.removeEventListener(name, realHandler, options);
}; };
const addEventListener = (e: Element) => const addEventListener = (e: Element) => e.addEventListener(name, realHandler, options);
e.addEventListener(name, realHandler, options);
const removeWatch = watch( const removeWatch = watch(
element, element,
@ -64,7 +61,7 @@ export function useEventListener({
}); });
} }
}, },
{ immediate: true } { immediate: true },
); );
remove = () => { remove = () => {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { LegendOptions } from "@/types/dashboard"; import type { LegendOptions } from "@/types/dashboard";
import { isDef } from "@/utils/is"; import { isDef } from "@/utils/is";
export default function useLegendProcess(legend?: LegendOptions) { export default function useLegendProcess(legend?: LegendOptions) {
@ -37,13 +37,10 @@ export default function useLegendProcess(legend?: LegendOptions) {
} }
return true; return true;
} }
function aggregations( function aggregations(data: { [key: string]: number[] }, intervalTime: string[]) {
data: { [key: string]: number[] },
intervalTime: string[]
) {
const source: { [key: string]: unknown }[] = []; const source: { [key: string]: unknown }[] = [];
const keys = Object.keys(data || {}).filter( const keys = Object.keys(data || {}).filter(
(i: any) => Array.isArray(data[i]) && data[i].length (i: any) => Array.isArray(data[i]) && data[i].length,
); );
const headers = []; const headers = [];
@ -59,10 +56,8 @@ export default function useLegendProcess(legend?: LegendOptions) {
}; };
}) })
.sort( .sort(
( (a: { key: string; value: number }, b: { key: string; value: number }) =>
a: { key: string; value: number }, b.value - a.value,
b: { key: string; value: number }
) => b.value - a.value
) )
.filter((_: unknown, index: number) => index < 10), .filter((_: unknown, index: number) => index < 10),
}; };

View File

@ -17,25 +17,17 @@
import { MetricQueryTypes, Calculations } from "./data"; import { MetricQueryTypes, Calculations } from "./data";
export function useListConfig(config: any, index: string) { export function useListConfig(config: any, index: string) {
const i = Number(index); const i = Number(index);
const types = [ const types = [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg];
Calculations.Average,
Calculations.ApdexAvg,
Calculations.PercentageAvg,
];
const calculation = const calculation =
config.metricConfig && config.metricConfig && config.metricConfig[i] && config.metricConfig[i].calculation;
config.metricConfig[i] &&
config.metricConfig[i].calculation;
const isLinear = const isLinear =
[ [MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(
MetricQueryTypes.ReadMetricsValues, config.metricTypes[i],
MetricQueryTypes.ReadLabeledMetricsValues, ) && !types.includes(calculation);
].includes(config.metricTypes[i]) && !types.includes(calculation);
const isAvg = const isAvg =
[ [MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(
MetricQueryTypes.ReadMetricsValues, config.metricTypes[i],
MetricQueryTypes.ReadLabeledMetricsValues, ) && types.includes(calculation);
].includes(config.metricTypes[i]) && types.includes(calculation);
return { return {
isLinear, isLinear,
isAvg, isAvg,

View File

@ -20,8 +20,8 @@ import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { Instance, Endpoint, Service } from "@/types/selector"; import type { Instance, Endpoint, Service } from "@/types/selector";
import { MetricConfigOpt } from "@/types/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard";
import { MetricCatalog } from "@/views/dashboard/data"; import { MetricCatalog } from "@/views/dashboard/data";
export function useQueryProcessor(config: any) { export function useQueryProcessor(config: any) {
@ -54,21 +54,14 @@ export function useQueryProcessor(config: any) {
const fragment = config.metrics.map((name: string, index: number) => { const fragment = config.metrics.map((name: string, index: number) => {
const metricType = config.metricTypes[index] || ""; const metricType = config.metricTypes[index] || "";
const c = (config.metricConfig && config.metricConfig[index]) || {}; const c = (config.metricConfig && config.metricConfig[index]) || {};
if ( if ([MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics].includes(metricType)) {
[
MetricQueryTypes.ReadSampledRecords,
MetricQueryTypes.SortMetrics,
].includes(metricType)
) {
variables.push(`$condition${index}: TopNCondition!`); variables.push(`$condition${index}: TopNCondition!`);
conditions[`condition${index}`] = { conditions[`condition${index}`] = {
name, name,
parentService: ["All"].includes(dashboardStore.entity) parentService: ["All"].includes(dashboardStore.entity)
? null ? null
: selectorStore.currentService.value, : selectorStore.currentService.value,
normal: selectorStore.currentService normal: selectorStore.currentService ? selectorStore.currentService.normal : true,
? selectorStore.currentService.normal
: true,
scope: config.catalog, scope: config.catalog,
topN: c.topN || 10, topN: c.topN || 10,
order: c.sortOrder || "DES", order: c.sortOrder || "DES",
@ -77,13 +70,8 @@ export function useQueryProcessor(config: any) {
const entity = { const entity = {
scope: config.catalog, scope: config.catalog,
serviceName: serviceName:
dashboardStore.entity === "All" dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value,
? undefined normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal,
: selectorStore.currentService.value,
normal:
dashboardStore.entity === "All"
? undefined
: selectorStore.currentService.normal,
serviceInstanceName: [ serviceInstanceName: [
"ServiceInstance", "ServiceInstance",
"ServiceInstanceRelation", "ServiceInstanceRelation",
@ -97,16 +85,11 @@ export function useQueryProcessor(config: any) {
processName: dashboardStore.entity.includes("Process") processName: dashboardStore.entity.includes("Process")
? selectorStore.currentProcess && selectorStore.currentProcess.value ? selectorStore.currentProcess && selectorStore.currentProcess.value
: undefined, : undefined,
destNormal: isRelation destNormal: isRelation ? selectorStore.currentDestService.normal : undefined,
? selectorStore.currentDestService.normal destServiceName: isRelation ? selectorStore.currentDestService.value : undefined,
: undefined, destServiceInstanceName: ["ServiceInstanceRelation", "ProcessRelation"].includes(
destServiceName: isRelation dashboardStore.entity,
? selectorStore.currentDestService.value )
: undefined,
destServiceInstanceName: [
"ServiceInstanceRelation",
"ProcessRelation",
].includes(dashboardStore.entity)
? selectorStore.currentDestPod && selectorStore.currentDestPod.value ? selectorStore.currentDestPod && selectorStore.currentDestPod.value
: undefined, : undefined,
destEndpointName: destEndpointName:
@ -114,8 +97,7 @@ export function useQueryProcessor(config: any) {
? selectorStore.currentDestPod && selectorStore.currentDestPod.value ? selectorStore.currentDestPod && selectorStore.currentDestPod.value
: undefined, : undefined,
destProcessName: dashboardStore.entity.includes("ProcessRelation") destProcessName: dashboardStore.entity.includes("ProcessRelation")
? selectorStore.currentDestProcess && ? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value
selectorStore.currentDestProcess.value
: undefined, : undefined,
}; };
if ([MetricQueryTypes.ReadRecords].includes(metricType)) { if ([MetricQueryTypes.ReadRecords].includes(metricType)) {
@ -161,7 +143,7 @@ export function useSourceProcessor(
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
metricConfig: MetricConfigOpt[]; metricConfig: MetricConfigOpt[];
} },
) { ) {
if (resp.errors) { if (resp.errors) {
ElMessage.error(resp.errors); ElMessage.error(resp.errors);
@ -180,9 +162,7 @@ export function useSourceProcessor(
if (type === MetricQueryTypes.ReadMetricsValues) { if (type === MetricQueryTypes.ReadMetricsValues) {
source[c.label || m] = source[c.label || m] =
(resp.data[keys[index]] && (resp.data[keys[index]] && calculateExp(resp.data[keys[index]].values.values, c)) || [];
calculateExp(resp.data[keys[index]].values.values, c)) ||
[];
} }
if (type === MetricQueryTypes.ReadLabeledMetricsValues) { if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
const resVal = Object.values(resp.data)[0] || []; const resVal = Object.values(resp.data)[0] || [];
@ -194,7 +174,7 @@ export function useSourceProcessor(
.map((item: string) => item.replace(/^\s*|\s*$/g, "")); .map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (const item of resVal) { for (const item of resVal) {
const values = item.values.values.map((d: { value: number }) => const values = item.values.values.map((d: { value: number }) =>
aggregation(Number(d.value), c) aggregation(Number(d.value), c),
); );
const indexNum = labelsIdx.findIndex((d: string) => d === item.label); const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
if (labels[indexNum] && indexNum > -1) { if (labels[indexNum] && indexNum > -1) {
@ -216,13 +196,11 @@ export function useSourceProcessor(
] as string[] ] as string[]
).includes(type) ).includes(type)
) { ) {
source[m] = (Object.values(resp.data)[0] || []).map( source[m] = (Object.values(resp.data)[0] || []).map((d: { value: unknown; name: string }) => {
(d: { value: unknown; name: string }) => {
d.value = aggregation(Number(d.value), c); d.value = aggregation(Number(d.value), c);
return d; return d;
} });
);
} }
if (type === MetricQueryTypes.READHEATMAP) { if (type === MetricQueryTypes.READHEATMAP) {
const resVal = Object.values(resp.data)[0] || {}; const resVal = Object.values(resp.data)[0] || {};
@ -240,9 +218,7 @@ export function useSourceProcessor(
if (resVal.buckets.length) { if (resVal.buckets.length) {
buckets = [ buckets = [
resVal.buckets[0].min, resVal.buckets[0].min,
...resVal.buckets.map( ...resVal.buckets.map((item: { min: string; max: string }) => item.max),
(item: { min: string; max: string }) => item.max
),
]; ];
} }
@ -260,7 +236,7 @@ export function useQueryPodsMetrics(
metricTypes: string[]; metricTypes: string[];
metricConfig: MetricConfigOpt[]; metricConfig: MetricConfigOpt[];
}, },
scope: string scope: string,
) { ) {
const metricTypes = (config.metricTypes || []).filter((m: string) => m); const metricTypes = (config.metricTypes || []).filter((m: string) => m);
if (!metricTypes.length) { if (!metricTypes.length) {
@ -278,10 +254,7 @@ export function useQueryPodsMetrics(
const variables: string[] = [`$duration: Duration!`]; const variables: string[] = [`$duration: Duration!`];
const currentService = selectorStore.currentService || {}; const currentService = selectorStore.currentService || {};
const fragmentList = pods.map( const fragmentList = pods.map(
( (d: (Instance | Endpoint | Service) & { normal: boolean }, index: number) => {
d: (Instance | Endpoint | Service) & { normal: boolean },
index: number
) => {
const param = { const param = {
scope, scope,
serviceName: scope === "Service" ? d.label : currentService.label, serviceName: scope === "Service" ? d.label : currentService.label,
@ -309,7 +282,7 @@ export function useQueryPodsMetrics(
return `${name}${index}${idx}: ${metricType}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[metricType]}`; return `${name}${index}${idx}: ${metricType}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[metricType]}`;
}); });
return f; return f;
} },
); );
const fragment = fragmentList.flat(1).join(" "); const fragment = fragmentList.flat(1).join(" ");
const queryStr = `query queryData(${variables}) {${fragment}}`; const queryStr = `query queryData(${variables}) {${fragment}}`;
@ -324,7 +297,7 @@ export function usePodsSource(
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
metricConfig: MetricConfigOpt[]; metricConfig: MetricConfigOpt[];
} },
): any { ): any {
if (resp.errors) { if (resp.errors) {
ElMessage.error(resp.errors); ElMessage.error(resp.errors);
@ -348,16 +321,14 @@ export function usePodsSource(
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) { if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) {
d[name] = {}; d[name] = {};
if ( if (
[ [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(
Calculations.Average, c.calculation,
Calculations.ApdexAvg, )
Calculations.PercentageAvg,
].includes(c.calculation)
) { ) {
d[name]["avg"] = calculateExp(resp.data[key].values.values, c); d[name]["avg"] = calculateExp(resp.data[key].values.values, c);
} }
d[name]["values"] = resp.data[key].values.values.map( d[name]["values"] = resp.data[key].values.values.map((val: { value: number }) =>
(val: { value: number }) => aggregation(val.value, c) aggregation(val.value, c),
); );
if (idx === 0) { if (idx === 0) {
names.push(name); names.push(name);
@ -365,9 +336,7 @@ export function usePodsSource(
metricTypesArr.push(config.metricTypes[index]); metricTypesArr.push(config.metricTypes[index]);
} }
} }
if ( if (config.metricTypes[index] === MetricQueryTypes.ReadLabeledMetricsValues) {
config.metricTypes[index] === MetricQueryTypes.ReadLabeledMetricsValues
) {
const resVal = resp.data[key] || []; const resVal = resp.data[key] || [];
const labels = (c.label || "") const labels = (c.label || "")
.split(",") .split(",")
@ -378,7 +347,7 @@ export function usePodsSource(
for (let i = 0; i < resVal.length; i++) { for (let i = 0; i < resVal.length; i++) {
const item = resVal[i]; const item = resVal[i];
const values = item.values.values.map((d: { value: number }) => const values = item.values.values.map((d: { value: number }) =>
aggregation(Number(d.value), c) aggregation(Number(d.value), c),
); );
const indexNum = labelsIdx.findIndex((d: string) => d === item.label); const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
let key = item.label; let key = item.label;
@ -389,11 +358,9 @@ export function usePodsSource(
d[key] = {}; d[key] = {};
} }
if ( if (
[ [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(
Calculations.Average, c.calculation,
Calculations.ApdexAvg, )
Calculations.PercentageAvg,
].includes(c.calculation)
) { ) {
d[key]["avg"] = calculateExp(item.values.values, c); d[key]["avg"] = calculateExp(item.values.values, c);
} }
@ -437,11 +404,9 @@ export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
} }
function calculateExp( function calculateExp(
arr: { value: number }[], arr: { value: number }[],
config: { calculation?: string } config: { calculation?: string },
): (number | string)[] { ): (number | string)[] {
const sum = arr const sum = arr.map((d: { value: number }) => d.value).reduce((a, b) => a + b);
.map((d: { value: number }) => d.value)
.reduce((a, b) => a + b);
let data: (number | string)[] = []; let data: (number | string)[] = [];
switch (config.calculation) { switch (config.calculation) {
case Calculations.Average: case Calculations.Average:
@ -460,10 +425,7 @@ function calculateExp(
return data; return data;
} }
export function aggregation( export function aggregation(val: number, config: { calculation?: string }): number | string {
val: number,
config: { calculation?: string }
): number | string {
let data: number | string = Number(val); let data: number | string = Number(val);
switch (config.calculation) { switch (config.calculation) {

View File

@ -18,11 +18,7 @@ import { ref, watch } from "vue";
import { tryOnUnmounted } from "@vueuse/core"; import { tryOnUnmounted } from "@vueuse/core";
import { isFunction } from "@/utils/is"; import { isFunction } from "@/utils/is";
export function useTimeoutFn( export function useTimeoutFn(handle: Fn<any>, wait: number, native = false): any {
handle: Fn<any>,
wait: number,
native = false
): any {
if (!isFunction(handle)) { if (!isFunction(handle)) {
throw new Error("handle is not Function!"); throw new Error("handle is not Function!");
} }
@ -36,7 +32,7 @@ export function useTimeoutFn(
(maturity) => { (maturity) => {
maturity && handle(); maturity && handle();
}, },
{ immediate: false } { immediate: false },
); );
} }
return { readyRef, stop, start }; return { readyRef, stop, start };

View File

@ -24,8 +24,7 @@ limitations under the License. -->
@input="changeTimeRange" @input="changeTimeRange"
/> />
<span> <span>
UTC{{ appStore.utcHour >= 0 ? "+" : "" UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }}
}}{{ `${appStore.utcHour}:${appStore.utcMin}` }}
</span> </span>
<span title="refresh" class="ghost ml-5 cp" @click="handleReload"> <span title="refresh" class="ghost ml-5 cp" @click="handleReload">
<Icon iconName="retry" :loading="appStore.autoRefresh" class="middle" /> <Icon iconName="retry" :loading="appStore.autoRefresh" class="middle" />
@ -69,15 +68,13 @@ const setConfig = (value: string) => {
}; };
function handleReload() { function handleReload() {
const gap = const gap = appStore.duration.end.getTime() - appStore.duration.start.getTime();
appStore.duration.end.getTime() - appStore.duration.start.getTime();
const dates: Date[] = [new Date(new Date().getTime() - gap), new Date()]; const dates: Date[] = [new Date(new Date().getTime() - gap), new Date()];
appStore.setDuration(timeFormat(dates)); appStore.setDuration(timeFormat(dates));
} }
function changeTimeRange(val: Date[] | any) { function changeTimeRange(val: Date[] | any) {
timeRange.value = timeRange.value = val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000 ? 1 : 0;
val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000 ? 1 : 0;
if (timeRange.value) { if (timeRange.value) {
return; return;
} }
@ -88,7 +85,7 @@ watch(
() => route.meta.title, () => route.meta.title,
(title: unknown) => { (title: unknown) => {
setConfig(String(title)); setConfig(String(title));
} },
); );
async function getVersion() { async function getVersion() {
const res = await appStore.fetchVersion(); const res = await appStore.fetchVersion();

View File

@ -15,10 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="side-bar"> <div class="side-bar">
<div :class="isCollapse ? 'logo-icon-collapse' : 'logo-icon'"> <div :class="isCollapse ? 'logo-icon-collapse' : 'logo-icon'">
<Icon <Icon :size="isCollapse ? 'xl' : 'logo'" :iconName="isCollapse ? 'logo' : 'logo-sw'" />
:size="isCollapse ? 'xl' : 'logo'"
:iconName="isCollapse ? 'logo' : 'logo-sw'"
/>
</div> </div>
<el-menu <el-menu
active-text-color="#448dfe" active-text-color="#448dfe"
@ -43,22 +40,14 @@ limitations under the License. -->
</router-link> </router-link>
</template> </template>
<el-menu-item-group> <el-menu-item-group>
<el-menu-item <el-menu-item v-for="(m, idx) in filterMenus(menu.children)" :index="m.name" :key="idx">
v-for="(m, idx) in filterMenus(menu.children)"
:index="m.name"
:key="idx"
>
<router-link class="items" :to="m.path"> <router-link class="items" :to="m.path">
<span class="title">{{ m.meta && t(m.meta.title) }}</span> <span class="title">{{ m.meta && t(m.meta.title) }}</span>
</router-link> </router-link>
</el-menu-item> </el-menu-item>
</el-menu-item-group> </el-menu-item-group>
</el-sub-menu> </el-sub-menu>
<el-menu-item <el-menu-item :index="String(menu.name)" @click="changePage(menu)" v-else>
:index="String(menu.name)"
@click="changePage(menu)"
v-else
>
<el-icon class="menu-icons" :style="{ marginRight: '12px' }"> <el-icon class="menu-icons" :style="{ marginRight: '12px' }">
<router-link class="items" :to="menu.children[0].path"> <router-link class="items" :to="menu.children[0].path">
<Icon size="lg" :iconName="menu.meta.icon" /> <Icon size="lg" :iconName="menu.meta.icon" />
@ -79,18 +68,15 @@ limitations under the License. -->
color: theme === 'light' ? '#eee' : '#252a2f', color: theme === 'light' ? '#eee' : '#252a2f',
}" }"
> >
<Icon <Icon size="middle" iconName="format_indent_decrease" @click="controlMenu" />
size="middle"
iconName="format_indent_decrease"
@click="controlMenu"
/>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue"; import { ref } from "vue";
import { useRouter, RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import Icon from "@/components/Icon.vue"; import Icon from "@/components/Icon.vue";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
@ -112,9 +98,7 @@ const controlMenu = () => {
isCollapse.value = !isCollapse.value; isCollapse.value = !isCollapse.value;
}; };
const changePage = (menu: RouteRecordRaw) => { const changePage = (menu: RouteRecordRaw) => {
theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name)) theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name)) ? "light" : "black";
? "light"
: "black";
}; };
const filterMenus = (menus: any[]) => { const filterMenus = (menus: any[]) => {
return menus.filter((d) => d.meta && !d.meta.notShow); return menus.filter((d) => d.meta && !d.meta.notShow);

View File

@ -176,10 +176,8 @@ const msg = {
toTheRight: "To The Right", toTheRight: "To The Right",
legendValues: "Legend Values", legendValues: "Legend Values",
minDuration: "Minimal Request Duration", minDuration: "Minimal Request Duration",
when4xx: when4xx: "Sample HTTP requests and responses with tracing when response code between 400 and 499",
"Sample HTTP requests and responses with tracing when response code between 400 and 499", when5xx: "Sample HTTP requests and responses with tracing when response code between 500 and 599",
when5xx:
"Sample HTTP requests and responses with tracing when response code between 500 and 599",
taskTitle: "HTTP request and response collecting rules", taskTitle: "HTTP request and response collecting rules",
seconds: "Seconds", seconds: "Seconds",
hourTip: "Select Hour", hourTip: "Select Hour",
@ -315,8 +313,7 @@ const msg = {
viewLogs: "View Logs", viewLogs: "View Logs",
logsTagsTip: `Only tags defined in the core/default/searchableLogsTags are searchable. logsTagsTip: `Only tags defined in the core/default/searchableLogsTags are searchable.
Check more details on the Configuration Vocabulary page`, Check more details on the Configuration Vocabulary page`,
keywordsOfContentLogTips: keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this.",
"Current storage of SkyWalking OAP server does not support this.",
setEvent: "Set Event", setEvent: "Set Event",
viewAttributes: "View", viewAttributes: "View",
serviceEvents: "Service Events", serviceEvents: "Service Events",

View File

@ -77,10 +77,8 @@ const msg = {
editGraph: "Editar Opciones", editGraph: "Editar Opciones",
dashboardName: "Selecciona Nombre del Panel", dashboardName: "Selecciona Nombre del Panel",
linkDashboard: "Nombre del panel relacionado con llamadas de la topología", linkDashboard: "Nombre del panel relacionado con llamadas de la topología",
linkServerMetrics: linkServerMetrics: "Métricas de servidor relacionadas con llamadas de la topología",
"Métricas de servidor relacionadas con llamadas de la topología", linkClientMetrics: "Métricas de cliente relacionadas con llamadas de la topología",
linkClientMetrics:
"Métricas de cliente relacionadas con llamadas de la topología",
nodeDashboard: "Nombre del panel relacionado con nodos de la topología", nodeDashboard: "Nombre del panel relacionado con nodos de la topología",
nodeMetrics: "Mêtricas relacionas con nodos de la topología", nodeMetrics: "Mêtricas relacionas con nodos de la topología",
instanceDashboard: "Nombre del panel relacionado con instancias de servicio", instanceDashboard: "Nombre del panel relacionado con instancias de servicio",
@ -315,8 +313,7 @@ const msg = {
viewLogs: "Ver Registro de Datos", viewLogs: "Ver Registro de Datos",
logsTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas. logsTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`, Más información en la página de Vocabulario de Configuración`,
keywordsOfContentLogTips: keywordsOfContentLogTips: "El almacenamiento actual del servidor SkyWalking OAP no lo soporta.",
"El almacenamiento actual del servidor SkyWalking OAP no lo soporta.",
setEvent: "Establecer Evento", setEvent: "Establecer Evento",
viewAttributes: "Ver", viewAttributes: "Ver",
serviceEvents: "Eventos Servico", serviceEvents: "Eventos Servico",
@ -347,8 +344,7 @@ const msg = {
destEndpoint: "Endpoint Destinación", destEndpoint: "Endpoint Destinación",
eventSource: "Fuente Envento", eventSource: "Fuente Envento",
modalTitle: "Inspección", modalTitle: "Inspección",
selectRedirectPage: selectRedirectPage: "Quiere inspeccionar las Trazas or Registros de datos del servicio %s?",
"Quiere inspeccionar las Trazas or Registros de datos del servicio %s?",
logAnalysis: "Lenguaje de Análisis de Registro de Datos", logAnalysis: "Lenguaje de Análisis de Registro de Datos",
logDataBody: "Contenido del Registro de Datos", logDataBody: "Contenido del Registro de Datos",
addType: "Por favor introduzca un tipo", addType: "Por favor introduzca un tipo",
@ -369,10 +365,8 @@ const msg = {
addTraceID: "Por favor introduzca el ID de la traza", addTraceID: "Por favor introduzca el ID de la traza",
addTags: "Por favor introduzaca una etiqueta", addTags: "Por favor introduzaca una etiqueta",
addKeywordsOfContent: "Por favor introduzca una clave de contenido", addKeywordsOfContent: "Por favor introduzca una clave de contenido",
addExcludingKeywordsOfContent: addExcludingKeywordsOfContent: "Por favor introduzca una clave excluyente de contenido",
"Por favor introduzca una clave excluyente de contenido", noticeTag: "Por favor presione Intro después de introducir una etiqueta(clave=valor).",
noticeTag:
"Por favor presione Intro después de introducir una etiqueta(clave=valor).",
conditionNotice: conditionNotice:
"Aviso: Por favor presione Intro después de introducir una clave de contenido, excluir clave de contenido(clave=valor).", "Aviso: Por favor presione Intro después de introducir una clave de contenido, excluir clave de contenido(clave=valor).",
language: "Lenguaje", language: "Lenguaje",

View File

@ -368,8 +368,7 @@ const msg = {
addKeywordsOfContent: "请输入一个内容关键词", addKeywordsOfContent: "请输入一个内容关键词",
addExcludingKeywordsOfContent: "请输入一个内容不包含的关键词", addExcludingKeywordsOfContent: "请输入一个内容不包含的关键词",
noticeTag: "请输入一个标签(key=value)之后回车", noticeTag: "请输入一个标签(key=value)之后回车",
conditionNotice: conditionNotice: "请输入一个内容关键词或者内容不包含的关键词(key=value)之后回车",
"请输入一个内容关键词或者内容不包含的关键词(key=value)之后回车",
language: "语言", language: "语言",
gateway: "网关", gateway: "网关",
virtualMQ: "虚拟消息队列", virtualMQ: "虚拟消息队列",

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
export const routesAlarm: Array<RouteRecordRaw> = [ export const routesAlarm: Array<RouteRecordRaw> = [

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
export const routesDashboard: Array<RouteRecordRaw> = [ export const routesDashboard: Array<RouteRecordRaw> = [
@ -88,8 +88,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
}, },
{ {
path: "", path: "",
redirect: redirect: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
"/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: () => import("@/views/dashboard/Edit.vue"),
name: "ViewServiceRelation", name: "ViewServiceRelation",
meta: { meta: {
@ -131,8 +130,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
}, },
{ {
path: "", path: "",
redirect: redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
"/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: () => import("@/views/dashboard/Edit.vue"),
name: "PodRelation", name: "PodRelation",
meta: { meta: {

View File

@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import { createRouter, createWebHistory } from "vue-router";
import { routesDashboard } from "./dashboard"; import { routesDashboard } from "./dashboard";
import { routesSetting } from "./setting"; import { routesSetting } from "./setting";
import { routesAlarm } from "./alarm"; import { routesAlarm } from "./alarm";

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
export const routesSetting: Array<RouteRecordRaw> = [ export const routesSetting: Array<RouteRecordRaw> = [

View File

@ -17,8 +17,8 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { Alarm } from "@/types/alarm"; import type { Alarm } from "@/types/alarm";
interface AlarmState { interface AlarmState {
loading: boolean; loading: boolean;
@ -35,9 +35,7 @@ export const alarmStore = defineStore({
}), }),
actions: { actions: {
async getAlarms(params: any) { async getAlarms(params: any) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryAlarms").params(params);
.query("queryAlarms")
.params(params);
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }

View File

@ -17,9 +17,9 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { Duration, DurationTime } from "@/types/app"; import type { Duration, DurationTime } from "@/types/app";
import getLocalTime from "@/utils/localtime"; import getLocalTime from "@/utils/localtime";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat"; import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
import { TimeType } from "@/constants/data"; import { TimeType } from "@/constants/data";
/*global Nullable*/ /*global Nullable*/
@ -93,8 +93,7 @@ export const appStore = defineStore({
break; break;
} }
const utcSpace = const utcSpace =
(this.utcHour + new Date().getTimezoneOffset() / 60) * 3600000 + (this.utcHour + new Date().getTimezoneOffset() / 60) * 3600000 + this.utcMin * 60000;
this.utcMin * 60000;
const startUnix: number = this.duration.start.getTime(); const startUnix: number = this.duration.start.getTime();
const endUnix: number = this.duration.end.getTime(); const endUnix: number = this.duration.end.getTime();
const timeIntervals: number[] = []; const timeIntervals: number[] = [];
@ -157,13 +156,11 @@ export const appStore = defineStore({
this.eventStack.forEach((event: any) => { this.eventStack.forEach((event: any) => {
setTimeout(event(), 0); setTimeout(event(), 0);
}), }),
500 500,
); );
}, },
async queryOAPTimeInfo() { async queryOAPTimeInfo() {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryOAPTimeInfo").params({});
.query("queryOAPTimeInfo")
.params({});
if (res.data.errors) { if (res.data.errors) {
this.utc = -(new Date().getTimezoneOffset() / 60) + ":0"; this.utc = -(new Date().getTimezoneOffset() / 60) + ":0";
} else { } else {
@ -176,9 +173,7 @@ export const appStore = defineStore({
return res.data; return res.data;
}, },
async fetchVersion(): Promise<void> { async fetchVersion(): Promise<void> {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryOAPVersion").params({});
.query("queryOAPVersion")
.params({});
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }

View File

@ -16,13 +16,13 @@
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { store } from "@/store"; import { store } from "@/store";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
import graphql from "@/graphql"; import graphql from "@/graphql";
import query from "@/graphql/fetch"; import query from "@/graphql/fetch";
import { DashboardItem } from "@/types/dashboard"; import type { DashboardItem } from "@/types/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { NewControl, TextConfig, TimeRangeConfig } from "../data"; import { NewControl, TextConfig, TimeRangeConfig } from "../data";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { EntityType } from "@/views/dashboard/data"; import { EntityType } from "@/views/dashboard/data";
@ -106,23 +106,10 @@ export const dashboardStore = defineStore({
newItem.graph = { newItem.graph = {
showDepth: true, showDepth: true,
depth: depth:
this.entity === EntityType[1].value this.entity === EntityType[1].value ? 1 : this.entity === EntityType[0].value ? 2 : 3,
? 1
: this.entity === EntityType[0].value
? 2
: 3,
}; };
} }
if ( if (["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling"].includes(type)) {
[
"Trace",
"Profile",
"Log",
"DemandLog",
"Ebpf",
"NetworkProfiling",
].includes(type)
) {
newItem.h = 36; newItem.h = 36;
} }
if (type === "Text") { if (type === "Text") {
@ -156,9 +143,7 @@ export const dashboardStore = defineStore({
}, },
addTabControls(type: string) { addTabControls(type: string) {
const activedGridItem = this.activedGridItem.split("-")[0]; const activedGridItem = this.activedGridItem.split("-")[0];
const idx = this.layout.findIndex( const idx = this.layout.findIndex((d: LayoutConfig) => d.i === activedGridItem);
(d: LayoutConfig) => d.i === activedGridItem
);
if (idx < 0) { if (idx < 0) {
return; return;
} }
@ -184,16 +169,7 @@ export const dashboardStore = defineStore({
showDepth: true, showDepth: true,
}; };
} }
if ( if (["Trace", "Profile", "Log", "DemandLog", "Ebpf", "NetworkProfiling"].includes(type)) {
[
"Trace",
"Profile",
"Log",
"DemandLog",
"Ebpf",
"NetworkProfiling",
].includes(type)
) {
newItem.h = 32; newItem.h = 32;
} }
if (type === "Text") { if (type === "Text") {
@ -238,18 +214,14 @@ export const dashboardStore = defineStore({
}, },
removeControls(item: LayoutConfig) { removeControls(item: LayoutConfig) {
const actived = this.activedGridItem.split("-"); const actived = this.activedGridItem.split("-");
const index = this.layout.findIndex( const index = this.layout.findIndex((d: LayoutConfig) => actived[0] === d.i);
(d: LayoutConfig) => actived[0] === d.i
);
if (this.selectedGrid && this.selectedGrid.i === item.i) { if (this.selectedGrid && this.selectedGrid.i === item.i) {
this.selectedGrid = null; this.selectedGrid = null;
} }
if (actived.length === 3) { if (actived.length === 3) {
const tabIndex = Number(actived[1]); const tabIndex = Number(actived[1]);
this.currentTabItems = this.currentTabItems.filter( this.currentTabItems = this.currentTabItems.filter((d: LayoutConfig) => actived[2] !== d.i);
(d: LayoutConfig) => actived[2] !== d.i
);
this.layout[index].children[tabIndex].children = this.currentTabItems; this.layout[index].children[tabIndex].children = this.currentTabItems;
return; return;
} }
@ -285,21 +257,18 @@ export const dashboardStore = defineStore({
}, },
setConfigs(param: { [key: string]: unknown }) { setConfigs(param: { [key: string]: unknown }) {
const actived = this.activedGridItem.split("-"); const actived = this.activedGridItem.split("-");
const index = this.layout.findIndex( const index = this.layout.findIndex((d: LayoutConfig) => actived[0] === d.i);
(d: LayoutConfig) => actived[0] === d.i
);
if (actived.length === 3) { if (actived.length === 3) {
const tabIndex = Number(actived[1]); const tabIndex = Number(actived[1]);
const itemIndex = this.layout[index].children[ const itemIndex = this.layout[index].children[tabIndex].children.findIndex(
tabIndex (d: LayoutConfig) => actived[2] === d.i,
].children.findIndex((d: LayoutConfig) => actived[2] === d.i); );
this.layout[index].children[tabIndex].children[itemIndex] = { this.layout[index].children[tabIndex].children[itemIndex] = {
...this.layout[index].children[tabIndex].children[itemIndex], ...this.layout[index].children[tabIndex].children[itemIndex],
...param, ...param,
}; };
this.selectedGrid = this.selectedGrid = this.layout[index].children[tabIndex].children[itemIndex];
this.layout[index].children[tabIndex].children[itemIndex];
this.setCurrentTabItems(this.layout[index].children[tabIndex].children); this.setCurrentTabItems(this.layout[index].children[tabIndex].children);
return; return;
} }
@ -332,23 +301,16 @@ export const dashboardStore = defineStore({
} }
}, },
async fetchMetricType(item: string) { async fetchMetricType(item: string) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryTypeOfMetrics").params({ name: item });
.query("queryTypeOfMetrics")
.params({ name: item });
return res.data; return res.data;
}, },
async fetchMetricList(regex: string) { async fetchMetricList(regex: string) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryMetrics").params({ regex });
.query("queryMetrics")
.params({ regex });
return res.data; return res.data;
}, },
async fetchMetricValue(param: { async fetchMetricValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
queryStr: string;
conditions: { [key: string]: unknown };
}) {
const res: AxiosResponse = await query(param); const res: AxiosResponse = await query(param);
return res.data; return res.data;
}, },
@ -371,10 +333,7 @@ export const dashboardStore = defineStore({
name: c.name, name: c.name,
isRoot: c.isRoot, isRoot: c.isRoot,
}); });
sessionStorage.setItem( sessionStorage.setItem(key, JSON.stringify({ id: t.id, configuration: c }));
key,
JSON.stringify({ id: t.id, configuration: c })
);
} }
list = list.sort((a, b) => { list = list.sort((a, b) => {
const nameA = a.name.toUpperCase(); const nameA = a.name.toUpperCase();
@ -399,9 +358,7 @@ export const dashboardStore = defineStore({
return; return;
} }
} }
this.dashboards = JSON.parse( this.dashboards = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
sessionStorage.getItem("dashboards") || "[]"
);
}, },
async resetTemplates() { async resetTemplates() {
const res = await this.fetchTemplates(); const res = await this.fetchTemplates();
@ -410,9 +367,7 @@ export const dashboardStore = defineStore({
ElMessage.error(res.errors); ElMessage.error(res.errors);
return; return;
} }
this.dashboards = JSON.parse( this.dashboards = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
sessionStorage.getItem("dashboards") || "[]"
);
}, },
async updateDashboard(setting: { id: string; configuration: string }) { async updateDashboard(setting: { id: string; configuration: string }) {
const res: AxiosResponse = await graphql.query("updateTemplate").params({ const res: AxiosResponse = await graphql.query("updateTemplate").params({
@ -454,7 +409,7 @@ export const dashboardStore = defineStore({
(d: DashboardItem) => (d: DashboardItem) =>
d.name === this.currentDashboard.name && d.name === this.currentDashboard.name &&
d.entity === this.currentDashboard.entity && d.entity === this.currentDashboard.entity &&
d.layer === this.currentDashboard.layerId d.layer === this.currentDashboard.layerId,
); );
if (index > -1) { if (index > -1) {
const { t } = useI18n(); const { t } = useI18n();
@ -487,7 +442,7 @@ export const dashboardStore = defineStore({
if (this.currentDashboard.id) { if (this.currentDashboard.id) {
sessionStorage.removeItem(key); sessionStorage.removeItem(key);
this.dashboards = this.dashboards.filter( this.dashboards = this.dashboards.filter(
(d: DashboardItem) => d.id !== this.currentDashboard.id (d: DashboardItem) => d.id !== this.currentDashboard.id,
); );
} }
this.dashboards.push(this.currentDashboard); this.dashboards.push(this.currentDashboard);
@ -511,9 +466,7 @@ export const dashboardStore = defineStore({
ElMessage.error(json.message); ElMessage.error(json.message);
return res.data; return res.data;
} }
this.dashboards = this.dashboards.filter( this.dashboards = this.dashboards.filter((d: any) => d.id !== this.currentDashboard.id);
(d: any) => d.id !== this.currentDashboard.id
);
const key = [ const key = [
this.currentDashboard.layer, this.currentDashboard.layer,
this.currentDashboard.entity, this.currentDashboard.entity,

View File

@ -15,13 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Instance } from "@/types/selector"; import type { Instance } from "@/types/selector";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { Conditions, Log } from "@/types/demand-log"; import type { Conditions, Log } from "@/types/demand-log";
interface DemandLogState { interface DemandLogState {
containers: Instance[]; containers: Instance[];
@ -75,16 +75,12 @@ export const demandLogStore = defineStore({
}, },
async getContainers(serviceInstanceId: string) { async getContainers(serviceInstanceId: string) {
if (!serviceInstanceId) { if (!serviceInstanceId) {
return new Promise((resolve) => return new Promise((resolve) => resolve({ errors: "No service instance" }));
resolve({ errors: "No service instance" })
);
} }
const condition = { const condition = {
serviceInstanceId, serviceInstanceId,
}; };
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("fetchContainers").params({ condition });
.query("fetchContainers")
.params({ condition });
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
@ -112,9 +108,7 @@ export const demandLogStore = defineStore({
return res.data; return res.data;
} }
this.total = res.data.data.logs.logs.length; this.total = res.data.data.logs.logs.length;
const logs = res.data.data.logs.logs const logs = res.data.data.logs.logs.map((d: Log) => d.content).join("\n");
.map((d: Log) => d.content)
.join("\n");
this.setLogs(logs); this.setLogs(logs);
return res.data; return res.data;
}, },

View File

@ -15,8 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
import { import type {
EBPFTaskCreationRequest, EBPFTaskCreationRequest,
EBPFProfilingSchedule, EBPFProfilingSchedule,
EBPFTaskList, EBPFTaskList,
@ -24,7 +24,7 @@ import {
} from "@/types/ebpf"; } from "@/types/ebpf";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
interface EbpfState { interface EbpfState {
taskList: EBPFTaskList[]; taskList: EBPFTaskList[];
eBPFSchedules: EBPFProfilingSchedule[]; eBPFSchedules: EBPFProfilingSchedule[];
@ -61,9 +61,7 @@ export const ebpfStore = defineStore({
this.analyzeTrees = tree; this.analyzeTrees = tree;
}, },
async getCreateTaskData(serviceId: string) { async getCreateTaskData(serviceId: string) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getCreateTaskData").params({ serviceId });
.query("getCreateTaskData")
.params({ serviceId });
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
@ -76,9 +74,7 @@ export const ebpfStore = defineStore({
return res.data; return res.data;
}, },
async createTask(param: EBPFTaskCreationRequest) { async createTask(param: EBPFTaskCreationRequest) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("saveEBPFTask").params({ request: param });
.query("saveEBPFTask")
.params({ request: param });
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
@ -89,17 +85,11 @@ export const ebpfStore = defineStore({
}); });
return res.data; return res.data;
}, },
async getTaskList(params: { async getTaskList(params: { serviceId: string; serviceInstanceId: string; targets: string[] }) {
serviceId: string;
serviceInstanceId: string;
targets: string[];
}) {
if (!params.serviceId) { if (!params.serviceId) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params);
.query("getEBPFTasks")
.params(params);
this.tip = ""; this.tip = "";
if (res.data.errors) { if (res.data.errors) {
@ -118,9 +108,7 @@ export const ebpfStore = defineStore({
if (!params.taskId) { if (!params.taskId) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getEBPFSchedules").params({ ...params });
.query("getEBPFSchedules")
.params({ ...params });
if (res.data.errors) { if (res.data.errors) {
this.eBPFSchedules = []; this.eBPFSchedules = [];
@ -148,9 +136,7 @@ export const ebpfStore = defineStore({
if (!params.timeRanges.length) { if (!params.timeRanges.length) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getEBPFResult").params(params);
.query("getEBPFResult")
.params(params);
if (res.data.errors) { if (res.data.errors) {
this.analyzeTrees = []; this.analyzeTrees = [];

View File

@ -17,9 +17,9 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { Event, QueryEventCondition } from "@/types/events"; import type { Event, QueryEventCondition } from "@/types/events";
import { Instance, Endpoint } from "@/types/selector"; import type { Instance, Endpoint } from "@/types/selector";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
@ -94,8 +94,7 @@ export const eventStore = defineStore({
return res.data; return res.data;
} }
if (res.data.data.fetchEvents) { if (res.data.data.fetchEvents) {
this.events = (res.data.data.fetchEvents.events || []).map( this.events = (res.data.data.fetchEvents.events || []).map((item: Event) => {
(item: Event) => {
let scope = "Service"; let scope = "Service";
if (item.source.serviceInstance) { if (item.source.serviceInstance) {
scope = "ServiceInstance"; scope = "ServiceInstance";
@ -108,8 +107,7 @@ export const eventStore = defineStore({
item.endTime = Number(item.startTime) + 60000; item.endTime = Number(item.startTime) + 60000;
} }
return item; return item;
} });
);
} }
return res.data; return res.data;
}, },

View File

@ -15,10 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Instance, Endpoint, Service } from "@/types/selector"; import type { Instance, Endpoint, Service } from "@/types/selector";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
@ -82,10 +82,9 @@ export const logStore = defineStore({
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }
this.instances = [ this.instances = [{ value: "0", label: "All" }, ...res.data.data.pods] || [
{ value: " 0", label: "All" }, { value: " 0", label: "All" },
...res.data.data.pods, ];
] || [{ value: " 0", label: "All" }];
return res.data; return res.data;
}, },
async getEndpoints(id: string, keyword?: string) { async getEndpoints(id: string, keyword?: string) {
@ -100,16 +99,13 @@ export const logStore = defineStore({
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }
this.endpoints = [ this.endpoints = [{ value: "0", label: "All" }, ...res.data.data.pods] || [
{ value: "0", label: "All" }, { value: "0", label: "All" },
...res.data.data.pods, ];
] || [{ value: "0", label: "All" }];
return res.data; return res.data;
}, },
async getLogsByKeywords() { async getLogsByKeywords() {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryLogsByKeywords").params({});
.query("queryLogsByKeywords")
.params({});
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;

View File

@ -15,12 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { EBPFTaskList, ProcessNode } from "@/types/ebpf"; import type { EBPFTaskList, ProcessNode } from "@/types/ebpf";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { Call } from "@/types/topology"; import type { Call } from "@/types/topology";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
interface NetworkProfilingState { interface NetworkProfilingState {
@ -117,11 +117,9 @@ export const networkProfilingStore = defineStore({
when4xx: string; when4xx: string;
when5xx: string; when5xx: string;
minDuration: number; minDuration: number;
}[] }[],
) { ) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("newNetworkProfiling").params({
.query("newNetworkProfiling")
.params({
request: { request: {
instanceId, instanceId,
samplings: params, samplings: params,
@ -133,17 +131,11 @@ export const networkProfilingStore = defineStore({
} }
return res.data; return res.data;
}, },
async getTaskList(params: { async getTaskList(params: { serviceId: string; serviceInstanceId: string; targets: string[] }) {
serviceId: string;
serviceInstanceId: string;
targets: string[];
}) {
if (!params.serviceId) { if (!params.serviceId) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getEBPFTasks").params(params);
.query("getEBPFTasks")
.params(params);
this.networkTip = ""; this.networkTip = "";
if (res.data.errors) { if (res.data.errors) {
@ -162,9 +154,7 @@ export const networkProfilingStore = defineStore({
if (!taskId) { if (!taskId) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("aliveNetworkProfiling").params({ taskId });
.query("aliveNetworkProfiling")
.params({ taskId });
this.aliveMessage = ""; this.aliveMessage = "";
if (res.data.errors) { if (res.data.errors) {
@ -176,14 +166,9 @@ export const networkProfilingStore = defineStore({
} }
return res.data; return res.data;
}, },
async getProcessTopology(params: { async getProcessTopology(params: { duration: any; serviceInstanceId: string }) {
duration: any;
serviceInstanceId: string;
}) {
this.loadNodes = true; this.loadNodes = true;
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getProcessTopology").params(params);
.query("getProcessTopology")
.params(params);
this.loadNodes = false; this.loadNodes = false;
if (res.data.errors) { if (res.data.errors) {
this.nodes = []; this.nodes = [];

View File

@ -15,18 +15,18 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Endpoint } from "@/types/selector"; import type { Endpoint } from "@/types/selector";
import { import type {
TaskListItem, TaskListItem,
SegmentSpan, SegmentSpan,
ProfileAnalyzationTrees, ProfileAnalyzationTrees,
TaskLog, TaskLog,
ProfileTaskCreationRequest, ProfileTaskCreationRequest,
} from "@/types/profile"; } from "@/types/profile";
import { Trace, Span } from "@/types/trace"; import type { Trace, Span } from "@/types/trace";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
interface ProfileState { interface ProfileState {
@ -99,9 +99,7 @@ export const profileStore = defineStore({
return res.data; return res.data;
}, },
async getTaskList() { async getTaskList() {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getProfileTaskList").params(this.condition);
.query("getProfileTaskList")
.params(this.condition);
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
@ -122,9 +120,7 @@ export const profileStore = defineStore({
if (!params.taskID) { if (!params.taskID) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getProfileTaskSegmentList").params(params);
.query("getProfileTaskSegmentList")
.params(params);
if (res.data.errors) { if (res.data.errors) {
this.segmentList = []; this.segmentList = [];
@ -151,9 +147,7 @@ export const profileStore = defineStore({
if (!params.segmentId) { if (!params.segmentId) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryProfileSegment").params(params);
.query("queryProfileSegment")
.params(params);
if (res.data.errors) { if (res.data.errors) {
this.segmentSpans = []; this.segmentSpans = [];
return res.data; return res.data;
@ -189,9 +183,7 @@ export const profileStore = defineStore({
if (!params.timeRanges.length) { if (!params.timeRanges.length) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getProfileAnalyze").params(params);
.query("getProfileAnalyze")
.params(params);
if (res.data.errors) { if (res.data.errors) {
this.analyzeTrees = []; this.analyzeTrees = [];
@ -222,9 +214,7 @@ export const profileStore = defineStore({
return res.data; return res.data;
}, },
async getTaskLogs(param: { taskID: string }) { async getTaskLogs(param: { taskID: string }) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getProfileTaskLogs").params(param);
.query("getProfileTaskLogs")
.params(param);
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;

View File

@ -15,10 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Service, Instance, Endpoint, Process } from "@/types/selector"; import type { Service, Instance, Endpoint, Process } from "@/types/selector";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
interface SelectorState { interface SelectorState {
services: Service[]; services: Service[];
@ -82,9 +82,7 @@ export const selectorStore = defineStore({
return res.data || {}; return res.data || {};
}, },
async fetchServices(layer: string): Promise<AxiosResponse> { async fetchServices(layer: string): Promise<AxiosResponse> {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryServices").params({ layer });
.query("queryServices")
.params({ layer });
if (!res.data.errors) { if (!res.data.errors) {
this.services = res.data.data.services || []; this.services = res.data.data.services || [];

View File

@ -16,12 +16,12 @@
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { store } from "@/store"; import { store } from "@/store";
import { Service } from "@/types/selector"; import type { Service } from "@/types/selector";
import { Node, Call } from "@/types/topology"; import type { Node, Call } from "@/types/topology";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import query from "@/graphql/fetch"; import query from "@/graphql/fetch";
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
@ -139,9 +139,7 @@ export const topologyStore = defineStore({
if (depth > 3) { if (depth > 3) {
const services = topo.nodes const services = topo.nodes
.map((item: Node) => item.id) .map((item: Node) => item.id)
.filter( .filter((d: string) => ![...ids, ...pods, ...serviceIds].includes(d));
(d: string) => ![...ids, ...pods, ...serviceIds].includes(d)
);
if (!services.length) { if (!services.length) {
const nodes = [...res.nodes, ...json.nodes, ...topo.nodes]; const nodes = [...res.nodes, ...json.nodes, ...topo.nodes];
const calls = [...res.calls, ...json.calls, ...topo.calls]; const calls = [...res.calls, ...json.calls, ...topo.calls];
@ -152,23 +150,10 @@ export const topologyStore = defineStore({
if (depth > 4) { if (depth > 4) {
const nodeIds = data.nodes const nodeIds = data.nodes
.map((item: Node) => item.id) .map((item: Node) => item.id)
.filter( .filter((d: string) => ![...services, ...ids, ...pods, ...serviceIds].includes(d));
(d: string) =>
![...services, ...ids, ...pods, ...serviceIds].includes(d)
);
if (!nodeIds.length) { if (!nodeIds.length) {
const nodes = [ const nodes = [...res.nodes, ...json.nodes, ...topo.nodes, ...data.nodes];
...res.nodes, const calls = [...res.calls, ...json.calls, ...topo.calls, ...data.calls];
...json.nodes,
...topo.nodes,
...data.nodes,
];
const calls = [
...res.calls,
...json.calls,
...topo.calls,
...data.calls,
];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
return; return;
} }
@ -189,18 +174,8 @@ export const topologyStore = defineStore({
]; ];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
} else { } else {
const nodes = [ const nodes = [...res.nodes, ...json.nodes, ...topo.nodes, ...data.nodes];
...res.nodes, const calls = [...res.calls, ...json.calls, ...topo.calls, ...data.calls];
...json.nodes,
...topo.nodes,
...data.nodes,
];
const calls = [
...res.calls,
...json.calls,
...topo.calls,
...data.calls,
];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
} }
} else { } else {
@ -220,9 +195,7 @@ export const topologyStore = defineStore({
}, },
async getServicesTopology(serviceIds: string[]) { async getServicesTopology(serviceIds: string[]) {
const duration = useAppStoreWithOut().durationTime; const duration = useAppStoreWithOut().durationTime;
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getServicesTopology").params({
.query("getServicesTopology")
.params({
serviceIds, serviceIds,
duration, duration,
}); });
@ -235,9 +208,7 @@ export const topologyStore = defineStore({
const serverServiceId = useSelectorStore().currentService.id; const serverServiceId = useSelectorStore().currentService.id;
const clientServiceId = useSelectorStore().currentDestService.id; const clientServiceId = useSelectorStore().currentDestService.id;
const duration = useAppStoreWithOut().durationTime; const duration = useAppStoreWithOut().durationTime;
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("getInstanceTopology").params({
.query("getInstanceTopology")
.params({
clientServiceId, clientServiceId,
serverServiceId, serverServiceId,
duration, duration,
@ -272,9 +243,7 @@ export const topologyStore = defineStore({
if (depth > 3) { if (depth > 3) {
const endpoints = topo.nodes const endpoints = topo.nodes
.map((item: Node) => item.id) .map((item: Node) => item.id)
.filter( .filter((d: string) => ![...ids, ...pods, ...endpointIds].includes(d));
(d: string) => ![...ids, ...pods, ...endpointIds].includes(d)
);
if (!endpoints.length) { if (!endpoints.length) {
const nodes = [...res.nodes, ...json.nodes, ...topo.nodes]; const nodes = [...res.nodes, ...json.nodes, ...topo.nodes];
const calls = [...res.calls, ...json.calls, ...topo.calls]; const calls = [...res.calls, ...json.calls, ...topo.calls];
@ -286,22 +255,11 @@ export const topologyStore = defineStore({
const nodeIds = data.nodes const nodeIds = data.nodes
.map((item: Node) => item.id) .map((item: Node) => item.id)
.filter( .filter(
(d: string) => (d: string) => ![...endpoints, ...ids, ...pods, ...endpointIds].includes(d),
![...endpoints, ...ids, ...pods, ...endpointIds].includes(d)
); );
if (!nodeIds.length) { if (!nodeIds.length) {
const nodes = [ const nodes = [...res.nodes, ...json.nodes, ...topo.nodes, ...data.nodes];
...res.nodes, const calls = [...res.calls, ...json.calls, ...topo.calls, ...data.calls];
...json.nodes,
...topo.nodes,
...data.nodes,
];
const calls = [
...res.calls,
...json.calls,
...topo.calls,
...data.calls,
];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
return; return;
} }
@ -322,18 +280,8 @@ export const topologyStore = defineStore({
]; ];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
} else { } else {
const nodes = [ const nodes = [...res.nodes, ...json.nodes, ...topo.nodes, ...data.nodes];
...res.nodes, const calls = [...res.calls, ...json.calls, ...topo.calls, ...data.calls];
...json.nodes,
...topo.nodes,
...data.nodes,
];
const calls = [
...res.calls,
...json.calls,
...topo.calls,
...data.calls,
];
this.setTopology({ nodes, calls }); this.setTopology({ nodes, calls });
} }
} else { } else {
@ -390,10 +338,7 @@ export const topologyStore = defineStore({
return { calls, nodes }; return { calls, nodes };
}, },
async getNodeMetricValue(param: { async getNodeMetricValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
queryStr: string;
conditions: { [key: string]: unknown };
}) {
const res: AxiosResponse = await query(param); const res: AxiosResponse = await query(param);
if (res.data.errors) { if (res.data.errors) {
@ -454,10 +399,7 @@ export const topologyStore = defineStore({
ElMessage.error(res.errors); ElMessage.error(res.errors);
} }
}, },
async getLegendMetrics(param: { async getLegendMetrics(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
queryStr: string;
conditions: { [key: string]: unknown };
}) {
const res: AxiosResponse = await query(param); const res: AxiosResponse = await query(param);
if (res.data.errors) { if (res.data.errors) {

View File

@ -15,11 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { Instance, Endpoint, Service } from "@/types/selector"; import type { Instance, Endpoint, Service } from "@/types/selector";
import { Trace, Span } from "@/types/trace"; import type { Trace, Span } from "@/types/trace";
import { store } from "@/store"; import { store } from "@/store";
import graphql from "@/graphql"; import graphql from "@/graphql";
import { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { QueryOrders } from "@/views/dashboard/data"; import { QueryOrders } from "@/views/dashboard/data";
@ -169,9 +169,7 @@ export const traceStore = defineStore({
return res.data; return res.data;
}, },
async getTraceSpans(params: { traceId: string }) { async getTraceSpans(params: { traceId: string }) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryTrace").params(params);
.query("queryTrace")
.params(params);
if (res.data.errors) { if (res.data.errors) {
return res.data; return res.data;
} }
@ -180,9 +178,7 @@ export const traceStore = defineStore({
return res.data; return res.data;
}, },
async getSpanLogs(params: any) { async getSpanLogs(params: any) {
const res: AxiosResponse = await graphql const res: AxiosResponse = await graphql.query("queryServiceLogs").params(params);
.query("queryServiceLogs")
.params(params);
if (res.data.errors) { if (res.data.errors) {
this.traceSpanLogs = []; this.traceSpanLogs = [];
return res.data; return res.data;

View File

@ -1,4 +1,3 @@
import { DurationTime } from "@/types/app";
/** /**
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { DurationTime } from "./app"; import type { DurationTime } from "./app";
export interface Conditions { export interface Conditions {
container: string; container: string;

2
src/types/ebpf.d.ts vendored
View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Process } from "./selector"; import type { Process } from "./selector";
export interface EBPFTaskCreationRequest { export interface EBPFTaskCreationRequest {
serviceId: string; serviceId: string;
processLabels: string[]; processLabels: string[];

View File

@ -38,7 +38,6 @@ declare interface ComponentElRef<T extends HTMLElement = HTMLDivElement> {
$el: T; $el: T;
} }
declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null;
ComponentElRef<T> | null;
declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>; declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;

View File

@ -15,11 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import dayjs from "dayjs"; import dayjs from "dayjs";
export default function dateFormatStep( export default function dateFormatStep(date: Date, step: string, monthDayDiff?: boolean): string {
date: Date,
step: string,
monthDayDiff?: boolean
): string {
const year = date.getFullYear(); const year = date.getFullYear();
const monthTemp = date.getMonth() + 1; const monthTemp = date.getMonth() + 1;
let month = `${monthTemp}`; let month = `${monthTemp}`;

View File

@ -39,10 +39,7 @@ export function addResizeListener(element: any, fn: () => unknown): void {
export function removeResizeListener(element: any, fn: () => unknown): void { export function removeResizeListener(element: any, fn: () => unknown): void {
if (!element || !element.__resizeListeners__) return; if (!element || !element.__resizeListeners__) return;
element.__resizeListeners__.splice( element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
element.__resizeListeners__.indexOf(fn),
1
);
if (!element.__resizeListeners__.length) { if (!element.__resizeListeners__.length) {
element.__ro__.disconnect(); element.__ro__.disconnect();
} }

View File

@ -53,12 +53,7 @@ export function isNumber(val: unknown): val is number {
} }
export function isPromise<T = any>(val: unknown): val is Promise<T> { export function isPromise<T = any>(val: unknown): val is Promise<T> {
return ( return is(val, "Promise") && isObject(val) && isFunction(val.then) && isFunction(val.catch);
is(val, "Promise") &&
isObject(val) &&
isFunction(val.then) &&
isFunction(val.catch)
);
} }
export function isString(val: unknown): val is string { export function isString(val: unknown): val is string {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Duration } from "@/types/app"; import type { Duration } from "@/types/app";
import { TimeType } from "@/constants/data"; import { TimeType } from "@/constants/data";
const timeFormat = (time: Date[]): Duration => { const timeFormat = (time: Date[]): Duration => {

View File

@ -17,11 +17,7 @@
class Vec2 extends Float32Array { class Vec2 extends Float32Array {
constructor(v?: unknown, y?: unknown) { constructor(v?: unknown, y?: unknown) {
super(2); super(2);
if ( if (v instanceof Vec2 || v instanceof Float32Array || (v instanceof Array && v.length == 2)) {
v instanceof Vec2 ||
v instanceof Float32Array ||
(v instanceof Array && v.length == 2)
) {
this[0] = v[0]; this[0] = v[0];
this[1] = v[1]; this[1] = v[1];
} else if (typeof v === "number" && typeof y === "number") { } else if (typeof v === "number" && typeof y === "number") {

View File

@ -17,19 +17,11 @@
class Vec3 extends Float32Array { class Vec3 extends Float32Array {
constructor(v?: unknown, y?: unknown, z?: unknown) { constructor(v?: unknown, y?: unknown, z?: unknown) {
super(3); super(3);
if ( if (v instanceof Vec3 || v instanceof Float32Array || (v instanceof Array && v.length == 3)) {
v instanceof Vec3 ||
v instanceof Float32Array ||
(v instanceof Array && v.length == 3)
) {
this[0] = v[0]; this[0] = v[0];
this[1] = v[1]; this[1] = v[1];
this[2] = v[2]; this[2] = v[2];
} else if ( } else if (typeof v === "number" && typeof y === "number" && typeof z === "number") {
typeof v === "number" &&
typeof y === "number" &&
typeof z === "number"
) {
this[0] = v; this[0] = v;
this[1] = y; this[1] = y;
this[2] = z; this[2] = z;
@ -158,17 +150,9 @@ class Vec3 extends Float32Array {
} }
static norm(x: unknown, y: unknown, z: unknown): Vec3 { static norm(x: unknown, y: unknown, z: unknown): Vec3 {
const rtn = new Vec3(); const rtn = new Vec3();
if ( if (x instanceof Vec3 || x instanceof Float32Array || (x instanceof Array && x.length == 3)) {
x instanceof Vec3 ||
x instanceof Float32Array ||
(x instanceof Array && x.length == 3)
) {
rtn.copy(x); rtn.copy(x);
} else if ( } else if (typeof x === "number" && typeof y === "number" && typeof z === "number") {
typeof x === "number" &&
typeof y === "number" &&
typeof z === "number"
) {
rtn.xyz(x, y, z); rtn.xyz(x, y, z);
} }
return rtn.norm(); return rtn.norm();

View File

@ -14,9 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<Dashboard v-if="dashboardStore.currentDashboard" /> <Dashboard v-if="dashboardStore.currentDashboard" />
<div v-else class="no-root"> <div v-else class="no-root"> {{ t("noRoot") }} {{ dashboardStore.layerId }} </div>
{{ t("noRoot") }} {{ dashboardStore.layerId }}
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -45,7 +43,7 @@ async function getDashboard() {
(d: { name: string; isRoot: boolean; layer: string; entity: string }) => (d: { name: string; isRoot: boolean; layer: string; entity: string }) =>
d.layer === dashboardStore.layerId && d.layer === dashboardStore.layerId &&
[EntityType[0].value, EntityType[1].value].includes(d.entity) && [EntityType[0].value, EntityType[1].value].includes(d.entity) &&
d.isRoot d.isRoot,
); );
if (!item) { if (!item) {
appStore.setPageTitle(dashboardStore.layer); appStore.setPageTitle(dashboardStore.layer);

View File

@ -55,12 +55,7 @@ limitations under the License. -->
<el-switch v-model="auto" @change="handleAuto" style="height: 25px" /> <el-switch v-model="auto" @change="handleAuto" style="height: 25px" />
<div class="auto-time ml-5"> <div class="auto-time ml-5">
<span class="auto-select"> <span class="auto-select">
<input <input type="number" v-model="autoTime" @change="changeAutoTime" min="1" />
type="number"
v-model="autoTime"
@change="changeAutoTime"
min="1"
/>
</span> </span>
{{ t("second") }} {{ t("second") }}
<i class="ml-10">{{ t("timeReload") }}</i> <i class="ml-10">{{ t("timeReload") }}</i>
@ -87,8 +82,7 @@ const utcMin = ref<number>(appStore.utcMin);
appStore.setPageTitle("Setting"); appStore.setPageTitle("Setting");
const handleReload = () => { const handleReload = () => {
const gap = const gap = appStore.duration.end.getTime() - appStore.duration.start.getTime();
appStore.duration.end.getTime() - appStore.duration.start.getTime();
const dates: Date[] = [ const dates: Date[] = [
getLocalTime(appStore.utc, new Date(new Date().getTime() - gap)), getLocalTime(appStore.utc, new Date(new Date().getTime() - gap)),
getLocalTime(appStore.utc, new Date()), getLocalTime(appStore.utc, new Date()),

View File

@ -14,11 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="timeline-table clear"> <div class="timeline-table clear">
<div <div v-for="(i, index) in alarmStore.alarms" :key="index" class="clear timeline-item">
v-for="(i, index) in alarmStore.alarms"
:key="index"
class="clear timeline-item"
>
<div class="g-sm-3 grey sm hide-xs time-line tr"> <div class="g-sm-3 grey sm hide-xs time-line tr">
{{ dateFormat(parseInt(i.startTime)) }} {{ dateFormat(parseInt(i.startTime)) }}
</div> </div>
@ -50,11 +46,7 @@ limitations under the License. -->
:destroy-on-close="true" :destroy-on-close="true"
@closed="isShowDetails = false" @closed="isShowDetails = false"
> >
<div <div class="mb-10 clear alarm-detail" v-for="(item, index) in AlarmDetailCol" :key="index">
class="mb-10 clear alarm-detail"
v-for="(item, index) in AlarmDetailCol"
:key="index"
>
<span class="g-sm-2 grey">{{ t(item.value) }}:</span> <span class="g-sm-2 grey">{{ t(item.value) }}:</span>
<span v-if="item.label === 'startTime'"> <span v-if="item.label === 'startTime'">
{{ dateFormat(currentDetail[item.label]) }} {{ dateFormat(currentDetail[item.label]) }}
@ -74,11 +66,7 @@ limitations under the License. -->
{{ t(i.text) }} {{ t(i.text) }}
</span> </span>
</li> </li>
<li <li v-for="event in currentEvents" :key="event.uuid" @click="viewEventDetail(event)">
v-for="event in currentEvents"
:key="event.uuid"
@click="viewEventDetail(event)"
>
<span <span
v-for="(d, index) of EventsDetailHeaders" v-for="(d, index) of EventsDetailHeaders"
:class="d.class" :class="d.class"
@ -106,29 +94,18 @@ limitations under the License. -->
@closed="showEventDetails = false" @closed="showEventDetails = false"
> >
<div class="event-detail"> <div class="event-detail">
<div <div class="mb-10" v-for="(eventKey, index) in EventsDetailKeys" :key="index">
class="mb-10"
v-for="(eventKey, index) in EventsDetailKeys"
:key="index"
>
<span class="keys">{{ t(eventKey.text) }}</span> <span class="keys">{{ t(eventKey.text) }}</span>
<span v-if="eventKey.class === 'parameters'"> <span v-if="eventKey.class === 'parameters'">
<span v-for="(d, index) of currentEvent[eventKey.class]" :key="index"> <span v-for="(d, index) of currentEvent[eventKey.class]" :key="index">
{{ d.key }}={{ d.value }}; {{ d.key }}={{ d.value }};
</span> </span>
</span> </span>
<span <span v-else-if="eventKey.class === 'startTime' || eventKey.class === 'endTime'">
v-else-if="
eventKey.class === 'startTime' || eventKey.class === 'endTime'
"
>
{{ dateFormat(currentEvent[eventKey.class]) }} {{ dateFormat(currentEvent[eventKey.class]) }}
</span> </span>
<span v-else-if="eventKey.class === 'source'" class="source"> <span v-else-if="eventKey.class === 'source'" class="source">
<span <span>{{ t("service") }}: {{ currentEvent[eventKey.class].service }}</span>
>{{ t("service") }}:
{{ currentEvent[eventKey.class].service }}</span
>
<div v-show="currentEvent[eventKey.class].endpoint"> <div v-show="currentEvent[eventKey.class].endpoint">
{{ t("endpoint") }}: {{ t("endpoint") }}:
{{ currentEvent[eventKey.class].endpoint }} {{ currentEvent[eventKey.class].endpoint }}
@ -146,7 +123,7 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue"; import { ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { Alarm, Event } from "@/types/alarm"; import type { Alarm, Event } from "@/types/alarm";
import { useAlarmStore } from "@/store/modules/alarm"; import { useAlarmStore } from "@/store/modules/alarm";
import { EventsDetailHeaders, AlarmDetailCol, EventsDetailKeys } from "./data"; import { EventsDetailHeaders, AlarmDetailCol, EventsDetailKeys } from "./data";
import { dateFormat } from "@/utils/dateFormat"; import { dateFormat } from "@/utils/dateFormat";
@ -164,11 +141,9 @@ function showDetails(item: Alarm) {
isShowDetails.value = true; isShowDetails.value = true;
currentDetail.value = item; currentDetail.value = item;
currentEvents.value = item.events; currentEvents.value = item.events;
alarmTags.value = currentDetail.value.tags.map( alarmTags.value = currentDetail.value.tags.map((d: { key: string; value: string }) => {
(d: { key: string; value: string }) => {
return `${d.key} = ${d.value}`; return `${d.key} = ${d.value}`;
} });
);
} }
function viewEventDetail(event: Event) { function viewEventDetail(event: Event) {

View File

@ -71,9 +71,7 @@ const entity = ref<string>("");
const keyword = ref<string>(""); const keyword = ref<string>("");
const pageNum = ref<number>(1); const pageNum = ref<number>(1);
const total = computed(() => const total = computed(() =>
alarmStore.alarms.length === pageSize alarmStore.alarms.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
? pageSize * pageNum.value + 1
: pageSize * pageNum.value
); );
refreshAlarms({ pageNum: 1 }); refreshAlarms({ pageNum: 1 });

View File

@ -52,10 +52,7 @@ limitations under the License. -->
</span> </span>
</div> </div>
</el-popover> </el-popover>
<span <span class="tags-tip" :class="type !== 'ALARM' && tagArr.length ? 'link-tips' : ''">
class="tags-tip"
:class="type !== 'ALARM' && tagArr.length ? 'link-tips' : ''"
>
<a <a
target="blank" target="blank"
href="https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/configuration-vocabulary.md" href="https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/configuration-vocabulary.md"
@ -211,7 +208,7 @@ watch(
() => appStore.durationTime, () => appStore.durationTime,
() => { () => {
fetchTagKeys(); fetchTagKeys();
} },
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -41,7 +41,7 @@ import Tool from "./panel/Tool.vue";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import Configuration from "./configuration"; import Configuration from "./configuration";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
export default defineComponent({ export default defineComponent({
name: "Dashboard", name: "Dashboard",
@ -64,7 +64,7 @@ export default defineComponent({
layoutKey.value = `${layer}_${entity}_${name}`; layoutKey.value = `${layer}_${entity}_${name}`;
} }
const c: { configuration: string; id: string } = JSON.parse( const c: { configuration: string; id: string } = JSON.parse(
sessionStorage.getItem(layoutKey.value) || "{}" sessionStorage.getItem(layoutKey.value) || "{}",
); );
const layout: any = c.configuration || {}; const layout: any = c.configuration || {};

View File

@ -33,9 +33,7 @@ limitations under the License. -->
{{ t("reloadDashboards") }} {{ t("reloadDashboards") }}
</el-button> </el-button>
<router-link to="/dashboard/new"> <router-link to="/dashboard/new">
<el-button size="small" type="primary"> <el-button size="small" type="primary"> + {{ t("newDashboard") }} </el-button>
+ {{ t("newDashboard") }}
</el-button>
</router-link> </router-link>
</div> </div>
<div class="table"> <div class="table">
@ -74,10 +72,7 @@ limitations under the License. -->
<el-button size="small" @click="handleRename(scope.row)"> <el-button size="small" @click="handleRename(scope.row)">
{{ t("rename") }} {{ t("rename") }}
</el-button> </el-button>
<el-popconfirm <el-popconfirm :title="t('deleteTitle')" @confirm="handleDelete(scope.row)">
:title="t('deleteTitle')"
@confirm="handleDelete(scope.row)"
>
<template #reference> <template #reference>
<el-button size="small" type="danger"> <el-button size="small" type="danger">
{{ t("delete") }} {{ t("delete") }}
@ -87,11 +82,7 @@ limitations under the License. -->
<el-popconfirm <el-popconfirm
:title="t('rootTitle')" :title="t('rootTitle')"
@confirm="setRoot(scope.row)" @confirm="setRoot(scope.row)"
v-if=" v-if="[EntityType[0].value, EntityType[1].value].includes(scope.row.entity)"
[EntityType[0].value, EntityType[1].value].includes(
scope.row.entity
)
"
> >
<template #reference> <template #reference>
<el-button size="small" style="width: 110px" type="danger"> <el-button size="small" style="width: 110px" type="danger">
@ -143,11 +134,11 @@ limitations under the License. -->
import { ref } from "vue"; import { ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { ElMessageBox, ElMessage } from "element-plus"; import { ElMessageBox, ElMessage } from "element-plus";
import type { ElTable } from "element-plus"; import { ElTable } from "element-plus";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import router from "@/router"; import router from "@/router";
import { DashboardItem, LayoutConfig } from "@/types/dashboard"; import type { DashboardItem, LayoutConfig } from "@/types/dashboard";
import { saveFile, readFile } from "@/utils/file"; import { saveFile, readFile } from "@/utils/file";
import { EntityType } from "./data"; import { EntityType } from "./data";
import { isEmptyObject } from "@/utils/is"; import { isEmptyObject } from "@/utils/is";
@ -181,7 +172,7 @@ async function importTemplates(event: any) {
const { layer, name, entity } = item.configuration; const { layer, name, entity } = item.configuration;
const index = dashboardStore.dashboards.findIndex( const index = dashboardStore.dashboards.findIndex(
(d: DashboardItem) => (d: DashboardItem) =>
d.name === name && d.entity === entity && d.layer === layer && !item.id d.name === name && d.entity === entity && d.layer === layer && !item.id,
); );
if (index > -1) { if (index > -1) {
return ElMessage.error(t("nameError")); return ElMessage.error(t("nameError"));
@ -190,9 +181,7 @@ async function importTemplates(event: any) {
loading.value = true; loading.value = true;
for (const item of arr) { for (const item of arr) {
const { layer, name, entity, isRoot, children } = item.configuration; const { layer, name, entity, isRoot, children } = item.configuration;
const index = dashboardStore.dashboards.findIndex( const index = dashboardStore.dashboards.findIndex((d: DashboardItem) => d.id === item.id);
(d: DashboardItem) => d.id === item.id
);
const p: DashboardItem = { const p: DashboardItem = {
name: name.split(" ").join("-"), name: name.split(" ").join("-"),
layer: layer, layer: layer,
@ -215,11 +204,9 @@ function exportTemplates() {
if (!multipleSelection.value.length) { if (!multipleSelection.value.length) {
return; return;
} }
const arr = multipleSelection.value.sort( const arr = multipleSelection.value.sort((a: DashboardItem, b: DashboardItem) => {
(a: DashboardItem, b: DashboardItem) => {
return a.name.localeCompare(b.name); return a.name.localeCompare(b.name);
} });
);
const templates = arr.map((d: DashboardItem) => { const templates = arr.map((d: DashboardItem) => {
const key = [d.layer, d.entity, d.name].join("_"); const key = [d.layer, d.entity, d.name].join("_");
const layout = JSON.parse(sessionStorage.getItem(key) || "{}"); const layout = JSON.parse(sessionStorage.getItem(key) || "{}");
@ -240,7 +227,7 @@ function optimizeTemplate(
standard?: unknown; standard?: unknown;
label?: string; label?: string;
value?: string; value?: string;
})[] })[],
) { ) {
for (const child of children || []) { for (const child of children || []) {
delete child.moved; delete child.moved;
@ -266,9 +253,7 @@ function optimizeTemplate(
if (!(child.metrics && child.metrics.length && child.metrics[0])) { if (!(child.metrics && child.metrics.length && child.metrics[0])) {
delete child.metrics; delete child.metrics;
} }
if ( if (!(child.metricTypes && child.metricTypes.length && child.metricTypes[0])) {
!(child.metricTypes && child.metricTypes.length && child.metricTypes[0])
) {
delete child.metricTypes; delete child.metricTypes;
} }
if (child.metricConfig && child.metricConfig.length) { if (child.metricConfig && child.metricConfig.length) {
@ -295,11 +280,7 @@ function optimizeTemplate(
optimizeTemplate(item.children); optimizeTemplate(item.children);
} }
} }
if ( if (["Trace", "Topology", "Tab", "Profile", "Ebpf", "Log"].includes(child.type)) {
["Trace", "Topology", "Tab", "Profile", "Ebpf", "Log"].includes(
child.type
)
) {
delete child.widget; delete child.widget;
} }
} }
@ -345,7 +326,7 @@ async function setRoot(row: DashboardItem) {
JSON.stringify({ JSON.stringify({
id: d.id, id: d.id,
configuration: c, configuration: c,
}) }),
); );
} }
} else { } else {
@ -373,7 +354,7 @@ async function setRoot(row: DashboardItem) {
JSON.stringify({ JSON.stringify({
id: d.id, id: d.id,
configuration: c, configuration: c,
}) }),
); );
} }
} }
@ -447,7 +428,7 @@ async function updateName(d: DashboardItem, value: string) {
JSON.stringify({ JSON.stringify({
id: d.id, id: d.id,
configuration: c, configuration: c,
}) }),
); );
searchText.value = ""; searchText.value = "";
} }
@ -462,14 +443,12 @@ async function handleDelete(row: DashboardItem) {
} }
function searchDashboards(pageIndex?: any) { function searchDashboards(pageIndex?: any) {
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const arr = list.filter((d: { name: string }) => const arr = list.filter((d: { name: string }) => d.name.includes(searchText.value));
d.name.includes(searchText.value)
);
total.value = arr.length; total.value = arr.length;
dashboards.value = arr.filter( dashboards.value = arr.filter(
(d: { name: string }, index: number) => (d: { name: string }, index: number) =>
index < pageIndex * pageSize && index >= (pageIndex - 1) * pageSize index < pageIndex * pageSize && index >= (pageIndex - 1) * pageSize,
); );
currentPage.value = pageIndex; currentPage.value = pageIndex;
} }

View File

@ -17,11 +17,7 @@ limitations under the License. -->
<div class="title">{{ t("newDashboard") }}</div> <div class="title">{{ t("newDashboard") }}</div>
<div class="item"> <div class="item">
<div class="label">{{ t("name") }}</div> <div class="label">{{ t("name") }}</div>
<el-input <el-input size="default" v-model="states.name" placeholder="Please input name" />
size="default"
v-model="states.name"
placeholder="Please input name"
/>
</div> </div>
<div class="item"> <div class="item">
<div class="label">{{ t("layer") }}</div> <div class="label">{{ t("layer") }}</div>
@ -77,9 +73,7 @@ dashboardStore.setDashboards();
const onCreate = () => { const onCreate = () => {
const index = dashboardStore.dashboards.findIndex( const index = dashboardStore.dashboards.findIndex(
(d: { name: string; entity: string; layer: string }) => (d: { name: string; entity: string; layer: string }) =>
d.name === states.name && d.name === states.name && states.entity === d.entity && states.selectedLayer === d.layer,
states.entity === d.entity &&
states.selectedLayer === d.layer
); );
if (!states.name) { if (!states.name) {
ElMessage.error(t("nameEmptyError")); ElMessage.error(t("nameEmptyError"));

View File

@ -13,21 +13,11 @@ limitations under the License. -->
<template> <template>
<div class="item"> <div class="item">
<span class="label">{{ t("textUrl") }}</span> <span class="label">{{ t("textUrl") }}</span>
<el-input <el-input class="input" v-model="url" size="small" @change="changeConfig({ url })" />
class="input"
v-model="url"
size="small"
@change="changeConfig({ url })"
/>
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("content") }}</span> <span class="label">{{ t("content") }}</span>
<el-input <el-input class="input" v-model="content" size="small" @change="changeConfig({ content })" />
class="input"
v-model="content"
size="small"
@change="changeConfig({ content })"
/>
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("textAlign") }}</span> <span class="label">{{ t("textAlign") }}</span>

View File

@ -13,12 +13,7 @@ limitations under the License. -->
<template> <template>
<div class="item"> <div class="item">
<span class="label">{{ t("text") }}</span> <span class="label">{{ t("text") }}</span>
<el-input <el-input class="input" v-model="text" size="small" @change="changeConfig({ text })" />
class="input"
v-model="text"
size="small"
@change="changeConfig({ text })"
/>
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("textAlign") }}</span> <span class="label">{{ t("textAlign") }}</span>

View File

@ -44,7 +44,7 @@ import { ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { DepthList } from "../data"; import { DepthList } from "../data";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();

View File

@ -60,18 +60,10 @@ limitations under the License. -->
<el-collapse-item :title="t('widgetOptions')" name="3"> <el-collapse-item :title="t('widgetOptions')" name="3">
<WidgetOptions /> <WidgetOptions />
</el-collapse-item> </el-collapse-item>
<el-collapse-item <el-collapse-item :title="t('associateOptions')" name="4" v-if="hasAssociate">
:title="t('associateOptions')"
name="4"
v-if="hasAssociate"
>
<AssociateOptions /> <AssociateOptions />
</el-collapse-item> </el-collapse-item>
<el-collapse-item <el-collapse-item :title="t('relatedTraceOptions')" name="5" v-if="hasAssociate">
:title="t('relatedTraceOptions')"
name="5"
v-if="hasAssociate"
>
<RelatedTraceOptions /> <RelatedTraceOptions />
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -91,7 +83,7 @@ import { reactive, defineComponent, ref, computed } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
import graphs from "../graphs"; import graphs from "../graphs";
import CustomOptions from "./widget/index"; import CustomOptions from "./widget/index";
@ -125,9 +117,8 @@ export default defineComponent({
const tips = computed(() => encodeURIComponent(widget.value.tips || "")); const tips = computed(() => encodeURIComponent(widget.value.tips || ""));
const hasAssociate = computed(() => const hasAssociate = computed(() =>
["Bar", "Line", "Area", "TopList"].includes( ["Bar", "Line", "Area", "TopList"].includes(
dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type,
dashboardStore.selectedGrid.graph.type ),
)
); );
function getSource(source: unknown) { function getSource(source: unknown) {

View File

@ -32,21 +32,17 @@ import { ref, computed } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import getDashboard from "@/hooks/useDashboardsSession"; import getDashboard from "@/hooks/useDashboardsSession";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const associate = dashboardStore.selectedGrid.associate || []; const associate = dashboardStore.selectedGrid.associate || [];
const widgetIds = ref<string[]>( const widgetIds = ref<string[]>(associate.map((d: { widgetId: string }) => d.widgetId));
associate.map((d: { widgetId: string }) => d.widgetId)
);
const widgets: any = computed(() => { const widgets: any = computed(() => {
const widgetList = getDashboard(dashboardStore.currentDashboard).widgets; const widgetList = getDashboard(dashboardStore.currentDashboard).widgets;
const items = []; const items = [];
for (const d of widgetList) { for (const d of widgetList) {
const isLinear = ["Bar", "Line", "Area"].includes( const isLinear = ["Bar", "Line", "Area"].includes((d.graph && d.graph.type) || "");
(d.graph && d.graph.type) || ""
);
if (isLinear && d.id && dashboardStore.selectedGrid.id !== d.id) { if (isLinear && d.id && dashboardStore.selectedGrid.id !== d.id) {
items.push({ value: d.id, label: (d.widget && d.widget.name) || d.id }); items.push({ value: d.id, label: (d.widget && d.widget.name) || d.id });
} }

View File

@ -50,7 +50,7 @@ import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import getDashboard from "@/hooks/useDashboardsSession"; import getDashboard from "@/hooks/useDashboardsSession";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
@ -80,9 +80,7 @@ function updateWidgetName(param: { [key: string]: string }) {
return; return;
} }
const { widgets } = getDashboard(dashboardStore.currentDashboard); const { widgets } = getDashboard(dashboardStore.currentDashboard);
const item = widgets.find( const item = widgets.find((d: LayoutConfig) => d.widget && d.widget.name === n);
(d: LayoutConfig) => d.widget && d.widget.name === n
);
if (item) { if (item) {
ElMessage.error(t("duplicateName")); ElMessage.error(t("duplicateName"));
return; return;

View File

@ -85,7 +85,7 @@ limitations under the License. -->
import { computed, reactive } from "vue"; import { computed, reactive } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { LegendOptions } from "@/types/dashboard"; import type { LegendOptions } from "@/types/dashboard";
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();

View File

@ -26,11 +26,7 @@ limitations under the License. -->
/> />
</div> </div>
<div>{{ t("metrics") }}</div> <div>{{ t("metrics") }}</div>
<div <div v-for="(metric, index) in states.metrics" :key="index" class="metric-item">
v-for="(metric, index) in states.metrics"
:key="index"
class="metric-item"
>
<Selector <Selector
:value="metric" :value="metric"
:options="states.metricList" :options="states.metricList"
@ -53,24 +49,12 @@ limitations under the License. -->
<Icon class="cp mr-5" iconName="mode_edit" size="middle" /> <Icon class="cp mr-5" iconName="mode_edit" size="middle" />
</span> </span>
</template> </template>
<Standard <Standard @update="queryMetrics" :currentMetricConfig="currentMetricConfig" :index="index" />
@update="queryMetrics"
:currentMetricConfig="currentMetricConfig"
:index="index"
/>
</el-popover> </el-popover>
<span <span v-show="states.isList || states.metricTypes[0] === ProtocolTypes.ReadMetricsValues">
v-show="
states.isList ||
states.metricTypes[0] === ProtocolTypes.ReadMetricsValues
"
>
<Icon <Icon
class="cp mr-5" class="cp mr-5"
v-if=" v-if="index === states.metrics.length - 1 && states.metrics.length < defaultLen"
index === states.metrics.length - 1 &&
states.metrics.length < defaultLen
"
iconName="add_circle_outlinecontrol_point" iconName="add_circle_outlinecontrol_point"
size="middle" size="middle"
@click="addMetric" @click="addMetric"
@ -99,7 +83,7 @@ limitations under the License. -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, computed } from "vue"; import { reactive, ref, computed } from "vue";
import { Option } from "@/types/app"; import type { Option } from "@/types/app";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { import {
MetricTypes, MetricTypes,
@ -119,7 +103,7 @@ import {
useGetMetricEntity, useGetMetricEntity,
} from "@/hooks/useMetricsProcessor"; } from "@/hooks/useMetricsProcessor";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { DashboardItem, MetricConfigOpt } from "@/types/dashboard"; import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
import Standard from "./Standard.vue"; import Standard from "./Standard.vue";
/*global defineEmits */ /*global defineEmits */
@ -128,9 +112,7 @@ const emit = defineEmits(["update", "loading"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const metrics = computed(() => dashboardStore.selectedGrid.metrics || []); const metrics = computed(() => dashboardStore.selectedGrid.metrics || []);
const graph = computed(() => dashboardStore.selectedGrid.graph || {}); const graph = computed(() => dashboardStore.selectedGrid.graph || {});
const metricTypes = computed( const metricTypes = computed(() => dashboardStore.selectedGrid.metricTypes || []);
() => dashboardStore.selectedGrid.metricTypes || []
);
const states = reactive<{ const states = reactive<{
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
@ -165,17 +147,12 @@ const setVisTypes = computed(() => {
let graphs = []; let graphs = [];
if (dashboardStore.entity === EntityType[0].value) { if (dashboardStore.entity === EntityType[0].value) {
graphs = ChartTypes.filter( graphs = ChartTypes.filter(
(d: Option) => (d: Option) => ![ChartTypes[7].value, ChartTypes[8].value].includes(d.value),
![ChartTypes[7].value, ChartTypes[8].value].includes(d.value)
); );
} else if (dashboardStore.entity === EntityType[1].value) { } else if (dashboardStore.entity === EntityType[1].value) {
graphs = ChartTypes.filter( graphs = ChartTypes.filter((d: Option) => !PodsChartTypes.includes(d.value));
(d: Option) => !PodsChartTypes.includes(d.value)
);
} else { } else {
graphs = ChartTypes.filter( graphs = ChartTypes.filter((d: Option) => !ListChartTypes.includes(d.value));
(d: Option) => !ListChartTypes.includes(d.value)
);
} }
return graphs; return graphs;
@ -192,29 +169,21 @@ async function setMetricType(chart?: any) {
} }
arr = json.data.metrics; arr = json.data.metrics;
} }
states.metricList = (arr || []).filter( states.metricList = (arr || []).filter((d: { catalog: string; type: string }) => {
(d: { catalog: string; type: string }) => {
if (states.isList) { if (states.isList) {
if ( if (d.type === MetricsType.REGULAR_VALUE || d.type === MetricsType.LABELED_VALUE) {
d.type === MetricsType.REGULAR_VALUE ||
d.type === MetricsType.LABELED_VALUE
) {
return d; return d;
} }
} else if (g.type === "Table") { } else if (g.type === "Table") {
if ( if (d.type === MetricsType.LABELED_VALUE || d.type === MetricsType.REGULAR_VALUE) {
d.type === MetricsType.LABELED_VALUE ||
d.type === MetricsType.REGULAR_VALUE
) {
return d; return d;
} }
} else { } else {
return d; return d;
} }
} });
); const metrics: any = states.metricList.filter((d: { value: string; type: string }) =>
const metrics: any = states.metricList.filter( states.metrics.includes(d.value),
(d: { value: string; type: string }) => states.metrics.includes(d.value)
); );
if (metrics.length) { if (metrics.length) {
@ -247,15 +216,10 @@ async function setMetricType(chart?: any) {
function setDashboards(type?: string) { function setDashboards(type?: string) {
const chart = const chart =
type || type || (dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type);
(dashboardStore.selectedGrid.graph &&
dashboardStore.selectedGrid.graph.type);
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const arr = list.reduce( const arr = list.reduce(
( (prev: (DashboardItem & { label: string; value: string })[], d: DashboardItem) => {
prev: (DashboardItem & { label: string; value: string })[],
d: DashboardItem
) => {
if (d.layer === dashboardStore.layerId) { if (d.layer === dashboardStore.layerId) {
if ( if (
(d.entity === EntityType[0].value && chart === "ServiceList") || (d.entity === EntityType[0].value && chart === "ServiceList") ||
@ -271,7 +235,7 @@ function setDashboards(type?: string) {
} }
return prev; return prev;
}, },
[] [],
); );
states.dashboardList = arr.length ? arr : [{ label: "", value: "" }]; states.dashboardList = arr.length ? arr : [{ label: "", value: "" }];
@ -296,10 +260,7 @@ function changeChartType(item: Option) {
defaultLen.value = 10; defaultLen.value = 10;
} }
function changeMetrics( function changeMetrics(index: number, arr: (Option & { type: string })[] | any) {
index: number,
arr: (Option & { type: string })[] | any
) {
if (!arr.length) { if (!arr.length) {
states.metricTypeList = []; states.metricTypeList = [];
states.metricTypes = []; states.metricTypes = [];
@ -326,9 +287,7 @@ function changeMetrics(
function changeMetricType(index: number, opt: Option[] | any) { function changeMetricType(index: number, opt: Option[] | any) {
const metric = const metric =
states.metricList.filter( states.metricList.filter((d: Option) => states.metrics[index] === d.value)[0] || {};
(d: Option) => states.metrics[index] === d.value
)[0] || {};
const l = setMetricTypeList(metric.type); const l = setMetricTypeList(metric.type);
if (states.isList) { if (states.isList) {
states.metricTypes[index] = opt[0].value; states.metricTypes[index] = opt[0].value;

View File

@ -96,7 +96,7 @@ import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { SortOrder, CalculationOpts } from "../../../data"; import { SortOrder, CalculationOpts } from "../../../data";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { MetricConfigOpt } from "@/types/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard";
import { ListChartTypes, ProtocolTypes } from "../../../data"; import { ListChartTypes, ProtocolTypes } from "../../../data";
/*global defineEmits, defineProps */ /*global defineEmits, defineProps */
@ -115,17 +115,14 @@ const currentMetric = ref<MetricConfigOpt>({
topN: props.currentMetricConfig.topN || 10, topN: props.currentMetricConfig.topN || 10,
}); });
const metricTypes = dashboardStore.selectedGrid.metricTypes || []; const metricTypes = dashboardStore.selectedGrid.metricTypes || [];
const metricType = computed( const metricType = computed(() => (dashboardStore.selectedGrid.metricTypes || [])[props.index]);
() => (dashboardStore.selectedGrid.metricTypes || [])[props.index]
);
const hasLabel = computed(() => { const hasLabel = computed(() => {
const graph = dashboardStore.selectedGrid.graph || {}; const graph = dashboardStore.selectedGrid.graph || {};
return ( return (
ListChartTypes.includes(graph.type) || ListChartTypes.includes(graph.type) ||
[ [ProtocolTypes.ReadLabeledMetricsValues, ProtocolTypes.ReadMetricsValues].includes(
ProtocolTypes.ReadLabeledMetricsValues, metricType.value,
ProtocolTypes.ReadMetricsValues, )
].includes(metricType.value)
); );
}); });
const isTopn = computed(() => const isTopn = computed(() =>
@ -133,7 +130,7 @@ const isTopn = computed(() =>
ProtocolTypes.SortMetrics, ProtocolTypes.SortMetrics,
ProtocolTypes.ReadSampledRecords, ProtocolTypes.ReadSampledRecords,
ProtocolTypes.ReadRecords, ProtocolTypes.ReadRecords,
].includes(metricTypes[props.index]) ].includes(metricTypes[props.index]),
); );
function updateConfig(index: number, param: { [key: string]: string }) { function updateConfig(index: number, param: { [key: string]: string }) {
const key = Object.keys(param)[0]; const key = Object.keys(param)[0];
@ -142,10 +139,7 @@ function updateConfig(index: number, param: { [key: string]: string }) {
} }
changeConfigs(index, { [key]: decodeURIComponent(param[key]) }); changeConfigs(index, { [key]: decodeURIComponent(param[key]) });
} }
function changeConfigs( function changeConfigs(index: number, param: { [key: string]: string | number }) {
index: number,
param: { [key: string]: string | number }
) {
const metricConfig = dashboardStore.selectedGrid.metricConfig || []; const metricConfig = dashboardStore.selectedGrid.metricConfig || [];
metricConfig[index] = { ...metricConfig[index], ...param }; metricConfig[index] = { ...metricConfig[index], ...param };
@ -162,7 +156,7 @@ watch(
...props.currentMetricConfig, ...props.currentMetricConfig,
topN: props.currentMetricConfig.topN || 10, topN: props.currentMetricConfig.topN || 10,
}; };
} },
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="log-wrapper flex-v"> <div class="log-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="profile-wrapper flex-v"> <div class="profile-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="event-wrapper flex-v"> <div class="event-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="log-wrapper flex-v"> <div class="log-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />
@ -43,7 +38,7 @@ import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import Header from "../related/log/Header.vue"; import Header from "../related/log/Header.vue";
import List from "../related/log/List.vue"; import List from "../related/log/List.vue";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
import type { PropType } from "vue"; import type { PropType } from "vue";
/*global defineProps */ /*global defineProps */

View File

@ -15,12 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="profile-wrapper flex-v"> <div class="profile-wrapper flex-v">
<div class="title">Network Profiling</div> <div class="title">Network Profiling</div>
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="operation cp"> <span class="operation cp">
<Icon iconName="ellipsis_v" size="middle" /> <Icon iconName="ellipsis_v" size="middle" />

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="profile-wrapper flex-v"> <div class="profile-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -108,7 +108,7 @@ import { ref, watch, defineComponent, toRefs } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import controls from "./tab"; import controls from "./tab";
import { dragIgnoreFrom } from "../data"; import { dragIgnoreFrom } from "../data";
@ -131,21 +131,17 @@ export default defineComponent({
const { t } = useI18n(); const { t } = useI18n();
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const route = useRoute(); const route = useRoute();
const activeTabIndex = ref<number>( const activeTabIndex = ref<number>(Number(route.params.activeTabIndex) || 0);
Number(route.params.activeTabIndex) || 0
);
const activeTabWidget = ref<string>(""); const activeTabWidget = ref<string>("");
const editTabIndex = ref<number>(NaN); // edit tab item name const editTabIndex = ref<number>(NaN); // edit tab item name
const canEditTabName = ref<boolean>(false); const canEditTabName = ref<boolean>(false);
const needQuery = ref<boolean>(false); const needQuery = ref<boolean>(false);
dashboardStore.setActiveTabIndex(activeTabIndex); dashboardStore.setActiveTabIndex(activeTabIndex);
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex((d: LayoutConfig) => d.i === props.data.i);
(d: LayoutConfig) => d.i === props.data.i
);
if (dashboardStore.layout[l].children.length) { if (dashboardStore.layout[l].children.length) {
dashboardStore.setCurrentTabItems( dashboardStore.setCurrentTabItems(
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children,
); );
dashboardStore.setActiveTabIndex(activeTabIndex.value, props.data.i); dashboardStore.setActiveTabIndex(activeTabIndex.value, props.data.i);
} }
@ -156,11 +152,9 @@ export default defineComponent({
dashboardStore.activeGridItem(props.data.i); dashboardStore.activeGridItem(props.data.i);
dashboardStore.selectWidget(props.data); dashboardStore.selectWidget(props.data);
dashboardStore.setActiveTabIndex(idx); dashboardStore.setActiveTabIndex(idx);
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex((d: LayoutConfig) => d.i === props.data.i);
(d: LayoutConfig) => d.i === props.data.i
);
dashboardStore.setCurrentTabItems( dashboardStore.setCurrentTabItems(
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children,
); );
needQuery.value = true; needQuery.value = true;
if (route.params.activeTabIndex) { if (route.params.activeTabIndex) {
@ -205,17 +199,13 @@ export default defineComponent({
function clickTabGrid(e: Event, item: LayoutConfig) { function clickTabGrid(e: Event, item: LayoutConfig) {
e.stopPropagation(); e.stopPropagation();
activeTabWidget.value = item.i; activeTabWidget.value = item.i;
dashboardStore.activeGridItem( dashboardStore.activeGridItem(`${props.data.i}-${activeTabIndex.value}-${item.i}`);
`${props.data.i}-${activeTabIndex.value}-${item.i}`
);
handleClick(e); handleClick(e);
} }
function layoutUpdatedEvent() { function layoutUpdatedEvent() {
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex((d: LayoutConfig) => d.i === props.data.i);
(d: LayoutConfig) => d.i === props.data.i
);
dashboardStore.setCurrentTabItems( dashboardStore.setCurrentTabItems(
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children,
); );
} }
function copyLink() { function copyLink() {
@ -242,7 +232,7 @@ export default defineComponent({
} else { } else {
activeTabWidget.value = ""; activeTabWidget.value = "";
} }
} },
); );
watch( watch(
() => dashboardStore.currentTabIndex, () => dashboardStore.currentTabIndex,
@ -250,11 +240,9 @@ export default defineComponent({
activeTabIndex.value = dashboardStore.currentTabIndex; activeTabIndex.value = dashboardStore.currentTabIndex;
dashboardStore.activeGridItem(props.data.i); dashboardStore.activeGridItem(props.data.i);
dashboardStore.selectWidget(props.data); dashboardStore.selectWidget(props.data);
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex((d: LayoutConfig) => d.i === props.data.i);
(d: LayoutConfig) => d.i === props.data.i
);
dashboardStore.setCurrentTabItems( dashboardStore.setCurrentTabItems(
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.layout[l].children[activeTabIndex.value].children,
); );
needQuery.value = true; needQuery.value = true;
if (route.params.activeTabIndex) { if (route.params.activeTabIndex) {
@ -262,7 +250,7 @@ export default defineComponent({
p = p + "/tab/" + activeTabIndex.value; p = p + "/tab/" + activeTabIndex.value;
history.replaceState({}, "", p); history.replaceState({}, "", p);
} }
} },
); );
return { return {
handleClick, handleClick,

View File

@ -15,12 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="topology"> <div class="topology">
<div class="header"> <div class="header">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span> <span>
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -15,12 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="time-range"> <div class="time-range">
<div class="header"> <div class="header">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span> <span>
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -15,12 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="topology flex-v"> <div class="topology flex-v">
<div class="operation"> <div class="operation">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span> <span>
<Icon iconName="ellipsis_v" size="middle" /> <Icon iconName="ellipsis_v" size="middle" />

View File

@ -14,12 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="trace-wrapper flex-v"> <div class="trace-wrapper flex-v">
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span class="delete cp"> <span class="delete cp">
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />

View File

@ -23,20 +23,10 @@ limitations under the License. -->
<div> <div>
<el-tooltip :content="widget.tips || ''"> <el-tooltip :content="widget.tips || ''">
<span> <span>
<Icon <Icon iconName="info_outline" size="sm" class="operation" v-show="widget.tips" />
iconName="info_outline"
size="sm"
class="operation"
v-show="widget.tips"
/>
</span> </span>
</el-tooltip> </el-tooltip>
<el-popover <el-popover placement="bottom" trigger="click" :width="100" v-if="dashboardStore.editMode">
placement="bottom"
trigger="click"
:width="100"
v-if="dashboardStore.editMode"
>
<template #reference> <template #reference>
<span> <span>
<Icon iconName="ellipsis_v" size="middle" class="operation" /> <Icon iconName="ellipsis_v" size="middle" class="operation" />
@ -77,7 +67,7 @@ limitations under the License. -->
<script lang="ts"> <script lang="ts">
import { toRefs, reactive, defineComponent, ref, watch, computed } from "vue"; import { toRefs, reactive, defineComponent, ref, watch, computed } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { LayoutConfig } from "@/types/dashboard"; import type { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
@ -89,7 +79,7 @@ import {
useGetMetricEntity, useGetMetricEntity,
} from "@/hooks/useMetricsProcessor"; } from "@/hooks/useMetricsProcessor";
import { EntityType, ListChartTypes } from "../data"; import { EntityType, ListChartTypes } from "../data";
import { EventParams } from "@/types/dashboard"; import type { EventParams } from "@/types/dashboard";
import getDashboard from "@/hooks/useDashboardsSession"; import getDashboard from "@/hooks/useDashboardsSession";
const props = { const props = {
@ -118,13 +108,10 @@ export default defineComponent({
const graph = computed(() => props.data.graph || {}); const graph = computed(() => props.data.graph || {});
const widget = computed(() => props.data.widget || {}); const widget = computed(() => props.data.widget || {});
const isList = computed(() => const isList = computed(() =>
ListChartTypes.includes((props.data.graph && props.data.graph.type) || "") ListChartTypes.includes((props.data.graph && props.data.graph.type) || ""),
); );
if ( if ((props.needQuery || !dashboardStore.currentDashboard.id) && !isList.value) {
(props.needQuery || !dashboardStore.currentDashboard.id) &&
!isList.value
) {
queryMetrics(); queryMetrics();
} }
@ -169,9 +156,7 @@ export default defineComponent({
const associate = (props.data.associate && props.data.associate) || []; const associate = (props.data.associate && props.data.associate) || [];
for (const item of associate) { for (const item of associate) {
const widget = widgets.find( const widget = widgets.find((d: LayoutConfig) => d.id === item.widgetId);
(d: LayoutConfig) => d.id === item.widgetId
);
if (widget) { if (widget) {
widget.filters = { widget.filters = {
dataIndex: params.dataIndex, dataIndex: params.dataIndex,
@ -196,7 +181,7 @@ export default defineComponent({
return; return;
} }
queryMetrics(); queryMetrics();
} },
); );
watch( watch(
() => [selectorStore.currentService, selectorStore.currentDestService], () => [selectorStore.currentService, selectorStore.currentDestService],
@ -210,7 +195,7 @@ export default defineComponent({
) { ) {
queryMetrics(); queryMetrics();
} }
} },
); );
watch( watch(
() => [selectorStore.currentPod, selectorStore.currentDestPod], () => [selectorStore.currentPod, selectorStore.currentDestPod],
@ -225,20 +210,18 @@ export default defineComponent({
return; return;
} }
queryMetrics(); queryMetrics();
} },
); );
watch( watch(
() => [selectorStore.currentProcess, selectorStore.currentDestProcess], () => [selectorStore.currentProcess, selectorStore.currentDestProcess],
() => { () => {
if ( if (!(selectorStore.currentDestProcess && selectorStore.currentProcess)) {
!(selectorStore.currentDestProcess && selectorStore.currentProcess)
) {
return; return;
} }
if (dashboardStore.entity === EntityType[7].value) { if (dashboardStore.entity === EntityType[7].value) {
queryMetrics(); queryMetrics();
} }
} },
); );
watch( watch(
() => appStore.durationTime, () => appStore.durationTime,
@ -249,7 +232,7 @@ export default defineComponent({
if (dashboardStore.entity === EntityType[1].value) { if (dashboardStore.entity === EntityType[1].value) {
queryMetrics(); queryMetrics();
} }
} },
); );
return { return {

View File

@ -140,9 +140,7 @@ export const MetricTypes: {
value: "readLabeledMetricsValues", value: "readLabeledMetricsValues",
}, },
], ],
HEATMAP: [ HEATMAP: [{ label: "read heatmap values in the duration", value: "readHeatMap" }],
{ label: "read heatmap values in the duration", value: "readHeatMap" },
],
SAMPLED_RECORD: [{ label: "get sorted topN values", value: "readRecords" }], SAMPLED_RECORD: [{ label: "get sorted topN values", value: "readRecords" }],
}; };

View File

@ -14,22 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<Line <Line :data="data" :intervalTime="intervalTime" :config="config" @click="clickEvent" />
:data="data"
:intervalTime="intervalTime"
:config="config"
@click="clickEvent"
/>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { PropType } from "vue"; import type { PropType } from "vue";
import Line from "./Line.vue"; import Line from "./Line.vue";
import { import type { AreaConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard";
AreaConfig,
EventParams,
RelatedTrace,
Filters,
} from "@/types/dashboard";
/*global defineProps, defineEmits */ /*global defineProps, defineEmits */
const emits = defineEmits(["click"]); const emits = defineEmits(["click"]);

View File

@ -26,12 +26,7 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { import type { BarConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard";
BarConfig,
EventParams,
RelatedTrace,
Filters,
} from "@/types/dashboard";
import useLegendProcess from "@/hooks/useLegendProcessor"; import useLegendProcess from "@/hooks/useLegendProcessor";
/*global defineProps, defineEmits */ /*global defineProps, defineEmits */
@ -55,14 +50,12 @@ const props = defineProps({
default: () => ({}), default: () => ({}),
}, },
}); });
const { showEchartsLegend, isRight, chartColors } = useLegendProcess( const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend);
props.config.legend
);
const option = computed(() => getOption()); const option = computed(() => getOption());
function getOption() { function getOption() {
const keys = Object.keys(props.data || {}).filter( const keys = Object.keys(props.data || {}).filter(
(i: any) => Array.isArray(props.data[i]) && props.data[i].length (i: any) => Array.isArray(props.data[i]) && props.data[i].length,
); );
const temp = keys.map((i: string) => { const temp = keys.map((i: string) => {
if (!props.intervalTime) { if (!props.intervalTime) {

View File

@ -30,9 +30,10 @@ limitations under the License. -->
<div class="center no-data" v-else>{{ t("noData") }}</div> <div class="center no-data" v-else>{{ t("noData") }}</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, PropType } from "vue"; import { computed } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { CardConfig, MetricConfigOpt } from "@/types/dashboard"; import type { CardConfig, MetricConfigOpt } from "@/types/dashboard";
/*global defineProps */ /*global defineProps */
const props = defineProps({ const props = defineProps({
@ -55,9 +56,7 @@ const metricConfig = computed(() => props.config.metricConfig || []);
const key = computed(() => Object.keys(props.data)[0]); const key = computed(() => Object.keys(props.data)[0]);
const singleVal = computed(() => Number(props.data[key.value])); const singleVal = computed(() => Number(props.data[key.value]));
const unit = computed( const unit = computed(
() => () => metricConfig.value[0] && encodeURIComponent(metricConfig.value[0].unit || ""),
metricConfig.value[0] &&
encodeURIComponent(metricConfig.value[0].unit || "")
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -63,17 +63,14 @@ import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { EndpointListConfig } from "@/types/dashboard"; import type { EndpointListConfig } from "@/types/dashboard";
import { Endpoint } from "@/types/selector"; import type { Endpoint } from "@/types/selector";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useMetricsProcessor";
useQueryPodsMetrics,
usePodsSource,
} from "@/hooks/useMetricsProcessor";
import { EntityType } from "../data"; import { EntityType } from "../data";
import router from "@/router"; import router from "@/router";
import getDashboard from "@/hooks/useDashboardsSession"; import getDashboard from "@/hooks/useDashboardsSession";
import { MetricConfigOpt } from "@/types/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard";
import ColumnGraph from "./components/ColumnGraph.vue"; import ColumnGraph from "./components/ColumnGraph.vue";
/*global defineProps */ /*global defineProps */
@ -135,25 +132,17 @@ async function queryEndpointMetrics(currentPods: Endpoint[]) {
const metrics = props.config.metrics || []; const metrics = props.config.metrics || [];
const types = props.config.metricTypes || []; const types = props.config.metricTypes || [];
if (metrics.length && metrics[0] && types.length && types[0]) { if (metrics.length && metrics[0] && types.length && types[0]) {
const params = await useQueryPodsMetrics( const params = await useQueryPodsMetrics(currentPods, props.config, EntityType[2].value);
currentPods,
props.config,
EntityType[2].value
);
const json = await dashboardStore.fetchMetricValue(params); const json = await dashboardStore.fetchMetricValue(params);
if (json.errors) { if (json.errors) {
ElMessage.error(json.errors); ElMessage.error(json.errors);
return; return;
} }
const { data, names, metricConfigArr, metricTypesArr } = usePodsSource( const { data, names, metricConfigArr, metricTypesArr } = usePodsSource(currentPods, json, {
currentPods,
json,
{
...props.config, ...props.config,
metricConfig: metricConfig.value, metricConfig: metricConfig.value,
} });
);
endpoints.value = data; endpoints.value = data;
colMetrics.value = names; colMetrics.value = names;
metricTypes.value = metricTypesArr; metricTypes.value = metricTypesArr;
@ -173,7 +162,7 @@ function clickEndpoint(scope: any) {
return; return;
} }
router.push( router.push(
`/dashboard/${dashboard.layer}/${dashboard.entity}/${selectorStore.currentService.id}/${scope.row.id}/${dashboard.name}` `/dashboard/${dashboard.layer}/${dashboard.entity}/${selectorStore.currentService.id}/${scope.row.id}/${dashboard.name}`,
); );
} }
async function searchList() { async function searchList() {
@ -191,13 +180,13 @@ watch(
} }
metricConfig.value = props.config.metricConfig; metricConfig.value = props.config.metricConfig;
queryEndpointMetrics(endpoints.value); queryEndpointMetrics(endpoints.value);
} },
); );
watch( watch(
() => selectorStore.currentService, () => selectorStore.currentService,
() => { () => {
queryEndpoints(); queryEndpoints();
} },
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -93,16 +93,13 @@ import { ElMessage } from "element-plus";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { InstanceListConfig } from "@/types/dashboard"; import type { InstanceListConfig } from "@/types/dashboard";
import { Instance } from "@/types/selector"; import type { Instance } from "@/types/selector";
import { import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useMetricsProcessor";
useQueryPodsMetrics,
usePodsSource,
} from "@/hooks/useMetricsProcessor";
import { EntityType } from "../data"; import { EntityType } from "../data";
import router from "@/router"; import router from "@/router";
import getDashboard from "@/hooks/useDashboardsSession"; import getDashboard from "@/hooks/useDashboardsSession";
import { MetricConfigOpt } from "@/types/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard";
import ColumnGraph from "./components/ColumnGraph.vue"; import ColumnGraph from "./components/ColumnGraph.vue";
/*global defineProps */ /*global defineProps */
@ -151,9 +148,7 @@ async function queryInstance() {
instances.value = []; instances.value = [];
return; return;
} }
instances.value = selectorStore.pods.filter( instances.value = selectorStore.pods.filter((d: unknown, index: number) => index < pageSize);
(d: unknown, index: number) => index < pageSize
);
queryInstanceMetrics(instances.value); queryInstanceMetrics(instances.value);
} }
@ -165,11 +160,7 @@ async function queryInstanceMetrics(currentInstances: Instance[]) {
const types = props.config.metricTypes || []; const types = props.config.metricTypes || [];
if (metrics.length && metrics[0] && types.length && types[0]) { if (metrics.length && metrics[0] && types.length && types[0]) {
const params = await useQueryPodsMetrics( const params = await useQueryPodsMetrics(currentInstances, props.config, EntityType[3].value);
currentInstances,
props.config,
EntityType[3].value
);
const json = await dashboardStore.fetchMetricValue(params); const json = await dashboardStore.fetchMetricValue(params);
if (json.errors) { if (json.errors) {
@ -182,7 +173,7 @@ async function queryInstanceMetrics(currentInstances: Instance[]) {
{ {
...props.config, ...props.config,
metricConfig: metricConfig.value, metricConfig: metricConfig.value,
} },
); );
instances.value = data; instances.value = data;
colMetrics.value = names; colMetrics.value = names;
@ -204,9 +195,9 @@ function clickInstance(scope: any) {
return; return;
} }
router.push( router.push(
`/dashboard/${dashboard.layer}/${dashboard.entity}/${ `/dashboard/${dashboard.layer}/${dashboard.entity}/${selectorStore.currentService.id}/${
selectorStore.currentService.id scope.row.id
}/${scope.row.id}/${dashboard.name.split(" ").join("-")}` }/${dashboard.name.split(" ").join("-")}`,
); );
} }
@ -221,11 +212,9 @@ function changePage(pageIndex: number) {
function searchList() { function searchList() {
const searchInstances = selectorStore.pods.filter((d: { label: string }) => const searchInstances = selectorStore.pods.filter((d: { label: string }) =>
d.label.includes(searchText.value) d.label.includes(searchText.value),
);
instances.value = searchInstances.filter(
(d: unknown, index: number) => index < pageSize
); );
instances.value = searchInstances.filter((d: unknown, index: number) => index < pageSize);
queryInstanceMetrics(instances.value); queryInstanceMetrics(instances.value);
} }
@ -241,13 +230,13 @@ watch(
} }
metricConfig.value = props.config.metricConfig; metricConfig.value = props.config.metricConfig;
queryInstanceMetrics(instances.value); queryInstanceMetrics(instances.value);
} },
); );
watch( watch(
() => selectorStore.currentService, () => selectorStore.currentService,
() => { () => {
queryInstance(); queryInstance();
} },
); );
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -27,12 +27,7 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { import type { LineConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard";
LineConfig,
EventParams,
RelatedTrace,
Filters,
} from "@/types/dashboard";
import Legend from "./components/Legend.vue"; import Legend from "./components/Legend.vue";
import useLegendProcess from "@/hooks/useLegendProcessor"; import useLegendProcess from "@/hooks/useLegendProcessor";
@ -69,12 +64,10 @@ const props = defineProps({
const setRight = ref<boolean>(false); const setRight = ref<boolean>(false);
const option = computed(() => getOption()); const option = computed(() => getOption());
function getOption() { function getOption() {
const { showEchartsLegend, isRight, chartColors } = useLegendProcess( const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend);
props.config.legend
);
setRight.value = isRight; setRight.value = isRight;
const keys = Object.keys(props.data || {}).filter( const keys = Object.keys(props.data || {}).filter(
(i: any) => Array.isArray(props.data[i]) && props.data[i].length (i: any) => Array.isArray(props.data[i]) && props.data[i].length,
); );
const temp = keys.map((i: any) => { const temp = keys.map((i: any) => {
const serie: any = { const serie: any = {
@ -156,8 +149,7 @@ function getOption() {
left: 0, left: 0,
right: 10, right: 10,
bottom: 5, bottom: 5,
containLabel: containLabel: props.config.showlabels === undefined ? true : props.config.showlabels,
props.config.showlabels === undefined ? true : props.config.showlabels,
}, },
xAxis: { xAxis: {
type: "category", type: "category",

Some files were not shown because too many files have changed in this diff Show More