31 Commits

Author SHA1 Message Date
Fine0830
a1c7a00a83 refactor: change router components (#349) 2023-11-27 21:08:19 -08:00
Fine0830
20e3ef12fe style: add underline for text widget (#348) 2023-11-28 11:14:06 +08:00
block666
0ea95b1ca6 Remove the description of OpenFunction in the UI. (#347) 2023-11-27 07:50:05 -08:00
Fine0830
a18ac3372e fix: change colors to match dark theme for Network Profiling (#346) 2023-11-26 04:02:41 -08:00
Fine0830
c1c086d999 fix: change metrics config, fix tab routes (#345) 2023-11-25 21:15:43 -08:00
Fine0830
ac57b229fc feat: enhance topology layout and fix calls metrics (#344) 2023-11-23 16:37:26 +08:00
Fine0830
d8a3c27345 fix: Log associate with Trace (#343) 2023-11-22 13:03:59 +08:00
Rick
03e1508afc feat: support to save and load theme setting from localStorage (#342) 2023-11-21 16:48:57 +08:00
Fine0830
8618a9440e fix: polish list style (#341) 2023-11-21 11:24:27 +08:00
Fine0830
02c5724859 fix: change log widget and loading mask style (#340) 2023-11-17 13:16:48 +08:00
Fine0830
c6d1c49569 refactor: enhance the Log widget (#339) 2023-11-17 10:15:39 +08:00
weixiang1862
8f3ce7d371 feat: add Nginx menu i18n (#338) 2023-11-16 21:23:10 +08:00
Fine0830
2085dc84b9 fix: set the height for trace widget (#337) 2023-11-16 11:44:34 +08:00
Fine0830
a4271bb479 feat: enhance the Dark Theme (#336) 2023-11-15 19:53:23 +08:00
Fine0830
832dc1676b feat: implement the Dark Theme (#334) 2023-11-14 20:37:15 +08:00
dependabot[bot]
780104c5d2 build(deps): bump axios from 0.24.0 to 1.6.0 (#335) 2023-11-11 17:41:00 +08:00
Fine0830
d86543aeed refactor: update Logs view (#333)
New columns of the Log View
1. Timestamp + Raw log(content) as column one, 70% of the initial table width. No separate timestamp column. The first column should be timestamp - content
2. Level tag(key=level)'s value. This could be missed from tags, if so, keep the column empty.
3. Trace link. If trace ID exists, generate a link to trace. Don't need to put the relative trace ID in the text.
4. Still keep details pop-up style.
2023-11-01 22:45:45 +08:00
Fine0830
d2eae87957 feat: add a title and a description for trace segments (#332) 2023-10-23 17:42:02 +08:00
Fine0830
d9064e8b45 fix: avoid querying data with empty parameters (#331)
* fix: Avoid querying data with empty parameters
2023-10-23 10:37:43 +08:00
peachisai
6fb4f074c1 add a netty icon (#330) 2023-10-21 22:46:17 +08:00
Xiangying Meng
f88c8a9771 feat(pulsar): add new menu for pulsar monitoring (#329) 2023-10-21 16:45:57 +08:00
dependabot[bot]
1be2792ff4 build(deps): bump @cypress/request and cypress (#327) 2023-10-19 17:41:18 +08:00
dependabot[bot]
037c2bbb11 build(deps-dev): bump @babel/traverse from 7.22.5 to 7.23.2 (#326) 2023-10-19 17:34:55 +08:00
Fine0830
70063c376f Fix tooltip style to support multiple metrics scrolling view in a metrics graph (#325) 2023-10-08 10:58:47 +08:00
zhourunjie1988
e42734ba80 fix: icons display in trace tree diagram (#324) 2023-09-26 17:20:05 +08:00
Fine0830
102436ca51 feat: add shortName for service (#323) 2023-09-20 21:16:41 +08:00
何延龙
d00fe6df9e fix: the display height of the link tree structure (#322) 2023-09-20 15:50:45 +08:00
吴晟 Wu Sheng
6872ad5bf2 Update README.md (#321) 2023-09-20 12:19:20 +08:00
Fine0830
3dc929dd53 refactor: update pagination (#320) 2023-09-20 11:57:52 +08:00
Fine0830
310fff4b28 fix: independent widget duration (#319) 2023-09-19 17:47:59 +08:00
Zhu Wang
63e97edae7 feat(kafka): add new menu for kafka monitoring (#318) 2023-09-07 14:51:51 +08:00
118 changed files with 1372 additions and 944 deletions

View File

@@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [14.x, 16.x, 18.x] node-version: [16.x, 18.x, 20.x]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node-version }}

View File

@@ -37,11 +37,11 @@ npm run dev
The default UI address is `http://localhost:8080`. The default UI address is `http://localhost:8080`.
# Contact Us # Contact Us
* Mail list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe to the mail list.
- Submit an [issue](https://github.com/apache/skywalking/issues) if you face some issues. Submit a [discussion](https://github.com/apache/skywalking/discussions) if you want to propose new feature or have any question. * Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
- Mailing list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe the mailing list. * For Chinese speaker, send `[CN] Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
- Join Slack. Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in. * Twitter, [ASFSkyWalking](https://twitter.com/AsfSkyWalking)
- QQ Group: 392443393, 901167865 * [bilibili B站 视频](https://space.bilibili.com/390683219)
# License # License

714
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,12 +18,12 @@
"check-components-types": "if (! git diff --quiet -U0 ./src/types); then echo 'type files are not updated correctly'; git diff -U0 ./src/types; exit 1; fi" "check-components-types": "if (! git diff --quiet -U0 ./src/types); then echo 'type files are not updated correctly'; git diff -U0 ./src/types; exit 1; fi"
}, },
"dependencies": { "dependencies": {
"axios": "^0.24.0", "axios": "^1.6.0",
"d3": "^7.3.0", "d3": "^7.3.0",
"d3-flame-graph": "^4.1.3", "d3-flame-graph": "^4.1.3",
"d3-tip": "^0.9.1", "d3-tip": "^0.9.1",
"echarts": "^5.2.2", "echarts": "^5.2.2",
"element-plus": "^2.1.0", "element-plus": "^2.2.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"monaco-editor": "^0.34.1", "monaco-editor": "^0.34.1",
"pinia": "^2.0.28", "pinia": "^2.0.28",
@@ -52,7 +52,7 @@
"@vue/test-utils": "^2.2.6", "@vue/test-utils": "^2.2.6",
"@vue/tsconfig": "^0.1.3", "@vue/tsconfig": "^0.1.3",
"@vueuse/core": "^9.6.0", "@vueuse/core": "^9.6.0",
"cypress": "^12.0.2", "cypress": "^13.3.2",
"eslint": "^8.22.0", "eslint": "^8.22.0",
"eslint-plugin-cypress": "^2.12.1", "eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-vue": "^9.3.0", "eslint-plugin-vue": "^9.3.0",

View File

@@ -27,10 +27,11 @@ limitations under the License. -->
} }
}, 500); }, 500);
</script> </script>
<style> <style lang="scss">
#app { #app {
color: #2c3e50; color: $font-color;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
background-color: $layout-background;
} }
</style> </style>

View File

@@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
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. -->
<svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" fill="#707070" p-id="9287"></path></svg> <svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" p-id="9287"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 259 B

View File

@@ -252,11 +252,11 @@ limitations under the License. -->
display: block; display: block;
white-space: nowrap; white-space: nowrap;
z-index: 9999999; z-index: 9999999;
box-shadow: #ddd 1px 2px 10px; box-shadow: var(--sw-topology-box-shadow);
transition: all cubic-bezier(0.075, 0.82, 0.165, 1) linear; transition: all cubic-bezier(0.075, 0.82, 0.165, 1) linear;
background-color: rgb(255 255 255); background-color: var(--sw-bg-color-overlay);
border-radius: 4px; border-radius: 4px;
color: rgb(51 51 51); color: $font-color;
padding: 5px; padding: 5px;
} }
@@ -267,7 +267,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
</style> </style>

View File

@@ -88,7 +88,7 @@ limitations under the License. -->
border: 1px solid #ddd; border: 1px solid #ddd;
background: $theme-background; background: $theme-background;
border-radius: 3px; border-radius: 3px;
color: #000; color: $font-color;
font-size: $font-size-smaller; font-size: $font-size-smaller;
height: 24px; height: 24px;
@@ -112,7 +112,7 @@ limitations under the License. -->
width: 100%; width: 100%;
padding: 2px 10px; padding: 2px 10px;
overflow: auto; overflow: auto;
color: #606266; color: var(--sw-setting-color);
position: relative; position: relative;
&:hover { &:hover {
@@ -133,7 +133,7 @@ limitations under the License. -->
} }
.opt-wrapper { .opt-wrapper {
color: #606266; color: var(--sw-setting-color);
position: absolute; position: absolute;
top: 26px; top: 26px;
left: 0; left: 0;

View File

@@ -26,3 +26,8 @@ export const Languages = [
{ label: "Chinese", value: "zh" }, { label: "Chinese", value: "zh" },
{ label: "Spanish", value: "es" }, { label: "Spanish", value: "es" },
]; ];
export enum Themes {
Dark = "dark",
Light = "light",
}

View File

@@ -24,6 +24,7 @@ export const Services = {
group group
layers layers
normal normal
shortName
} }
`, `,
}; };

View File

@@ -130,3 +130,43 @@ export const RespFields: Indexable = {
error error
}`, }`,
}; };
export const DarkChartColors = [
"#79bbff",
"#a0a7e6",
"#30A4EB",
"#45BFC0",
"#ebbf93",
"#884dde",
"#1bbf93",
"#7289ab",
"#f56c6c",
"#81feb7",
"#4094fa",
"#ff894d",
"#884dde",
"#ebbf93",
"#fedc6d",
"#da7cfa",
"#b88230",
"#a0cfff",
];
export const LightChartColors = [
"#3f96e3",
"#a0a7e6",
"#45BFC0",
"#FFCC55",
"#FF6A84",
"#c23531",
"#2f4554",
"#61a0a8",
"#d48265",
"#91c7ae",
"#749f83",
"#ca8622",
"#bda29a",
"#6e7074",
"#546570",
"#c4ccd3",
];

View File

@@ -30,6 +30,8 @@ import { useDebounceFn } from "@vueuse/core";
import { useEventListener } from "./useEventListener"; import { useEventListener } from "./useEventListener";
import { useBreakpoint } from "./useBreakpoint"; import { useBreakpoint } from "./useBreakpoint";
import echarts from "@/utils/echarts"; import echarts from "@/utils/echarts";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
export type ECOption = echarts.ComposeOption< export type ECOption = echarts.ComposeOption<
| BarSeriesOption | BarSeriesOption
@@ -44,8 +46,9 @@ export type ECOption = echarts.ComposeOption<
>; >;
export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable { export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable {
const appStore = useAppStoreWithOut();
const getDarkMode = computed(() => { const getDarkMode = computed(() => {
return theme === "default" ? "light" : theme; return appStore.theme === "default" ? Themes.Light : theme;
}); });
let chartInstance: Nullable<echarts.ECharts> = null; let chartInstance: Nullable<echarts.ECharts> = null;
let resizeFn: Fn = resize; let resizeFn: Fn = resize;
@@ -55,7 +58,7 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" |
resizeFn = useDebounceFn(resize, 200); resizeFn = useDebounceFn(resize, 200);
const getOptions = computed(() => { const getOptions = computed(() => {
if (getDarkMode.value !== "dark") { if (getDarkMode.value !== Themes.Dark) {
return cacheOptions.value as ECOption; return cacheOptions.value as ECOption;
} }
return { return {

View File

@@ -389,7 +389,10 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], instance
values: [], values: [],
}; };
} }
obj[metrics[index]].values.push({ value: resp[k].results[0].values[0].value, id: instances[idx].id }); obj[metrics[index]].values.push({
value: resp[k].results[0] && resp[k].results[0].values[0].value,
id: instances[idx].id,
});
} }
} }
} }

View File

@@ -16,6 +16,9 @@
*/ */
import type { LegendOptions } from "@/types/dashboard"; import type { LegendOptions } from "@/types/dashboard";
import { isDef } from "@/utils/is"; import { isDef } from "@/utils/is";
import { DarkChartColors, LightChartColors } from "./data";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
export default function useLegendProcess(legend?: LegendOptions) { export default function useLegendProcess(legend?: LegendOptions) {
let isRight = false; let isRight = false;
@@ -96,37 +99,11 @@ export default function useLegendProcess(legend?: LegendOptions) {
return { source, headers }; return { source, headers };
} }
function chartColors(keys: string[]) { function chartColors() {
let color: string[] = []; const appStore = useAppStoreWithOut();
switch (keys.length) { const list = appStore.theme === Themes.Dark ? DarkChartColors : LightChartColors;
case 2:
color = ["#FF6A84", "#a0b1e6"]; return list;
break;
case 1:
color = ["#3f96e3"];
break;
default:
color = [
"#30A4EB",
"#45BFC0",
"#FFCC55",
"#FF6A84",
"#a0a7e6",
"#c23531",
"#2f4554",
"#61a0a8",
"#d48265",
"#91c7ae",
"#749f83",
"#ca8622",
"#bda29a",
"#6e7074",
"#546570",
"#c4ccd3",
];
break;
}
return color;
} }
return { showEchartsLegend, isRight, aggregations, chartColors }; return { showEchartsLegend, isRight, aggregations, chartColors };
} }

View File

@@ -24,7 +24,7 @@ limitations under the License. -->
<style lang="scss" scoped> <style lang="scss" scoped>
.app-main { .app-main {
height: calc(100% - 40px); height: calc(100% - 40px);
background: #f7f9fa; background: $layout-background;
overflow: auto; overflow: auto;
} }
</style> </style>

View File

@@ -48,11 +48,14 @@ limitations under the License. -->
@input="changeTimeRange" @input="changeTimeRange"
/> />
<span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span> <span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span>
<span class="ml-5">
<el-switch v-model="theme" :active-icon="Moon" :inactive-icon="Sunny" inline-prompt @change="changeTheme" />
</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" />
</span> </span>
<span class="version ml-5 cp"> <span class="version ml-5 cp">
<el-popover trigger="hover" width="250" placement="bottom" effect="light" :content="appStore.version"> <el-popover trigger="hover" width="250" placement="bottom" :content="appStore.version">
<template #reference> <template #reference>
<span> <span>
<Icon iconName="info_outline" size="middle" /> <Icon iconName="info_outline" size="middle" />
@@ -74,7 +77,8 @@ limitations under the License. -->
import { MetricCatalog } from "@/views/dashboard/data"; import { MetricCatalog } from "@/views/dashboard/data";
import type { DashboardItem } from "@/types/dashboard"; import type { DashboardItem } from "@/types/dashboard";
import router from "@/router"; import router from "@/router";
import { ArrowRight } from "@element-plus/icons-vue"; import { ArrowRight, Moon, Sunny } from "@element-plus/icons-vue";
import { Themes } from "@/constants/data";
/*global Indexable */ /*global Indexable */
const { t, te } = useI18n(); const { t, te } = useI18n();
@@ -84,11 +88,36 @@ limitations under the License. -->
const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]); const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]);
const timeRange = ref<number>(0); const timeRange = ref<number>(0);
const pageTitle = ref<string>(""); const pageTitle = ref<string>("");
const theme = ref<boolean>(true);
const savedTheme = window.localStorage.getItem("theme-is-dark");
if (savedTheme === "false") {
theme.value = false;
} else if (savedTheme === "") {
// read the theme preference from system setting if there is no user setting
theme.value = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
}
changeTheme();
resetDuration(); resetDuration();
getVersion(); getVersion();
getNavPaths(); getNavPaths();
function changeTheme() {
const root = document.documentElement;
if (theme.value) {
root.classList.add(Themes.Dark);
root.classList.remove(Themes.Light);
appStore.setTheme(Themes.Dark);
} else {
root.classList.add(Themes.Light);
root.classList.remove(Themes.Dark);
appStore.setTheme(Themes.Light);
}
window.localStorage.setItem("theme-is-dark", String(theme.value));
}
function getName(list: any[]) { function getName(list: any[]) {
return list.find((d: any) => d.selected) || {}; return list.find((d: any) => d.selected) || {};
} }
@@ -287,21 +316,16 @@ limitations under the License. -->
padding: 5px; padding: 5px;
text-align: left; text-align: left;
justify-content: space-between; justify-content: space-between;
background-color: #fafbfc; background-color: $theme-background;
border-bottom: 1px solid #dfe4e8; border-bottom: 1px solid $border-color;
color: #222; color: $font-color;
font-size: $font-size-smaller; font-size: $font-size-smaller;
} }
.nav-bar.dark {
background-color: #333840;
border-bottom: 1px solid #252a2f;
color: #fafbfc;
}
.title { .title {
font-size: $font-size-normal; font-size: $font-size-normal;
font-weight: 500; font-weight: 500;
padding-top: 5px;
} }
.nav-tabs { .nav-tabs {

View File

@@ -165,7 +165,6 @@ const msg = {
iframeSrc: "Iframe Link", iframeSrc: "Iframe Link",
generateLink: "Generate Link", generateLink: "Generate Link",
setDuration: "Lock Query Duration", setDuration: "Lock Query Duration",
openFunction: "OpenFunction",
period: "Period", period: "Period",
windows: "Windows", windows: "Windows",
seconds: "Seconds", seconds: "Seconds",
@@ -297,7 +296,8 @@ const msg = {
return: "Return", return: "Return",
isError: "Error", isError: "Error",
contentType: "Content Type", contentType: "Content Type",
content: "Content", content: "Timestamp - Content",
level: "Level",
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`,
@@ -382,5 +382,7 @@ const msg = {
addExpressions: "Add Expressions", addExpressions: "Add Expressions",
expressions: "Expression", expressions: "Expression",
unhealthyExpression: "Unhealthy Expression", unhealthyExpression: "Unhealthy Expression",
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
}; };
export default msg; export default msg;

View File

@@ -149,7 +149,6 @@ const msg = {
iframeSrc: "Enlace Iframe", iframeSrc: "Enlace Iframe",
generateLink: "Generar enlaces", generateLink: "Generar enlaces",
setDuration: "Duración de la consulta de bloqueo", setDuration: "Duración de la consulta de bloqueo",
openFunction: "OpenFunction",
seconds: "Segundos", seconds: "Segundos",
hourTip: "Seleccione Hora", hourTip: "Seleccione Hora",
minuteTip: "Seleccione Minuto", minuteTip: "Seleccione Minuto",
@@ -297,6 +296,7 @@ const msg = {
isError: "Error", isError: "Error",
contentType: "Tipo de Contenido", contentType: "Tipo de Contenido",
content: "Contenido", content: "Contenido",
level: "Level",
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`,
@@ -382,5 +382,7 @@ const msg = {
addExpressions: "Add Expressions", addExpressions: "Add Expressions",
expressions: "Expression", expressions: "Expression",
unhealthyExpression: "Unhealthy Expression", unhealthyExpression: "Unhealthy Expression",
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
}; };
export default msg; export default msg;

View File

@@ -41,13 +41,6 @@ const titles = {
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.", service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
service_mesh_data_plane: "Data Plane", service_mesh_data_plane: "Data Plane",
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.", service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
// Functions
functions: "Functions",
functions_desc:
"FaaS (Function-as-a-Service) is a type of cloud-computing service that allows you to execute code in response to events without the complex infrastructure typically associated with building and launching microservices applications.",
functions_openfunction: "OpenFunction",
functions_openfunction_desc:
"OpenFunction as a FaaS platform, provides out-of-box observability with SkyWalking integration.",
// Kubernetes // Kubernetes
kubernetes: "Kubernetes", kubernetes: "Kubernetes",
kubernetes_desc: kubernetes_desc:
@@ -82,6 +75,8 @@ const titles = {
gateway: "Gateway", gateway: "Gateway",
gateway_desc: gateway_desc:
"API gateway is an API management tool that sits between a client and a collection of backend services.", "API gateway is an API management tool that sits between a client and a collection of backend services.",
gateway_nginx: "Nginx",
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_apisix: "APISIX", gateway_apisix: "APISIX",
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.", gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_aws_api_gateway: "AWS API Gateway", gateway_aws_api_gateway: "AWS API Gateway",
@@ -109,6 +104,10 @@ const titles = {
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.", "A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
mq_rabbitmq: "RabbitMQ", mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.", mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
mq_kafka: "Kafka",
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
mq_pulsar: "Pulsar",
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
// self observability // self observability
self_observability: "Self Observability", self_observability: "Self Observability",
self_observability_desc: self_observability_desc:

View File

@@ -41,13 +41,6 @@ const titles = {
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.", service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
service_mesh_data_plane: "Plano de Datos", service_mesh_data_plane: "Plano de Datos",
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.", service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
// Functions
functions: "Funciones",
functions_desc:
"FaaS (Function-as-a-Service) is a type of cloud-computing service that allows you to execute code in response to events without the complex infrastructure typically associated with building and launching microservices applications.",
functions_openfunction: "OpenFunction",
functions_openfunction_desc:
"OpenFunction as a FaaS platform, provides out-of-box observability with SkyWalking integration.",
// Kubernetes // Kubernetes
kubernetes: "Kubernetes", kubernetes: "Kubernetes",
kubernetes_desc: kubernetes_desc:
@@ -82,6 +75,8 @@ const titles = {
gateway: "Puerta", gateway: "Puerta",
gateway_desc: gateway_desc:
"API gateway is an API management tool that sits between a client and a collection of backend services.", "API gateway is an API management tool that sits between a client and a collection of backend services.",
gateway_nginx: "Nginx",
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_apisix: "APISIX", gateway_apisix: "APISIX",
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.", gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_aws_api_gateway: "AWS API Gateway", gateway_aws_api_gateway: "AWS API Gateway",
@@ -109,6 +104,10 @@ const titles = {
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.", "A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
mq_rabbitmq: "RabbitMQ", mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.", mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
mq_kafka: "Kafka",
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
mq_pulsar: "Pulsar",
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
// self observability // self observability
self_observability: "Self Observability", self_observability: "Self Observability",
self_observability_desc: self_observability_desc:

View File

@@ -35,12 +35,6 @@ const titles = {
service_mesh_control_plane_desc: "通过Istio的自我监控指标提供对其行为的监控。", service_mesh_control_plane_desc: "通过Istio的自我监控指标提供对其行为的监控。",
service_mesh_data_plane: "数据平面", service_mesh_data_plane: "数据平面",
service_mesh_data_plane_desc: "通过Envoy Metrics Service观察Envoy Proxy。", service_mesh_data_plane_desc: "通过Envoy Metrics Service观察Envoy Proxy。",
// Functions
functions: "Functions",
functions_desc:
"FaaS功能即服务是一种云计算服务允许您在没有通常与构建和启动微服务应用程序相关的复杂基础设施的情况下执行代码以响应事件。",
functions_openfunction: "OpenFunction",
functions_openfunction_desc: "OpenFunction作为一个FaaS平台通过SkyWalking集成提供开箱即用的可观察性。",
// Kubernetes // Kubernetes
kubernetes: "Kubernetes", kubernetes: "Kubernetes",
kubernetes_desc: "Kubernetes是一个开源的容器编排系统用于自动化软件部署、扩展和管理。", kubernetes_desc: "Kubernetes是一个开源的容器编排系统用于自动化软件部署、扩展和管理。",
@@ -72,6 +66,8 @@ const titles = {
// Gateway // Gateway
gateway: "网关", gateway: "网关",
gateway_desc: "API网关是位于客户端和后端服务集合之间的API管理工具。", gateway_desc: "API网关是位于客户端和后端服务集合之间的API管理工具。",
gateway_nginx: "Nginx",
gateway_nginx_desc: "通过OpenTelemetry的Prometheus接收器提供Nginx监控。",
gateway_apisix: "APISIX", gateway_apisix: "APISIX",
gateway_apisix_desc: "通过OpenTelemetry的Prometheus接收器提供APISIX监控。", gateway_apisix_desc: "通过OpenTelemetry的Prometheus接收器提供APISIX监控。",
gateway_aws_api_gateway: "AWS API Gateway", gateway_aws_api_gateway: "AWS API Gateway",
@@ -96,6 +92,10 @@ const titles = {
mq_desc: "消息队列是无服务器和微服务架构中使用的异步服务对服务通信的一种形式。", mq_desc: "消息队列是无服务器和微服务架构中使用的异步服务对服务通信的一种形式。",
mq_rabbitmq: "RabbitMQ", mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "通过OpenTelemetry的Prometheus接收器提供RabbitMQ监控。", mq_rabbitmq_desc: "通过OpenTelemetry的Prometheus接收器提供RabbitMQ监控。",
mq_kafka: "Kafka",
mq_Kafka_desc: "通过OpenTelemetry的Prometheus接收器提供Kafka监控。",
mq_pulsar: "Pulsar",
mq_Pulsar_desc: "通过OpenTelemetry的Prometheus接收器提供Pulsar监控。",
// self observability // self observability
self_observability: "自监控", self_observability: "自监控",
self_observability_desc: "自观察性为运行SkyWalking生态系统中的组件和服务器提供了可观察性。", self_observability_desc: "自观察性为运行SkyWalking生态系统中的组件和服务器提供了可观察性。",

View File

@@ -163,7 +163,6 @@ const msg = {
iframeSrc: "Iframe链接", iframeSrc: "Iframe链接",
generateLink: "生成链接", generateLink: "生成链接",
setDuration: "锁定查询持续时间", setDuration: "锁定查询持续时间",
openFunction: "OpenFunction",
period: "周期", period: "周期",
windows: "Windows", windows: "Windows",
seconds: "秒", seconds: "秒",
@@ -294,7 +293,8 @@ const msg = {
return: "返回", return: "返回",
isError: "错误", isError: "错误",
contentType: "内容类型", contentType: "内容类型",
content: "内容", content: "时间戳 - 内容",
level: "Level",
viewLogs: "查看日志", viewLogs: "查看日志",
logsTagsTip: "只有core/default/searchableLogsTags中定义的标记才可搜索。查看配置词汇表页面上的更多详细信息。", logsTagsTip: "只有core/default/searchableLogsTags中定义的标记才可搜索。查看配置词汇表页面上的更多详细信息。",
keywordsOfContentLogTips: "SkyWalking OAP服务器的当前存储不支持此操作", keywordsOfContentLogTips: "SkyWalking OAP服务器的当前存储不支持此操作",
@@ -380,5 +380,7 @@ const msg = {
addExpressions: "添加表达式", addExpressions: "添加表达式",
expressions: "表达式", expressions: "表达式",
unhealthyExpression: "非健康表达式", unhealthyExpression: "非健康表达式",
traceDesc:
"Trace Segment代表在单一操作系统进程例如JVM中执行的追踪部分。它包含了一组跨度spans这些跨度通常与单一请求或执行上下文关联。",
}; };
export default msg; export default msg;

View File

@@ -16,6 +16,7 @@
*/ */
import type { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
import Alarm from "@/views/Alarm.vue";
export const routesAlarm: Array<RouteRecordRaw> = [ export const routesAlarm: Array<RouteRecordRaw> = [
{ {
@@ -33,7 +34,7 @@ export const routesAlarm: Array<RouteRecordRaw> = [
{ {
path: "/alerting", path: "/alerting",
name: "Alarm", name: "Alarm",
component: () => import("@/views/Alarm.vue"), component: Alarm,
}, },
], ],
}, },

View File

@@ -16,6 +16,10 @@
*/ */
import type { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
import List from "@/views/dashboard/List.vue";
import New from "@/views/dashboard/New.vue";
import Edit from "@/views/dashboard/Edit.vue";
import Widget from "@/views/dashboard/Widget.vue";
export const routesDashboard: Array<RouteRecordRaw> = [ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
@@ -32,7 +36,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/list", path: "/dashboard/list",
component: () => import("@/views/dashboard/List.vue"), component: List,
name: "List", name: "List",
meta: { meta: {
i18nKey: "dashboardList", i18nKey: "dashboardList",
@@ -42,7 +46,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
}, },
{ {
path: "/dashboard/new", path: "/dashboard/new",
component: () => import("@/views/dashboard/New.vue"), component: New,
name: "New", name: "New",
meta: { meta: {
i18nKey: "dashboardNew", i18nKey: "dashboardNew",
@@ -54,26 +58,26 @@ export const routesDashboard: Array<RouteRecordRaw> = [
path: "", path: "",
redirect: "/dashboard/:layerId/:entity/:name", redirect: "/dashboard/:layerId/:entity/:name",
name: "Create", name: "Create",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
meta: { meta: {
notShow: true, notShow: true,
}, },
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:name", path: "/dashboard/:layerId/:entity/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "CreateChild", name: "CreateChild",
}, },
{ {
path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "CreateActiveTabIndex", name: "CreateActiveTabIndex",
}, },
], ],
}, },
{ {
path: "", path: "",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "View", name: "View",
redirect: "/dashboard/:layerId/:entity/:serviceId/:name", redirect: "/dashboard/:layerId/:entity/:serviceId/:name",
meta: { meta: {
@@ -82,12 +86,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewChild", name: "ViewChild",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewActiveTabIndex", name: "ViewActiveTabIndex",
}, },
], ],
@@ -95,7 +99,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
path: "", path: "",
redirect: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", redirect: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewServiceRelation", name: "ViewServiceRelation",
meta: { meta: {
notShow: true, notShow: true,
@@ -103,12 +107,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name", path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewServiceRelation", name: "ViewServiceRelation",
}, },
{ {
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex", path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewServiceRelationActiveTabIndex", name: "ViewServiceRelationActiveTabIndex",
}, },
], ],
@@ -116,7 +120,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
path: "", path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewPod", name: "ViewPod",
meta: { meta: {
notShow: true, notShow: true,
@@ -124,12 +128,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewPod", name: "ViewPod",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewPodActiveTabIndex", name: "ViewPodActiveTabIndex",
}, },
], ],
@@ -137,7 +141,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
path: "", path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name", redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcess", name: "ViewProcess",
meta: { meta: {
notShow: true, notShow: true,
@@ -145,12 +149,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcess", name: "ViewProcess",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcessActiveTabIndex", name: "ViewProcessActiveTabIndex",
}, },
], ],
@@ -158,7 +162,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
path: "", path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "PodRelation", name: "PodRelation",
meta: { meta: {
notShow: true, notShow: true,
@@ -166,12 +170,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewPodRelation", name: "ViewPodRelation",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewPodRelationActiveTabIndex", name: "ViewPodRelationActiveTabIndex",
}, },
], ],
@@ -180,7 +184,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
path: "", path: "",
redirect: redirect:
"/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name", "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ProcessRelation", name: "ProcessRelation",
meta: { meta: {
notShow: true, notShow: true,
@@ -188,17 +192,17 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [ children: [
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcessRelation", name: "ViewProcessRelation",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/tab/:activeTabIndex", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcessRelationActiveTabIndex", name: "ViewProcessRelationActiveTabIndex",
}, },
{ {
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/duration/:duration", path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/duration/:duration",
component: () => import("@/views/dashboard/Edit.vue"), component: Edit,
name: "ViewProcessRelationDuration", name: "ViewProcessRelationDuration",
}, },
], ],
@@ -206,14 +210,14 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{ {
path: "", path: "",
name: "Widget", name: "Widget",
component: () => import("@/views/dashboard/Widget.vue"), component: Widget,
meta: { meta: {
notShow: true, notShow: true,
}, },
children: [ children: [
{ {
path: "/page/:layer/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:config/:duration?", path: "/page/:layer/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:config/:duration?",
component: () => import("@/views/dashboard/Widget.vue"), component: Widget,
name: "ViewWidget", name: "ViewWidget",
}, },
], ],

View File

@@ -17,6 +17,7 @@
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import type { MenuOptions } from "@/types/app"; import type { MenuOptions } from "@/types/app";
import Layer from "@/views/Layer.vue";
function layerDashboards() { function layerDashboards() {
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
@@ -47,13 +48,13 @@ function layerDashboards() {
descKey: child.descKey, descKey: child.descKey,
i18nKey: child.i18nKey, i18nKey: child.i18nKey,
}, },
component: () => import("@/views/Layer.vue"), component: Layer,
}; };
route.children.push(d); route.children.push(d);
const tab = { const tab = {
name: `${child.name}ActiveTabIndex`, name: `${child.name}ActiveTabIndex`,
path: `/${child.name}/tab/:activeTabIndex`, path: `/${child.path}/tab/:activeTabIndex`,
component: () => import("@/views/Layer.vue"), component: Layer,
meta: { meta: {
notShow: true, notShow: true,
layer: child.layer, layer: child.layer,
@@ -74,7 +75,7 @@ function layerDashboards() {
descKey: item.descKey, descKey: item.descKey,
i18nKey: item.i18nKey, i18nKey: item.i18nKey,
}, },
component: () => import("@/views/Layer.vue"), component: Layer,
}, },
]; ];
} }

View File

@@ -16,6 +16,7 @@
*/ */
import type { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
import Marketplace from "@/views/Marketplace.vue";
export const routesMarketplace: Array<RouteRecordRaw> = [ export const routesMarketplace: Array<RouteRecordRaw> = [
{ {
@@ -33,7 +34,7 @@ export const routesMarketplace: Array<RouteRecordRaw> = [
{ {
path: "/marketplace", path: "/marketplace",
name: "MenusManagement", name: "MenusManagement",
component: () => import("@/views/Marketplace.vue"), component: Marketplace,
}, },
], ],
}, },

View File

@@ -16,6 +16,7 @@
*/ */
import type { RouteRecordRaw } from "vue-router"; import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue"; import Layout from "@/layout/Index.vue";
import Settings from "@/views/Settings.vue";
export const routesSettings: Array<RouteRecordRaw> = [ export const routesSettings: Array<RouteRecordRaw> = [
{ {
@@ -33,7 +34,7 @@ export const routesSettings: Array<RouteRecordRaw> = [
{ {
path: "/settings", path: "/settings",
name: "Settings", name: "Settings",
component: () => import("@/views/Settings.vue"), component: Settings,
}, },
], ],
}, },

View File

@@ -23,6 +23,7 @@ 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";
import type { MenuOptions, SubItem } from "@/types/app"; import type { MenuOptions, SubItem } from "@/types/app";
import { Themes } from "@/constants/data";
/*global Nullable*/ /*global Nullable*/
interface AppState { interface AppState {
durationRow: Recordable; durationRow: Recordable;
@@ -36,6 +37,7 @@ interface AppState {
isMobile: boolean; isMobile: boolean;
reloadTimer: Nullable<IntervalHandle>; reloadTimer: Nullable<IntervalHandle>;
allMenus: MenuOptions[]; allMenus: MenuOptions[];
theme: string;
} }
export const appStore = defineStore({ export const appStore = defineStore({
@@ -56,6 +58,7 @@ export const appStore = defineStore({
isMobile: false, isMobile: false,
reloadTimer: null, reloadTimer: null,
allMenus: [], allMenus: [],
theme: Themes.Dark,
}), }),
getters: { getters: {
duration(): Duration { duration(): Duration {
@@ -126,6 +129,9 @@ export const appStore = defineStore({
updateDurationRow(data: Duration) { updateDurationRow(data: Duration) {
this.durationRow = data; this.durationRow = data;
}, },
setTheme(data: string) {
this.theme = data;
},
setUTC(utcHour: number, utcMin: number): void { setUTC(utcHour: number, utcMin: number): void {
this.runEventStack(); this.runEventStack();
this.utcMin = utcMin; this.utcMin = utcMin;

View File

@@ -179,6 +179,7 @@ export const dashboardStore = defineStore({
newItem.graph = { newItem.graph = {
showDepth: true, showDepth: true,
}; };
newItem.metricMode = MetricModes.Expression;
} }
if (ControlsTypes.includes(type)) { if (ControlsTypes.includes(type)) {
newItem.h = 32; newItem.h = 32;

View File

@@ -163,7 +163,7 @@ export const profileStore = defineStore({
return res.data; return res.data;
}, },
async getSegmentSpans(params: { segmentId: string }) { async getSegmentSpans(params: { segmentId: string }) {
if (!params.segmentId) { if (!(params && params.segmentId)) {
return new Promise((resolve) => resolve({})); return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql.query("queryProfileSegment").params(params); const res: AxiosResponse = await graphql.query("queryProfileSegment").params(params);

View File

@@ -191,6 +191,9 @@ export const topologyStore = defineStore({
} }
}, },
async getServicesTopology(serviceIds: string[]) { async getServicesTopology(serviceIds: string[]) {
if (!serviceIds.length) {
return new Promise((resolve) => resolve({}));
}
const duration = useAppStoreWithOut().durationTime; const duration = useAppStoreWithOut().durationTime;
const res: AxiosResponse = await graphql.query("getServicesTopology").params({ const res: AxiosResponse = await graphql.query("getServicesTopology").params({
serviceIds, serviceIds,
@@ -207,7 +210,7 @@ export const topologyStore = defineStore({
const clientServiceId = (currentDestService && currentDestService.id) || ""; const clientServiceId = (currentDestService && currentDestService.id) || "";
const duration = useAppStoreWithOut().durationTime; const duration = useAppStoreWithOut().durationTime;
if (!(serverServiceId && clientServiceId)) { if (!(serverServiceId && clientServiceId)) {
return; return new Promise((resolve) => resolve({}));
} }
const res: AxiosResponse = await graphql.query("getInstanceTopology").params({ const res: AxiosResponse = await graphql.query("getInstanceTopology").params({
clientServiceId, clientServiceId,
@@ -220,6 +223,9 @@ export const topologyStore = defineStore({
return res.data; return res.data;
}, },
async updateEndpointTopology(endpointIds: string[], depth: number) { async updateEndpointTopology(endpointIds: string[], depth: number) {
if (!endpointIds.length) {
return new Promise((resolve) => resolve({}));
}
const res = await this.getEndpointTopology(endpointIds); const res = await this.getEndpointTopology(endpointIds);
if (depth > 1) { if (depth > 1) {
const ids = res.nodes.map((item: Node) => item.id).filter((d: string) => !endpointIds.includes(d)); const ids = res.nodes.map((item: Node) => item.id).filter((d: string) => !endpointIds.includes(d));
@@ -285,6 +291,9 @@ export const topologyStore = defineStore({
} }
}, },
async getEndpointTopology(endpointIds: string[]) { async getEndpointTopology(endpointIds: string[]) {
if (!endpointIds.length) {
return new Promise((resolve) => resolve({}));
}
const duration = useAppStoreWithOut().durationTime; const duration = useAppStoreWithOut().durationTime;
const variables = ["$duration: Duration!"]; const variables = ["$duration: Duration!"];
const fragment = endpointIds.map((id: string, index: number) => { const fragment = endpointIds.map((id: string, index: number) => {

View File

@@ -1,25 +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.
*/
$font-color: #3d444f;
$text-color: #fff;
$disabled-color: #ccc;
$active-color: #409eff;
$theme-background: #fff;
$active-background: #409eff;
$font-size-smaller: 12px;
$font-size-normal: 14px;

View File

@@ -123,96 +123,3 @@ code,
pre { pre {
font-family: Consolas, Menlo, Courier, monospace; font-family: Consolas, Menlo, Courier, monospace;
} }
.el-menu {
--el-menu-item-height: 50px;
}
.el-menu-item-group__title {
display: none;
}
.el-sub-menu .el-menu-item {
height: 40px;
line-height: 40px;
padding: 0 0 0 56px !important;
}
.el-sub-menu__title {
.el-icon.menu-icons {
margin-top: -5px !important;
}
}
.el-switch__label--left {
margin-right: 5px;
}
.el-switch__label--right {
margin-left: 5px;
}
.el-switch__label * {
font-size: $font-size-smaller;
}
.el-drawer__header {
margin-bottom: 0;
padding-left: 10px;
font-size: 16px;
}
.el-drawer__body {
padding: 0;
}
.switch {
margin: 0 5px;
}
div.vis-tooltip {
max-width: 600px;
overflow: hidden;
background-color: $theme-background !important;
white-space: normal !important;
font-size: $font-size-smaller !important;
}
.vis-item {
cursor: pointer;
height: 20px;
}
.vis-item.Error {
background-color: #e66;
opacity: 0.8;
border-color: #e66;
color: $text-color !important;
}
.vis-item.Normal {
background-color: #fac858;
border-color: #fac858;
color: #666 !important;
}
.vis-item .vis-item-content {
padding: 0 3px !important;
}
.vis-item.vis-selected.Error,
.vis-item.vis-selected.Normal {
color: #1a1a1a !important;
}
.el-menu--vertical.sub-list {
display: none;
}
div:has(> a.menu-title) {
display: none;
}
.el-input-number .el-input__inner {
text-align: left !important;
}

252
src/styles/theme.scss Normal file
View File

@@ -0,0 +1,252 @@
/**
* 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.
*/
@use "element-plus/theme-chalk/src/dark/css-vars.scss" as *;
:root {
--sw-green: #70c877;
--sw-orange: #e6a23c;
}
html {
--el-color-primary: #409eff;
--theme-background: #fff;
--font-color: #3d444f;
--disabled-color: #ccc;
--dashboard-tool-bg: rgb(240 242 245);
--text-color-placeholder: #666;
--border-color: #dcdfe6;
--border-color-primary: #eee;
--layout-background: #f7f9fa;
--box-shadow-color: #ccc;
--sw-bg-color-overlay: #fff;
--sw-border-color-light: #e4e7ed;
--popper-hover-bg: #eee;
--sw-icon-btn-bg: #eee;
--sw-icon-btn-color: #666;
--sw-icon-btn-border: #ccc;
--sw-table-col: #fff;
--sw-config-header: aliceblue;
--sw-topology-color: #666;
--vis-tooltip-bg: #fff;
--sw-topology-switch-icon: rgba(0, 0, 0, 0.3);
--sw-topology-box-shadow: #eee 1px 2px 10px;
--sw-topology-setting-bg: #fff;
--sw-topology-border: 1px solid #999;
--sw-trace-success: rgb(46 47 51 / 10%);
--sw-trace-list-border: rgb(0 0 0 / 10%);
--sw-list-selected: #ededed;
--sw-table-header: #f3f4f9;
--sw-list-hover: rgb(0 0 0 / 4%);
--sw-setting-color: #606266;
--sw-alarm-tool: #f0f2f5;
--sw-alarm-tool-border: #c1c5ca41;
--sw-table-color: #000;
--sw-event-vis-selected: #1a1a1a;
--sw-time-axis-text: #4d4d4d;
--sw-drawer-header: #72767b;
--sw-marketplace-border: #dedfe0;
--sw-grid-item-active: #79bbff;
}
html.dark {
--el-color-primary: #409eff;
--theme-background: #212224;
--font-color: #fafbfc;
--disabled-color: #ccc;
--dashboard-tool-bg: #000;
--text-color-placeholder: #ccc;
--border-color: #262629;
--border-color-primary: #4b4b52;
--layout-background: #000;
--box-shadow-color: #606266;
--sw-bg-color-overlay: #1d1e1f;
--sw-border-color-light: #414243;
--popper-hover-bg: rgb(64, 158, 255, 0.1);
--sw-icon-btn-bg: #222;
--sw-icon-btn-color: #ccc;
--sw-icon-btn-border: #999;
--sw-table-col: none;
--sw-config-header: #303133;
--sw-topology-color: #ccc;
--vis-tooltip-bg: #414243;
--sw-topology-switch-icon: #aaa;
--sw-topology-box-shadow: 0 0 2px 0 #444;
--sw-topology-setting-bg: #333;
--sw-topology-border: 1px solid #666;
--sw-trace-success: #aaa;
--sw-trace-list-border: #333133;
--sw-list-hover: #262629;
--sw-table-header: #303133;
--sw-list-selected: #3d444f;
--sw-setting-color: #eee;
--sw-alarm-tool: #303133;
--sw-alarm-tool-border: #444;
--sw-table-color: #fff;
--sw-event-vis-selected: #fff;
--sw-time-axis-text: #aaa;
--sw-drawer-header: #e9e9eb;
--sw-marketplace-border: #606266;
--sw-grid-item-active: #73767a;
}
.el-drawer__header {
color: var(--sw-drawer-header);
}
.el-table tr {
background-color: var(--el-table-tr-bg-color);
}
.el-popper.is-light {
background: var(--sw-bg-color-overlay);
border: 1px solid var(--sw-border-color-light);
}
.el-switch {
--el-switch-off-color: #aaa;
}
.el-table__body-wrapper tr td.el-table-fixed-column--left,
.el-table__body-wrapper tr td.el-table-fixed-column--right,
.el-table__body-wrapper tr th.el-table-fixed-column--left,
.el-table__body-wrapper tr th.el-table-fixed-column--right,
.el-table__footer-wrapper tr td.el-table-fixed-column--left,
.el-table__footer-wrapper tr td.el-table-fixed-column--right,
.el-table__footer-wrapper tr th.el-table-fixed-column--left,
.el-table__footer-wrapper tr th.el-table-fixed-column--right,
.el-table__header-wrapper tr td.el-table-fixed-column--left,
.el-table__header-wrapper tr td.el-table-fixed-column--right,
.el-table__header-wrapper tr th.el-table-fixed-column--left,
.el-table__header-wrapper tr th.el-table-fixed-column--right {
background-color: var(--sw-table-col);
}
.el-table.is-scrolling-none th.el-table-fixed-column--left,
.el-table.is-scrolling-none th.el-table-fixed-column--right,
.el-table th.el-table__cell {
background-color: var(--sw-table-col);
}
$tool-icon-btn-bg: var(--sw-icon-btn-bg);
$tool-icon-btn-color: var(--sw-icon-btn-color);
$popper-hover-bg-color: var(--popper-hover-bg);
$box-shadow-color: var(--box-shadow-color);
$border-color-primary: var(--border-color-primary);
$layout-background: var(--layout-background);
$border-color: var(--border-color);
$dashboard-tool-bg-color: var(--dashboard-tool-bg);
$font-color: var(--font-color);
$text-color: var(--theme-background);
$disabled-color: var(--disabled-color);
$active-color: var(--el-color-primary);
$theme-background: var(--theme-background);
$active-background: var(--el-color-primary);
$font-size-smaller: 12px;
$font-size-normal: 14px;
.opt:hover {
background-color: var(--sw-list-hover) !important;
}
.el-loading-mask {
background-color: var(--theme-background);
}
.el-menu {
--el-menu-item-height: 50px;
}
.el-menu-item-group__title {
display: none;
}
.el-sub-menu .el-menu-item {
height: 40px;
line-height: 40px;
padding: 0 0 0 56px !important;
}
.el-sub-menu__title {
.el-icon.menu-icons {
margin-top: -5px !important;
}
}
.el-drawer__header {
margin-bottom: 0;
padding-left: 10px;
font-size: 16px;
}
.el-drawer__body {
padding: 0;
}
.switch {
margin: 0 5px;
}
div.vis-tooltip {
max-width: 600px;
overflow: hidden;
background-color: var(--vis-tooltip-bg) !important;
white-space: normal !important;
font-size: $font-size-smaller !important;
color: var(--font-color) !important;
}
.vis-item {
cursor: pointer;
height: 20px;
}
.vis-item.Error {
background-color: #e66;
opacity: 0.8;
border-color: #e66;
color: var(--sw-event-vis-selected) !important;
}
.vis-item.Normal {
background-color: #fac858;
border-color: #fac858;
color: var(--sw-event-vis-selected) !important;
}
.vis-item .vis-item-content {
padding: 0 3px !important;
}
.vis-item.vis-selected.Error,
.vis-item.vis-selected.Normal {
color: var(--sw-event-vis-selected) !important;
}
.vis-time-axis .vis-text {
color: var(--sw-time-axis-text) !important;
}
.el-menu--vertical.sub-list {
display: none;
}
div:has(> a.menu-title) {
display: none;
}
.el-input-number .el-input__inner {
text-align: left !important;
}

View File

@@ -22,6 +22,7 @@ export type Service = {
normal?: boolean; normal?: boolean;
group?: string; group?: string;
merge?: string; merge?: string;
shortName?: string;
}; };
export type Instance = { export type Instance = {

View File

@@ -113,7 +113,7 @@ limitations under the License. -->
.category { .category {
flex-wrap: wrap; flex-wrap: wrap;
border-right: 1px solid #ddd; border-right: 1px solid var(--sw-marketplace-border);
align-content: flex-start; align-content: flex-start;
height: 100%; height: 100%;
overflow: auto; overflow: auto;

View File

@@ -156,7 +156,7 @@ limitations under the License. -->
} }
.settings { .settings {
color: #606266; color: var(--sw-setting-color);
font-size: 13px; font-size: 13px;
padding: 20px; padding: 20px;
@@ -177,7 +177,7 @@ limitations under the License. -->
width: 180px; width: 180px;
display: inline-block; display: inline-block;
font-weight: 500; font-weight: 500;
color: #000; color: $font-color;
line-height: 25px; line-height: 25px;
} }
} }

View File

@@ -157,7 +157,7 @@ limitations under the License. -->
.timeline-table-i { .timeline-table-i {
padding: 10px 15px; padding: 10px 15px;
border-left: 4px solid #eee; border-left: 4px solid var(--border-color-primary);
position: relative; position: relative;
&::after { &::after {

View File

@@ -39,7 +39,11 @@ limitations under the License. -->
@current-change="changePage" @current-change="changePage"
:pager-count="5" :pager-count="5"
small small
:style="`--el-pagination-bg-color: #f0f2f5; --el-pagination-button-disabled-bg-color: #f0f2f5;`" :style="
appStore.theme === Themes.Light
? `--el-pagination-bg-color: #f0f2f5; --el-pagination-button-disabled-bg-color: #f0f2f5;`
: ''
"
/> />
</div> </div>
</div> </div>
@@ -54,6 +58,7 @@ limitations under the License. -->
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useAlarmStore } from "@/store/modules/alarm"; import { useAlarmStore } from "@/store/modules/alarm";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { Themes } from "@/constants/data";
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const alarmStore = useAlarmStore(); const alarmStore = useAlarmStore();
@@ -99,8 +104,8 @@ limitations under the License. -->
<style lang="scss" scoped> <style lang="scss" scoped>
.alarm-tool { .alarm-tool {
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #c1c5ca41; border-bottom: 1px solid var(--sw-alarm-tool-border);
background-color: #f0f2f5; background-color: var(--sw-alarm-tool);
padding: 10px; padding: 10px;
position: relative; position: relative;
} }

View File

@@ -116,8 +116,6 @@ limitations under the License. -->
</el-button> </el-button>
<el-pagination <el-pagination
class="pagination" class="pagination"
background
small
layout="prev, pager, next" layout="prev, pager, next"
:page-size="pageSize" :page-size="pageSize"
:total="total" :total="total"

View File

@@ -87,10 +87,12 @@ limitations under the License. -->
dashboardStore.setLayer(route.params.layer); dashboardStore.setLayer(route.params.layer);
dashboardStore.setEntity(route.params.entity); dashboardStore.setEntity(route.params.entity);
const { auto, autoPeriod } = config.value; const { auto, autoPeriod } = config.value;
if (auto) { if (auto) {
await setDuration(); await setDuration();
appStoreWithOut.setReloadTimer(setInterval(setDuration, autoPeriod * 1000)); appStoreWithOut.setReloadTimer(setInterval(setDuration, autoPeriod * 1000));
} else {
const duration = JSON.parse(route.params.duration as string);
appStoreWithOut.setDuration(duration);
} }
await setSelector(); await setSelector();
await queryMetrics(); await queryMetrics();
@@ -184,7 +186,7 @@ limitations under the License. -->
<style lang="scss" scoped> <style lang="scss" scoped>
.content { .content {
min-width: 100px; min-width: 100px;
border: 1px solid #eee; border: 1px solid $border-color-primary;
background-color: $theme-background; background-color: $theme-background;
position: relative; position: relative;
} }

View File

@@ -20,14 +20,9 @@ limitations under the License. -->
</div> </div>
<div v-if="hasDuration"> <div v-if="hasDuration">
<label>{{ t("duration") }}</label> <label>{{ t("duration") }}</label>
<TimePicker <TimePicker :value="duration" position="right" format="YYYY-MM-DD HH:mm" @input="changeTimeRange" />
:value="[appStore.durationRow.start, appStore.durationRow.end]"
position="right"
format="YYYY-MM-DD HH:mm"
@input="changeTimeRange"
/>
</div> </div>
<div v-if="!hasDuration"> <div v-else>
<label>{{ t("auto") }}</label> <label>{{ t("auto") }}</label>
<el-switch class="mr-5" v-model="auto" style="height: 25px" /> <el-switch class="mr-5" v-model="auto" style="height: 25px" />
<Selector v-model="freshOpt" :options="RefreshOptions" size="small" /> <Selector v-model="freshOpt" :options="RefreshOptions" size="small" />
@@ -72,6 +67,7 @@ limitations under the License. -->
const auto = ref<boolean>(true); const auto = ref<boolean>(true);
const period = ref<number>(6); const period = ref<number>(6);
const freshOpt = ref<string>(RefreshOptions[0].value); const freshOpt = ref<string>(RefreshOptions[0].value);
const duration = ref<string>(JSON.parse(JSON.stringify([appStore.durationRow.start, appStore.durationRow.end])));
function changeTimeRange(val: Date[] | any) { function changeTimeRange(val: Date[] | any) {
dates.value = val; dates.value = val;
@@ -127,7 +123,10 @@ limitations under the License. -->
tips: encodeURIComponent(widget.tips || ""), tips: encodeURIComponent(widget.tips || ""),
}; };
} }
if (auto.value) { if (hasDuration.value) {
opt.auto = 0;
opt.autoPeriod = 0;
} else {
const f = RefreshOptions.filter((d: { value: string }) => d.value === freshOpt.value)[0] || {}; const f = RefreshOptions.filter((d: { value: string }) => d.value === freshOpt.value)[0] || {};
opt.auto = Number(f.value) * 60 * 1000; opt.auto = Number(f.value) * 60 * 1000;
opt.autoPeriod = period.value; opt.autoPeriod = period.value;

View File

@@ -91,7 +91,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -68,7 +68,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -89,6 +89,7 @@ limitations under the License. -->
const fontSize = ref<number>(graph.fontSize || 12); const fontSize = ref<number>(graph.fontSize || 12);
const textAlign = ref(graph.textAlign || "left"); const textAlign = ref(graph.textAlign || "left");
const Colors = [ const Colors = [
{ label: "Theme", value: "theme" },
{ {
label: "Green", label: "Green",
value: "green", value: "green",
@@ -151,7 +152,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -80,7 +80,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -147,7 +147,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -63,7 +63,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -201,7 +201,7 @@ limitations under the License. -->
.graph { .graph {
position: relative; position: relative;
min-width: 1280px; min-width: 1280px;
border: 1px solid #eee; border: 1px solid $border-color-primary;
background-color: $theme-background; background-color: $theme-background;
} }
@@ -209,7 +209,7 @@ limitations under the License. -->
height: 25px; height: 25px;
line-height: 25px; line-height: 25px;
text-align: center; text-align: center;
background-color: aliceblue; background-color: var(--sw-config-header);
font-size: $font-size-smaller; font-size: $font-size-smaller;
position: relative; position: relative;
} }
@@ -249,7 +249,7 @@ limitations under the License. -->
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
border-top: 1px solid #eee; border-top: 1px solid $border-color-primary;
padding: 10px; padding: 10px;
text-align: right; text-align: right;
width: 100%; width: 100%;

View File

@@ -630,11 +630,10 @@ limitations under the License. -->
.expression-param { .expression-param {
display: inline-block; display: inline-block;
width: 400px; width: 400px;
border: 1px solid #dcdfe6; border: 1px solid $border-color;
cursor: text; cursor: text;
padding: 0 5px; padding: 0 5px;
border-radius: 3px; border-radius: 3px;
color: #606266;
outline: none; outline: none;
margin-right: 5px; margin-right: 5px;
min-height: 26px; min-height: 26px;

View File

@@ -75,7 +75,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.tools { .tools {
@@ -87,7 +87,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
@@ -95,6 +95,6 @@ limitations under the License. -->
font-weight: bold; font-weight: bold;
line-height: 40px; line-height: 40px;
padding: 0 10px; padding: 0 10px;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
</style> </style>

View File

@@ -69,7 +69,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
min-width: 1024px; min-width: 1024px;
} }
@@ -82,7 +82,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
</style> </style>

View File

@@ -68,7 +68,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.tools { .tools {
@@ -80,7 +80,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -80,7 +80,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
min-width: 1024px; min-width: 1024px;
} }
@@ -93,7 +93,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -77,7 +77,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
min-width: 1024px; min-width: 1024px;
} }
@@ -90,7 +90,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -67,7 +67,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.tools { .tools {
@@ -79,7 +79,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
@@ -87,6 +87,6 @@ limitations under the License. -->
font-weight: bold; font-weight: bold;
line-height: 40px; line-height: 40px;
padding: 0 10px; padding: 0 10px;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
</style> </style>

View File

@@ -68,7 +68,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.tools { .tools {
@@ -80,7 +80,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -282,7 +282,7 @@ limitations under the License. -->
<style lang="scss" scoped> <style lang="scss" scoped>
.tabs { .tabs {
height: 40px; height: 40px;
color: $disabled-color; color: var(--sw-icon-btn-color);
width: 100%; width: 100%;
overflow-x: auto; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
@@ -302,16 +302,15 @@ limitations under the License. -->
height: 20px; height: 20px;
line-height: 20px; line-height: 20px;
outline: none; outline: none;
color: #333; color: $font-color;
font-style: normal; font-style: normal;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
margin-right: 20px; margin-right: 20px;
background-color: $theme-background;
} }
.tab-icons { .tab-icons {
color: #333;
i { i {
margin-right: 3px; margin-right: 3px;
} }
@@ -350,17 +349,17 @@ limitations under the License. -->
.tab-header { .tab-header {
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
border-bottom: 1px solid #eee; border-bottom: 1px solid $border-color-primary;
} }
.vue-grid-layout { .vue-grid-layout {
background: #f7f9fa; background: $layout-background;
height: auto !important; height: auto !important;
} }
.vue-grid-item:not(.vue-grid-placeholder) { .vue-grid-item:not(.vue-grid-placeholder) {
background: $theme-background; background: $theme-background;
box-shadow: 0 1px 4px 0 #00000029; box-shadow: 0 0 3px 0 $box-shadow-color;
border-radius: 3px; border-radius: 3px;
} }
@@ -370,11 +369,11 @@ limitations under the License. -->
} }
.tab-icon { .tab-icon {
color: #666; color: var(--sw-icon-btn-color);
} }
.vue-grid-item.active { .vue-grid-item.active {
border: 1px solid $active-color; border: 1px solid var(--sw-grid-item-active);
} }
.no-data-tips { .no-data-tips {

View File

@@ -67,7 +67,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.tools { .tools {
@@ -79,7 +79,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
@@ -87,6 +87,6 @@ limitations under the License. -->
font-weight: bold; font-weight: bold;
line-height: 40px; line-height: 40px;
padding: 0 10px; padding: 0 10px;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
</style> </style>

View File

@@ -32,7 +32,7 @@ limitations under the License. -->
<div <div
class="body" class="body"
:style="{ :style="{
backgroundColor: TextColors[graph.backgroundColor], backgroundColor,
justifyContent: graph.textAlign, justifyContent: graph.textAlign,
}" }"
> >
@@ -40,8 +40,9 @@ limitations under the License. -->
:href="graph.url" :href="graph.url"
target="_blank" target="_blank"
:style="{ :style="{
color: TextColors[graph.fontColor], color: fontColor,
fontSize: graph.fontSize + 'px', fontSize: graph.fontSize + 'px',
textDecoration: 'underline',
}" }"
> >
{{ graph.content }} {{ graph.content }}
@@ -55,6 +56,8 @@ limitations under the License. -->
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { TextColors } from "@/views/dashboard/data"; import { TextColors } from "@/views/dashboard/data";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
/*global defineProps */ /*global defineProps */
const props = defineProps({ const props = defineProps({
@@ -65,9 +68,17 @@ limitations under the License. -->
activeIndex: { type: String, default: "" }, activeIndex: { type: String, default: "" },
}); });
const { t } = useI18n(); const { t } = useI18n();
const appStore = useAppStoreWithOut();
const graph = computed(() => props.data.graph || {}); const graph = computed(() => props.data.graph || {});
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const backgroundColor = computed(
() => TextColors[graph.value.backgroundColor] || (appStore.theme === Themes.Dark ? "#212224" : "#fff"),
);
const fontColor = computed(
() => TextColors[graph.value.fontColor] || (appStore.theme === Themes.Dark ? "#fafbfc" : "#3d444f"),
);
function removeTopo() { function removeTopo() {
dashboardStore.removeControls(props.data); dashboardStore.removeControls(props.data);
} }
@@ -112,7 +123,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
</style> </style>

View File

@@ -103,7 +103,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -176,7 +176,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
</style> </style>

View File

@@ -59,7 +59,6 @@ limitations under the License. -->
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.topology { .topology {
// background-color: #333840;
width: 100%; width: 100%;
height: 100%; height: 100%;
font-size: $font-size-smaller; font-size: $font-size-smaller;
@@ -82,7 +81,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -76,7 +76,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
min-width: 1200px; min-width: 1200px;
} }
@@ -89,11 +89,12 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
.trace { .trace {
min-height: calc(100% - 150px);
width: 100%; width: 100%;
overflow: auto; overflow: auto;
min-width: 1200px; min-width: 1200px;

View File

@@ -277,7 +277,7 @@ limitations under the License. -->
height: 30px; height: 30px;
padding: 5px; padding: 5px;
width: 100%; width: 100%;
border-bottom: 1px solid #eee; border-bottom: 1px solid $border-color-primary;
justify-content: space-between; justify-content: space-between;
} }
@@ -294,7 +294,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }

View File

@@ -306,9 +306,9 @@ export const TextColors: { [key: string]: string } = {
green: "#67C23A", green: "#67C23A",
blue: "#409EFF", blue: "#409EFF",
red: "#F56C6C", red: "#F56C6C",
grey: "#909399", grey: "#809399",
white: "#fff", white: "#fff",
black: "#000", black: "#303133",
orange: "#E6A23C", orange: "#E6A23C",
purple: "#bf99f8", purple: "#bf99f8",
}; };
@@ -345,3 +345,7 @@ export enum MetricModes {
Expression = "Expression", Expression = "Expression",
General = "General", General = "General",
} }
export enum CallTypes {
Server = "SERVER",
Client = "CLIENT",
}

View File

@@ -24,6 +24,8 @@ limitations under the License. -->
import type { BarConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard"; import type { BarConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard";
import useLegendProcess from "@/hooks/useLegendProcessor"; import useLegendProcess from "@/hooks/useLegendProcessor";
import Legend from "./components/Legend.vue"; import Legend from "./components/Legend.vue";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
/*global defineProps, defineEmits */ /*global defineProps, defineEmits */
const emits = defineEmits(["click"]); const emits = defineEmits(["click"]);
@@ -46,6 +48,7 @@ limitations under the License. -->
default: () => ({}), default: () => ({}),
}, },
}); });
const appStore = useAppStoreWithOut();
const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend); const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend);
const option = computed(() => getOption()); const option = computed(() => getOption());
@@ -71,7 +74,7 @@ limitations under the License. -->
}, },
}; };
}); });
const color: string[] = chartColors(keys); const color: string[] = chartColors();
return { return {
color, color,
tooltip: { tooltip: {
@@ -82,7 +85,7 @@ limitations under the License. -->
}, },
enterable: true, enterable: true,
confine: true, confine: true,
extraCssText: "max-height: 300px; overflow: auto; border: none;", extraCssText: "max-height:85%; overflow: auto;",
}, },
legend: { legend: {
type: "scroll", type: "scroll",
@@ -91,8 +94,11 @@ limitations under the License. -->
top: 0, top: 0,
left: 0, left: 0,
itemWidth: 12, itemWidth: 12,
backgroundColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
borderColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
textStyle: { textStyle: {
color: "#333", fontSize: 12,
color: appStore.theme === Themes.Dark ? "#eee" : "#333",
}, },
}, },
grid: { grid: {

View File

@@ -61,7 +61,7 @@ limitations under the License. -->
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.chart-card { .chart-card {
color: #333; color: $font-color;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;

View File

@@ -66,9 +66,7 @@ limitations under the License. -->
</el-table> </el-table>
</div> </div>
<el-pagination <el-pagination
class="pagination" class="pagination flex-h"
background
small
layout="prev, pager, next" layout="prev, pager, next"
:page-size="pageSize" :page-size="pageSize"
:total="pods.length" :total="pods.length"

View File

@@ -31,6 +31,8 @@ limitations under the License. -->
import Legend from "./components/Legend.vue"; import Legend from "./components/Legend.vue";
import useLegendProcess from "@/hooks/useLegendProcessor"; import useLegendProcess from "@/hooks/useLegendProcessor";
import { isDef } from "@/utils/is"; import { isDef } from "@/utils/is";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
/*global defineProps, defineEmits */ /*global defineProps, defineEmits */
const emits = defineEmits(["click"]); const emits = defineEmits(["click"]);
@@ -40,7 +42,6 @@ limitations under the License. -->
default: () => ({}), default: () => ({}),
}, },
intervalTime: { type: Array as PropType<string[]>, default: () => [] }, intervalTime: { type: Array as PropType<string[]>, default: () => [] },
theme: { type: String, default: "light" },
config: { config: {
type: Object as PropType< type: Object as PropType<
LineConfig & { LineConfig & {
@@ -62,6 +63,7 @@ limitations under the License. -->
}), }),
}, },
}); });
const appStore = useAppStoreWithOut();
const setRight = ref<boolean>(false); const setRight = ref<boolean>(false);
const option = computed(() => getOption()); const option = computed(() => getOption());
function getOption() { function getOption() {
@@ -90,16 +92,18 @@ limitations under the License. -->
} }
return serie; return serie;
}); });
const color: string[] = chartColors(keys); const color: string[] = chartColors();
const tooltip = { const tooltip = {
trigger: "axis", trigger: "axis",
backgroundColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
borderColor: appStore.theme === Themes.Dark ? "#333" : "#fff",
textStyle: { textStyle: {
fontSize: 12, fontSize: 12,
color: "#333", color: appStore.theme === Themes.Dark ? "#eee" : "#333",
}, },
enterable: true, enterable: true,
confine: true, confine: true,
extraCssText: "max-height: 300px; overflow: auto; border: none;", extraCssText: "max-height:85%; overflow: auto;",
}; };
const tips = { const tips = {
formatter(params: any) { formatter(params: any) {
@@ -108,9 +112,11 @@ limitations under the License. -->
confine: true, confine: true,
extraCssText: `height: 20px; padding:0 2px;`, extraCssText: `height: 20px; padding:0 2px;`,
trigger: "axis", trigger: "axis",
backgroundColor: appStore.theme === Themes.Dark ? "#666" : "#eee",
borderColor: appStore.theme === Themes.Dark ? "#666" : "#eee",
textStyle: { textStyle: {
fontSize: 12, fontSize: 12,
color: "#333", color: appStore.theme === Themes.Dark ? "#eee" : "#333",
}, },
}; };
@@ -125,7 +131,7 @@ limitations under the License. -->
left: 0, left: 0,
itemWidth: 12, itemWidth: 12,
textStyle: { textStyle: {
color: props.theme === "dark" ? "#fff" : "#333", color: appStore.theme === Themes.Dark ? "#fff" : "#333",
}, },
}, },
grid: { grid: {

View File

@@ -40,7 +40,7 @@ limitations under the License. -->
<el-table-column fixed label="Service Names" min-width="220"> <el-table-column fixed label="Service Names" min-width="220">
<template #default="scope"> <template #default="scope">
<span class="link" :style="{ fontSize: `${config.fontSize}px` }" @click="clickService(scope)"> <span class="link" :style="{ fontSize: `${config.fontSize}px` }" @click="clickService(scope)">
{{ scope.row.label }} {{ scope.row.shortName }}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
@@ -59,9 +59,7 @@ limitations under the License. -->
</el-table> </el-table>
</div> </div>
<el-pagination <el-pagination
class="pagination" class="pagination flex-h"
background
small
layout="prev, pager, next" layout="prev, pager, next"
:page-size="pageSize" :page-size="pageSize"
:total="selectorStore.services.length" :total="selectorStore.services.length"
@@ -210,6 +208,7 @@ limitations under the License. -->
group: d.group, group: d.group,
normal: d.normal, normal: d.normal,
merge: d.merge, merge: d.merge,
shortName: d.shortName,
}; };
}); });
if (props.config.metricMode === MetricModes.Expression) { if (props.config.metricMode === MetricModes.Expression) {

View File

@@ -106,12 +106,12 @@ limitations under the License. -->
.row:first-child { .row:first-child {
div { div {
border-top: 1px solid $disabled-color; border-top: 1px solid $disabled-color;
background: #eee; background-color: var(--border-color-primary);
} }
} }
.header { .header {
color: #000; color: var(--sw-table-color);
font-weight: bold; font-weight: bold;
} }

View File

@@ -141,7 +141,7 @@ limitations under the License. -->
.progress-bar { .progress-bar {
font-size: $font-size-smaller; font-size: $font-size-smaller;
color: #333; color: $font-color;
} }
.chart-slow-i { .chart-slow-i {
@@ -171,7 +171,7 @@ limitations under the License. -->
padding: 4px 10px 7px; padding: 4px 10px 7px;
border-radius: 4px; border-radius: 4px;
border: 1px solid #ddd; border: 1px solid #ddd;
color: #333; color: $font-color;
background-color: $theme-background; background-color: $theme-background;
will-change: opacity, background-color; will-change: opacity, background-color;
transition: opacity 0.3s, background-color 0.3s; transition: opacity 0.3s, background-color 0.3s;
@@ -188,12 +188,12 @@ limitations under the License. -->
} }
.operation-icon { .operation-icon {
color: #333; color: $font-color;
} }
.operation { .operation {
padding: 5px 0; padding: 5px 0;
color: #333; color: $font-color;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
text-align: center; text-align: center;
@@ -201,7 +201,7 @@ limitations under the License. -->
&:hover { &:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
</style> </style>

View File

@@ -111,9 +111,8 @@ limitations under the License. -->
const isRight = computed(() => useLegendProcess(props.config).isRight); const isRight = computed(() => useLegendProcess(props.config).isRight);
const width = computed(() => (props.config.width ? props.config.width + "px" : isRight.value ? "150px" : "100%")); const width = computed(() => (props.config.width ? props.config.width + "px" : isRight.value ? "150px" : "100%"));
const colors = computed(() => { const colors = computed(() => {
const keys = Object.keys(props.data || {}).filter((i: any) => Array.isArray(props.data[i]) && props.data[i].length);
const { chartColors } = useLegendProcess(props.config); const { chartColors } = useLegendProcess(props.config);
return chartColors(keys); return chartColors();
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -23,7 +23,6 @@
.list { .list {
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
height: calc(100% - 90px);
} }
.pagination { .pagination {
@@ -31,6 +30,7 @@
text-align: center; text-align: center;
height: 30px; height: 30px;
padding: 8px 0; padding: 8px 0;
justify-content: flex-end;
} }
.link { .link {

View File

@@ -80,18 +80,18 @@ limitations under the License. -->
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.vue-grid-layout { .vue-grid-layout {
background: #f7f9fa; background: $layout-background;
height: auto !important; height: auto !important;
} }
.vue-grid-item:not(.vue-grid-placeholder) { .vue-grid-item:not(.vue-grid-placeholder) {
background-color: $theme-background; background-color: $theme-background;
box-shadow: 0 1px 4px 0 #00000029; box-shadow: 0 0 3px 0 $box-shadow-color;
border-radius: 3px; border-radius: 3px;
} }
.vue-grid-item.active { .vue-grid-item.active {
border: 1px solid $active-color; border: 1px solid var(--sw-grid-item-active);
} }
.no-data-tips { .no-data-tips {

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="dashboard-tool flex-h"> <div class="dashboard-tool flex-h">
<div :class="isRelation ? 'flex-v' : 'flex-h'"> <div :class="isRelation ? 'flex-v' : 'flex-h'" class="tool-selectors">
<div class="flex-h"> <div class="flex-h">
<div class="selectors-item" v-if="key !== 10"> <div class="selectors-item" v-if="key !== 10">
<span class="label">$Service</span> <span class="label">$Service</span>
@@ -103,27 +103,24 @@ limitations under the License. -->
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="clickIcons(t)" v-for="(t, index) in toolIcons" :key="index" :title="t.content"> <el-dropdown-item @click="clickIcons(t)" v-for="(t, index) in toolIcons" :key="index" :title="t.content">
<Icon class="mr-5" size="middle" :iconName="t.name" /> <Icon class="mr-5" size="sm" :iconName="t.name" />
<span>{{ t.content }}</span> <span>{{ t.content }}</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<el-tooltip content="Apply" placement="bottom" effect="light"> <el-tooltip content="Apply" placement="bottom">
<i @click="applyDashboard"> <i @click="applyDashboard">
<Icon class="icon-btn" size="sm" iconName="save" /> <Icon class="icon-btn" size="sm" iconName="save" />
</i> </i>
</el-tooltip> </el-tooltip>
</div> </div>
<div class="switch"> <div class="ml-5">
<el-switch <el-switch
v-model="dashboardStore.editMode" v-model="dashboardStore.editMode"
active-text="E" active-text="E"
inactive-text="V" inactive-text="V"
size="small"
inline-prompt inline-prompt
active-color="#409eff"
inactive-color="#999"
@change="changeMode" @change="changeMode"
/> />
</div> </div>
@@ -738,15 +735,15 @@ limitations under the License. -->
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-tool { .dashboard-tool {
text-align: right; text-align: right;
padding: 3px 5px 5px; padding: 5px;
background: rgb(240 242 245); background: $dashboard-tool-bg-color;
border-bottom: 1px solid #dfe4e8; border-bottom: 1px solid $border-color;
justify-content: space-between; justify-content: space-between;
} }
.switch { .tool-selectors {
padding-top: 2px; align-items: center;
margin: 0 10px; height: auto;
} }
.label { .label {
@@ -761,6 +758,7 @@ limitations under the License. -->
.tools { .tools {
justify-content: space-between; justify-content: space-between;
align-items: center;
height: auto; height: auto;
} }
@@ -768,12 +766,12 @@ limitations under the License. -->
display: inline-block; display: inline-block;
padding: 3px; padding: 3px;
text-align: center; text-align: center;
border: 1px solid $disabled-color; border: 1px solid var(--sw-icon-btn-border);
border-radius: 3px; border-radius: 3px;
margin-left: 6px; margin-left: 6px;
cursor: pointer; cursor: pointer;
background-color: #eee; background-color: var(--sw-icon-btn-bg);
color: #666; color: var(--sw-icon-btn-color);
font-size: $font-size-smaller; font-size: $font-size-smaller;
} }

View File

@@ -65,7 +65,6 @@ limitations under the License. -->
<el-pagination <el-pagination
class="mt-10" class="mt-10"
small small
background
layout="prev, pager, next" layout="prev, pager, next"
:page-size="pageSize" :page-size="pageSize"
:total="continousProfilingStore.instances.length" :total="continousProfilingStore.instances.length"
@@ -150,14 +149,14 @@ limitations under the License. -->
font-weight: bold; font-weight: bold;
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
padding: 10px 20px; padding: 10px 20px;
background-color: #f3f4f9; background-color: var(--sw-table-header);
} }
.settings { .settings {
padding: 1px 0; padding: 1px 0;
border: 1px solid #666; border: 1px solid #666;
border-radius: 3px; border-radius: 3px;
color: #666; color: var(--text-color-placeholder);
cursor: pointer; cursor: pointer;
} }

View File

@@ -212,11 +212,11 @@ limitations under the License. -->
} }
#uri-param { #uri-param {
border: 1px solid #dcdfe6; border: 1px solid $border-color;
cursor: text; cursor: text;
padding: 0 5px; padding: 0 5px;
border-radius: 4px; border-radius: 4px;
color: #606266; color: var(--sw-setting-color);
outline: none; outline: none;
height: 100px; height: 100px;

View File

@@ -147,7 +147,7 @@ limitations under the License. -->
width: 300px; width: 300px;
height: 98%; height: 98%;
overflow: auto; overflow: auto;
border-right: 1px solid rgb(0 0 0 / 10%); border-right: 1px solid var(--sw-trace-list-border);
} }
.item span { .item span {
@@ -159,7 +159,7 @@ limitations under the License. -->
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
&.selected { &.selected {
background-color: #ededed; background-color: var(--sw-list-selected);
} }
} }
@@ -184,20 +184,21 @@ limitations under the License. -->
.profile-tr { .profile-tr {
&:hover { &:hover {
background-color: rgb(0 0 0 / 4%); background-color: var(--sw-list-hover);
} }
} }
.profile-t-tool { .profile-t-tool {
padding: 10px 5px 10px 10px; padding: 10px 5px 10px 10px;
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
background: #f3f4f9; background-color: var(--sw-table-header);
width: 100%; width: 100%;
font-weight: bold; font-weight: bold;
} }
.new-task { .new-task {
float: right; float: right;
color: $font-color;
} }
.reload { .reload {

View File

@@ -90,7 +90,7 @@ limitations under the License. -->
.header { .header {
padding: 5px 20px 5px 10px; padding: 5px 20px 5px 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
justify-content: space-between; justify-content: space-between;
} }

View File

@@ -76,7 +76,6 @@ limitations under the License. -->
</el-table> </el-table>
<el-pagination <el-pagination
class="pagination" class="pagination"
background
small small
layout="prev, pager, next" layout="prev, pager, next"
:page-size="pageSize" :page-size="pageSize"

View File

@@ -80,7 +80,7 @@ limitations under the License. -->
width: 300px; width: 300px;
height: calc(100% - 10px); height: calc(100% - 10px);
overflow: auto; overflow: auto;
border-right: 1px solid rgb(0 0 0 / 10%); border-right: 1px solid var(--sw-trace-list-border);
} }
.item span { .item span {
@@ -92,7 +92,7 @@ limitations under the License. -->
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
&.selected { &.selected {
background-color: #ededed; background-color: var(--sw-list-selected);
} }
} }
@@ -117,16 +117,16 @@ limitations under the License. -->
.profile-tr { .profile-tr {
&:hover { &:hover {
background-color: rgb(0 0 0 / 4%); background-color: var(--sw-list-hover);
} }
} }
.profile-t-tool { .profile-t-tool {
padding: 5px 10px; padding: 5px 10px;
font-weight: bold; font-weight: bold;
border-right: 1px solid rgb(0 0 0 / 7%); border-right: 1px solid var(--sw-trace-list-border);
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid var(--sw-trace-list-border);
background: #f3f4f9; background-color: var(--sw-table-header);
} }
.profile-btn { .profile-btn {

View File

@@ -15,10 +15,10 @@ limitations under the License. -->
<template> <template>
<div class="log"> <div class="log">
<div class="log-header" :class="type === 'browser' ? ['browser-header', 'flex-h'] : 'service-header'"> <div class="log-header flex-h" :class="type === 'browser' ? ['browser-header', 'flex-h'] : 'service-header'">
<template v-for="(item, index) in columns" :key="`col${index}`"> <template v-for="(item, index) in columns" :key="`col${index}`">
<div :class="[item.label, ['message', 'stack'].includes(item.label) ? 'max-item' : '']"> <div :class="[item.label, ['message', 'stack'].includes(item.label) ? 'max-item' : '']">
{{ t(item.value) }} {{ item.value && t(item.value) }}
</div> </div>
</template> </template>
</div> </div>
@@ -42,7 +42,7 @@ limitations under the License. -->
@closed="showDetail = false" @closed="showDetail = false"
:title="t('logDetail')" :title="t('logDetail')"
> >
<LogDetail :currentLog="currentLog" :columns="columns" /> <LogDetail :currentLog="currentLog" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@@ -74,41 +74,41 @@ limitations under the License. -->
.log { .log {
font-size: $font-size-smaller; font-size: $font-size-smaller;
height: 100%; height: 100%;
border-bottom: 1px solid #eee; border-bottom: 1px solid $border-color-primary;
width: 100%; width: 100%;
overflow: auto; overflow: auto;
} }
.log-header { .log-header {
width: 100%;
white-space: nowrap; white-space: nowrap;
user-select: none; user-select: none;
border-left: 0; border-left: 0;
border-right: 0; border-right: 0;
border-bottom: 1px solid rgb(0 0 0 / 10%); border-bottom: 1px solid var(--sw-trace-list-border);
.traceId { .traceId {
width: 390px; width: 20px;
}
.content {
width: 1300px;
} }
.content,
.tags { .tags {
width: 300px; width: 15px;
} }
.serviceInstanceName,
.endpointName,
.serviceName { .serviceName {
width: 200px; width: 200px;
} }
} }
.log-header div { .log-header div {
display: inline-block;
padding: 0 5px; padding: 0 5px;
border: 1px solid transparent; border: 1px solid transparent;
border-right: 1px dotted silver;
line-height: 30px; line-height: 30px;
background-color: #f3f4f9; background-color: var(--sw-table-header);
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

View File

@@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="log-detail"> <div class="log-detail">
<div class="mb-10 clear rk-flex" v-for="(item, index) in columns" :key="index"> <div class="mb-10 clear rk-flex" v-for="(item, index) in ServiceLogDetail" :key="index">
<span class="g-sm-4 grey">{{ t(item.value) }}:</span> <span class="g-sm-4 grey">{{ t(item.value) }}:</span>
<span v-if="['timestamp', 'time'].includes(item.label)" class="g-sm-8 mb-10"> <span v-if="['timestamp', 'time'].includes(item.label)" class="g-sm-8 mb-10">
{{ dateFormat(currentLog[item.label]) }} {{ dateFormat(currentLog[item.label]) }}
</span> </span>
<textarea <textarea
class="content mb-10" class="content mb-10 g-sm-8"
:readonly="true" :readonly="true"
v-else-if="item.label === 'content'" v-else-if="item.label === 'content'"
:value="contentFormat(item.label)" :value="contentFormat(item.label)"
@@ -36,14 +36,13 @@ limitations under the License. -->
import { computed } from "vue"; import { computed } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import type { Option } from "@/types/app";
import { dateFormat } from "@/utils/dateFormat"; import { dateFormat } from "@/utils/dateFormat";
import { formatJson } from "@/utils/formatJson"; import { formatJson } from "@/utils/formatJson";
import { ServiceLogDetail } from "./data";
/*global defineProps */ /*global defineProps */
const props = defineProps({ const props = defineProps({
currentLog: { type: Object as PropType<any>, default: () => ({}) }, currentLog: { type: Object as PropType<any>, default: () => ({}) },
columns: { type: Array as PropType<Option[]>, default: () => [] },
}); });
const { t } = useI18n(); const { t } = useI18n();
const logTags = computed(() => { const logTags = computed(() => {
@@ -67,12 +66,11 @@ limitations under the License. -->
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.content { .content {
max-width: 700px;
min-width: 500px;
min-height: 500px; min-height: 500px;
border: none; border: none;
outline: none; outline: none;
color: $font-color; color: $font-color;
overflow: auto; overflow: auto;
background-color: var(--el-dialog-bg-color);
} }
</style> </style>

View File

@@ -14,7 +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-item"> <div class="log-item flex-h">
<div <div
v-for="(item, index) in columns" v-for="(item, index) in columns"
:key="index" :key="index"
@@ -24,12 +24,12 @@ limitations under the License. -->
<span v-if="item.label === 'timestamp'"> <span v-if="item.label === 'timestamp'">
{{ dateFormat(data.timestamp) }} {{ dateFormat(data.timestamp) }}
</span> </span>
<span v-else-if="item.label === 'tags'"> <span v-else-if="item.label === 'tags'" :class="level.toLowerCase()"> > </span>
{{ tags }} <el-tooltip v-else-if="item.label === 'traceId' && !noLink" content="Trace Link">
</span> <span :class="noLink ? '' : 'blue'">
<span v-else-if="item.label === 'traceId' && !noLink" :class="noLink ? '' : 'blue'"> <Icon v-if="data[item.label]" iconName="merge" />
{{ data[item.label] }} </span>
</span> </el-tooltip>
<span v-else>{{ data[item.label] }}</span> <span v-else>{{ data[item.label] }}</span>
</div> </div>
</div> </div>
@@ -51,11 +51,11 @@ limitations under the License. -->
const options: Recordable<LayoutConfig> = inject("options") || {}; const options: Recordable<LayoutConfig> = inject("options") || {};
const emit = defineEmits(["select"]); const emit = defineEmits(["select"]);
const columns = ServiceLogConstants; const columns = ServiceLogConstants;
const tags = computed(() => { const level = computed(() => {
if (!props.data.tags) { if (!props.data.tags) {
return ""; return "";
} }
return String(props.data.tags.map((d: { key: string; value: string }) => `${d.key}=${d.value}`)); return (props.data.tags.find((d: { key: string; value: string }) => d.key === "level") || {}).value || "";
}); });
function selectLog(label: string, value: string) { function selectLog(label: string, value: string) {
@@ -76,6 +76,7 @@ limitations under the License. -->
{ {
sourceId: options.id || "", sourceId: options.id || "",
traceId: id, traceId: id,
id: props.data.serviceId || "",
}, },
"Trace", "Trace",
); );
@@ -83,57 +84,59 @@ limitations under the License. -->
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.log-item { .log-item {
white-space: nowrap;
position: relative;
cursor: pointer; cursor: pointer;
align-items: center;
min-height: 30px;
.traceId { .traceId {
width: 390px;
cursor: pointer; cursor: pointer;
width: 20px;
text-align: center;
position: relative;
span { span {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
line-height: 30px;
} }
.blue { .blue {
color: #448dfe; color: var(--el-color-primary);
} }
} }
.content,
.tags { .tags {
width: 300px; width: 15px;
text-align: center;
color: var(--sw-green);
font-weight: 400;
font-size: 14px;
}
.content {
width: 1300px;
} }
.serviceInstanceName,
.endpointName,
.serviceName { .serviceName {
width: 200px; width: 200px;
} }
} }
.log-item:hover { .log-item:hover {
background: rgba(0, 0, 0, 0.04); background: var(--sw-list-hover);
} }
.log-item > div { .log-item > div {
width: 140px; width: 60px;
padding: 0 5px; padding: 0 5px;
display: inline-block; display: inline-block;
border: 1px solid transparent; border: 1px solid transparent;
border-right: 1px dotted silver; white-space: normal;
word-break: break-all;
overflow: hidden; overflow: hidden;
height: 30px;
line-height: 30px;
text-overflow: ellipsis;
white-space: nowrap;
} }
.log-item .text { .log-item .text {
width: 100%; width: 100%;
display: inline-block;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@@ -143,4 +146,12 @@ limitations under the License. -->
height: 100%; height: 100%;
padding: 3px 8px; padding: 3px 8px;
} }
.error {
color: var(--sw-orange);
}
.warning {
color: var(--sw-orange);
}
</style> </style>

View File

@@ -16,33 +16,13 @@
*/ */
export const ServiceLogConstants = [ export const ServiceLogConstants = [
{
label: "serviceName",
value: "service",
},
{
label: "serviceInstanceName",
value: "instance",
},
{
label: "endpointName",
value: "endpoint",
},
{
label: "timestamp",
value: "time",
},
{
label: "contentType",
value: "contentType",
},
{ {
label: "tags", label: "tags",
value: "tags", value: "",
}, },
{ {
label: "traceId", label: "traceId",
value: "traceID", value: "",
}, },
{ {
label: "content", label: "content",
@@ -58,6 +38,10 @@ export const ServiceLogDetail = [
label: "serviceInstanceName", label: "serviceInstanceName",
value: "instance", value: "instance",
}, },
{
label: "endpointName",
value: "endpoint",
},
{ {
label: "timestamp", label: "timestamp",
value: "time", value: "time",

View File

@@ -18,7 +18,7 @@ limitations under the License. -->
<g class="svg-graph" :transform="`translate(${diff[0]}, ${diff[1]})`"> <g class="svg-graph" :transform="`translate(${diff[0]}, ${diff[1]})`">
<g class="hex-polygon"> <g class="hex-polygon">
<path :d="getHexPolygonVertices()" stroke="#D5DDF6" stroke-width="2" fill="none" /> <path :d="getHexPolygonVertices()" stroke="#D5DDF6" stroke-width="2" fill="none" />
<text :x="0" :y="radius - 15" fill="#000" text-anchor="middle"> <text :x="0" :y="radius - 15" :fill="appStore.theme === Themes.Dark ? '#eee' : '#000'" text-anchor="middle">
{{ selectorStore.currentPod && selectorStore.currentPod.label }} {{ selectorStore.currentPod && selectorStore.currentPod.label }}
</text> </text>
</g> </g>
@@ -40,7 +40,12 @@ limitations under the License. -->
:x="(node.x || 0) - 15" :x="(node.x || 0) - 15"
:y="(node.y || 0) - 15" :y="(node.y || 0) - 15"
/> />
<text :x="node.x" :y="(node.y || 0) + 28" fill="#000" text-anchor="middle"> <text
:x="node.x"
:y="(node.y || 0) + 28"
:fill="appStore.theme === Themes.Dark ? '#eee' : '#000'"
text-anchor="middle"
>
{{ node.name.length > 10 ? `${node.name.substring(0, 10)}...` : node.name }} {{ node.name.length > 10 ? `${node.name.substring(0, 10)}...` : node.name }}
</text> </text>
</g> </g>
@@ -122,6 +127,7 @@ limitations under the License. -->
import TimeLine from "./TimeLine.vue"; import TimeLine from "./TimeLine.vue";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import icons from "@/assets/img/icons"; import icons from "@/assets/img/icons";
import { Themes } from "@/constants/data";
/*global Nullable, defineProps */ /*global Nullable, defineProps */
const props = defineProps({ const props = defineProps({
@@ -524,7 +530,7 @@ limitations under the License. -->
cursor: pointer; cursor: pointer;
transition: all 0.5ms linear; transition: all 0.5ms linear;
border: 1px solid $disabled-color; border: 1px solid $disabled-color;
color: #666; color: var(--text-color-placeholder);
display: inline-block; display: inline-block;
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 3px;
@@ -568,7 +574,7 @@ limitations under the License. -->
position: absolute; position: absolute;
visibility: hidden; visibility: hidden;
padding: 5px; padding: 5px;
border: 1px solid #000; border: var(--sw-topology-border);
border-radius: 3px; border-radius: 3px;
background-color: $theme-background; background-color: $theme-background;
} }

View File

@@ -15,7 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="label">{{ t("linkDashboard") }}</div> <div class="label">{{ t("linkDashboard") }}</div>
<Selector <Selector
:value="dashboardStore.selectedGrid.linkDashboard || ''" :value="(dashboardStore.selectedGrid && dashboardStore.selectedGrid.linkDashboard) || ''"
:options="linkDashboards" :options="linkDashboards"
size="small" size="small"
placeholder="Please input a dashboard name for calls" placeholder="Please input a dashboard name for calls"

View File

@@ -18,7 +18,11 @@ limitations under the License. -->
<div class="profile-t-tool"> <div class="profile-t-tool">
<span>{{ t("taskList") }}</span> <span>{{ t("taskList") }}</span>
<span class="new-task cp" @click="createTask"> <span class="new-task cp" @click="createTask">
<Icon :style="{ color: inProcess ? '#ccc' : '#000' }" iconName="library_add" size="middle" /> <Icon
:style="{ color: inProcess ? '#ccc' : appStore.theme === Themes.Dark ? '#fff' : '#000' }"
iconName="library_add"
size="middle"
/>
</span> </span>
</div> </div>
<div class="profile-t-wrapper"> <div class="profile-t-wrapper">
@@ -78,6 +82,7 @@ limitations under the License. -->
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import NewTask from "./NewTask.vue"; import NewTask from "./NewTask.vue";
import { EBPFProfilingTriggerType } from "@/store/data"; import { EBPFProfilingTriggerType } from "@/store/data";
import { Themes } from "@/constants/data";
/*global Nullable */ /*global Nullable */
const { t } = useI18n(); const { t } = useI18n();
@@ -216,7 +221,7 @@ limitations under the License. -->
width: 330px; width: 330px;
height: calc(100% - 10px); height: calc(100% - 10px);
overflow: auto; overflow: auto;
border-right: 1px solid rgb(0 0 0 / 10%); border-right: 1px solid var(--sw-trace-list-border);
} }
.item span { .item span {
@@ -228,7 +233,7 @@ limitations under the License. -->
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
&.selected { &.selected {
background-color: #ededed; background-color: var(--sw-list-selected);
} }
} }
@@ -253,14 +258,14 @@ limitations under the License. -->
.profile-tr { .profile-tr {
&:hover { &:hover {
background-color: rgb(0 0 0 / 4%); background-color: var(--sw-list-hover);
} }
} }
.profile-t-tool { .profile-t-tool {
padding: 10px 5px 10px 10px; padding: 10px 5px 10px 10px;
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid rgb(0 0 0 / 7%);
background: #f3f4f9; background-color: var(--sw-table-header);
width: 100%; width: 100%;
} }

View File

@@ -142,7 +142,7 @@ limitations under the License. -->
cursor: pointer; cursor: pointer;
transition: all 0.5ms linear; transition: all 0.5ms linear;
border: 1px solid $disabled-color; border: 1px solid $disabled-color;
color: #666; color: var(--text-color-placeholder);
display: inline-block; display: inline-block;
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 3px;

View File

@@ -119,7 +119,7 @@ limitations under the License. -->
.header { .header {
padding: 10px; padding: 10px;
font-size: $font-size-smaller; font-size: $font-size-smaller;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid $border-color;
} }
.name { .name {

View File

@@ -58,6 +58,7 @@ limitations under the License. -->
const key = computed( const key = computed(
() => () =>
(profileStore.currentSegment && (profileStore.currentSegment &&
profileStore.currentSegment.spans &&
profileStore.currentSegment.spans.length && profileStore.currentSegment.spans.length &&
profileStore.currentSegment.spans[0].segmentId) || profileStore.currentSegment.spans[0].segmentId) ||
"", "",
@@ -82,7 +83,7 @@ limitations under the License. -->
.profile-t-wrapper { .profile-t-wrapper {
overflow: auto; overflow: auto;
flex-grow: 1; flex-grow: 1;
border-right: 1px solid rgb(0 0 0 / 10%); border-right: 1px solid var(--sw-trace-list-border);
} }
.profile-t-loading { .profile-t-loading {
@@ -110,25 +111,25 @@ limitations under the License. -->
.profile-tr { .profile-tr {
&:hover { &:hover {
background-color: rgb(0 0 0 / 4%); background-color: var(--sw-list-hover);
} }
} }
.profile-td { .profile-td {
padding: 5px 10px; padding: 5px 10px;
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid var(--sw-trace-list-border);
&.selected { &.selected {
background-color: #ededed; background-color: var(--sw-list-selected);
} }
} }
.profile-t-tool { .profile-t-tool {
padding: 5px 10px; padding: 5px 10px;
font-weight: bold; font-weight: bold;
border-right: 1px solid rgb(0 0 0 / 7%); border-right: 1px solid var(--sw-trace-list-border);
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid var(--sw-trace-list-border);
background: #f3f4f9; background-color: var(--sw-table-header);
} }
.log-item { .log-item {
@@ -144,6 +145,6 @@ limitations under the License. -->
} }
.profile-segment { .profile-segment {
border-top: 1px solid rgb(0 0 0 / 7%); border-top: 1px solid var(--sw-trace-list-border);
} }
</style> </style>

View File

@@ -107,7 +107,7 @@ limitations under the License. -->
user-select: none; user-select: none;
border-left: 0; border-left: 0;
border-right: 0; border-right: 0;
border-bottom: 1px solid rgb(0 0 0 / 10%); border-bottom: 1px solid var(--sw-trace-list-border);
} }
.profile-header div { .profile-header div {
@@ -115,7 +115,7 @@ limitations under the License. -->
padding: 0 4px; padding: 0 4px;
border-right: 1px dotted silver; border-right: 1px dotted silver;
line-height: 30px; line-height: 30px;
background-color: #f3f4f9; background-color: var(--sw-table-header);
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

View File

@@ -14,7 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div> <div>
<div :class="['profile-item', 'level' + data.parentId]" :style="{ color: data.topDur ? '#448dfe' : '#3d444f' }"> <div
:class="['profile-item', 'level' + data.parentId]"
:style="{ color: data.topDur ? '#448dfe' : appStore.theme === Themes.Dark ? '#fafbfc' : '#3d444f' }"
>
<div <div
:class="['thread', 'level' + data.parentId]" :class="['thread', 'level' + data.parentId]"
:style="{ :style="{
@@ -47,6 +50,8 @@ limitations under the License. -->
<script lang="ts"> <script lang="ts">
import { ref, defineComponent, toRefs } from "vue"; import { ref, defineComponent, toRefs } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
const props = { const props = {
data: { type: Object as PropType<any>, default: () => ({}) }, data: { type: Object as PropType<any>, default: () => ({}) },
@@ -56,24 +61,25 @@ limitations under the License. -->
name: "TableItem", name: "TableItem",
props, props,
setup(props) { setup(props) {
const appStore = useAppStoreWithOut();
const displayChildren = ref<boolean>(true); const displayChildren = ref<boolean>(true);
function toggle() { function toggle() {
displayChildren.value = !displayChildren.value; displayChildren.value = !displayChildren.value;
} }
return { toggle, displayChildren, ...toRefs(props) }; return { Themes, appStore, toggle, displayChildren, ...toRefs(props) };
}, },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "./profile.scss"; @import url("./profile.scss");
.profile-item.level0 { .profile-item.level0 {
background: rgba(0, 0, 0, 0.04); background-color: var(--sw-list-hover);
color: #448dfe; color: var(--el-color-primary);
&:hover { &:hover {
background: rgba(0, 0, 0, 0.04); background-color: var(--sw-list-hover);
color: #448dfe; color: var(--el-color-primary);
} }
&::before { &::before {
@@ -81,7 +87,7 @@ limitations under the License. -->
content: ""; content: "";
width: 5px; width: 5px;
height: 100%; height: 100%;
background: #448dfe; background-color: var(--el-color-primary);
left: 0; left: 0;
} }
} }
@@ -92,11 +98,11 @@ limitations under the License. -->
} }
.profile-item.selected { .profile-item.selected {
background: rgba(0, 0, 0, 0.04); background-color: var(--sw-list-selected);
} }
.profile-item:not(.level0):hover { .profile-item:not(.level0):hover {
background: rgba(0, 0, 0, 0.04); background-color: var(--sw-list-hover);
} }
.profile-item > div { .profile-item > div {
@@ -123,7 +129,7 @@ limitations under the License. -->
width: 100%; width: 100%;
height: 6px; height: 6px;
border-radius: 3px; border-radius: 3px;
background: rgb(63, 177, 227); background: var(--el-color-primary);
position: relative; position: relative;
margin-top: 11px; margin-top: 11px;
border: none; border: none;
@@ -131,7 +137,7 @@ limitations under the License. -->
.inner-progress_bar { .inner-progress_bar {
position: absolute; position: absolute;
background: rgb(110, 64, 170); background: rgb(110 64 170);
height: 4px; height: 4px;
border-radius: 2px; border-radius: 2px;
left: 0; left: 0;

View File

@@ -168,10 +168,10 @@ limitations under the License. -->
.profile-td { .profile-td {
padding: 5px 10px; padding: 5px 10px;
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid var(--sw-trace-list-border);
&.selected { &.selected {
background-color: #ededed; background-color: var(--sw-list-selected);
} }
} }
@@ -183,7 +183,7 @@ limitations under the License. -->
.profile-t-wrapper { .profile-t-wrapper {
overflow: auto; overflow: auto;
flex-grow: 1; flex-grow: 1;
border-right: 1px solid rgb(0 0 0 / 10%); border-right: 1px solid var(--sw-trace-list-border);
} }
.profile-t { .profile-t {
@@ -196,20 +196,20 @@ limitations under the License. -->
.profile-tr { .profile-tr {
&:hover { &:hover {
background-color: rgb(0 0 0 / 4%); background-color: var(--sw-list-hover);
} }
} }
.profile-segment { .profile-segment {
border-top: 1px solid rgb(0 0 0 / 7%); border-top: 1px solid var(--sw-trace-list-border);
} }
.profile-t-tool { .profile-t-tool {
padding: 5px 10px; padding: 5px 10px;
font-weight: bold; font-weight: bold;
border-right: 1px solid rgb(0 0 0 / 7%); border-right: 1px solid var(--sw-trace-list-border);
border-bottom: 1px solid rgb(0 0 0 / 7%); border-bottom: 1px solid var(--sw-trace-list-border);
background: #f3f4f9; background-color: var(--sw-table-header);
} }
.log-item { .log-item {

View File

@@ -43,6 +43,7 @@ limitations under the License. -->
:href="!n.type || n.type === `N/A` ? icons.UNDEFINED : icons[n.type.toUpperCase().replace('-', '')]" :href="!n.type || n.type === `N/A` ? icons.UNDEFINED : icons[n.type.toUpperCase().replace('-', '')]"
/> />
<text <text
class="node-text"
:x="n.x - (Math.min(n.name.length, 20) * 6) / 2 + 6" :x="n.x - (Math.min(n.name.length, 20) * 6) / 2 + 6"
:y="n.y + n.height + 8" :y="n.y + n.height + 8"
style="pointer-events: none" style="pointer-events: none"
@@ -139,7 +140,7 @@ limitations under the License. -->
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useTopologyStore } from "@/store/modules/topology"; import { useTopologyStore } from "@/store/modules/topology";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { EntityType, DepthList, MetricModes } from "../../../data"; import { EntityType, DepthList, MetricModes, CallTypes } from "../../../data";
import router from "@/router"; import router from "@/router";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import Settings from "./Settings.vue"; import Settings from "./Settings.vue";
@@ -188,7 +189,9 @@ limitations under the License. -->
onMounted(async () => { onMounted(async () => {
await nextTick(); await nextTick();
init(); setTimeout(() => {
init();
}, 10);
}); });
async function init() { async function init() {
const dom = document.querySelector(".topology")?.getBoundingClientRect() || { const dom = document.querySelector(".topology")?.getBoundingClientRect() || {
@@ -223,8 +226,8 @@ limitations under the License. -->
async function update() { async function update() {
if (settings.value.metricMode === MetricModes.Expression) { if (settings.value.metricMode === MetricModes.Expression) {
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || []); topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || []); topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
} else { } else {
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
@@ -238,10 +241,9 @@ limitations under the License. -->
setNodeTools(settings.value.nodeDashboard); setNodeTools(settings.value.nodeDashboard);
} }
function draw() { function computeLevels(calls: Call[], nodeList: Node[], levels: any[]) {
const node = findMostFrequent(topologyStore.calls); const node = findMostFrequent(calls);
const levels = []; const nodes = JSON.parse(JSON.stringify(nodeList)).sort((a: Node, b: Node) => {
const nodes = JSON.parse(JSON.stringify(topologyStore.nodes)).sort((a: Node, b: Node) => {
if (a.name.toLowerCase() < b.name.toLowerCase()) { if (a.name.toLowerCase() < b.name.toLowerCase()) {
return -1; return -1;
} }
@@ -253,15 +255,14 @@ limitations under the License. -->
const index = nodes.findIndex((n: Node) => n.type === "USER"); const index = nodes.findIndex((n: Node) => n.type === "USER");
let key = index; let key = index;
if (index < 0) { if (index < 0) {
const idx = nodes.findIndex((n: Node) => n.id === node.id); key = nodes.findIndex((n: Node) => n.id === node.id);
key = idx;
} }
levels.push([nodes[key]]); levels.push([nodes[key]]);
nodes.splice(key, 1); nodes.splice(key, 1);
for (const level of levels) { for (const level of levels) {
const a = []; const a = [];
for (const l of level) { for (const l of level) {
for (const n of topologyStore.calls) { for (const n of calls) {
if (n.target === l.id) { if (n.target === l.id) {
const i = nodes.findIndex((d: Node) => d.id === n.source); const i = nodes.findIndex((d: Node) => d.id === n.source);
if (i > -1) { if (i > -1) {
@@ -282,6 +283,18 @@ limitations under the License. -->
levels.push(a); levels.push(a);
} }
} }
if (nodes.length) {
const ids = nodes.map((d: Node) => d.id);
const links = calls.filter((item: Call) => ids.includes(item.source) || ids.includes(item.target));
const list = computeLevels(links, nodes, []);
levels = list.map((subArrayA, index) => subArrayA.concat(levels[index]));
}
return levels;
}
function draw() {
const levels = computeLevels(topologyStore.calls, topologyStore.nodes, []);
topologyLayout.value = layout(levels, topologyStore.calls, radius); topologyLayout.value = layout(levels, topologyStore.calls, radius);
graphWidth.value = topologyLayout.value.layout.width; graphWidth.value = topologyLayout.value.layout.width;
const drag: any = d3.drag().on("drag", (d: { x: number; y: number }) => { const drag: any = d3.drag().on("drag", (d: { x: number; y: number }) => {
@@ -678,6 +691,12 @@ limitations under the License. -->
overflow: auto; overflow: auto;
margin-top: 30px; margin-top: 30px;
.node-text {
fill: var(--sw-topology-color);
font-size: 12px;
opacity: 0.9;
}
.svg-topology { .svg-topology {
cursor: move; cursor: move;
background-color: $theme-background; background-color: $theme-background;
@@ -687,7 +706,7 @@ limitations under the License. -->
position: absolute; position: absolute;
top: 10px; top: 10px;
left: 25px; left: 25px;
color: #666; color: var(--sw-topology-color);
div { div {
margin-bottom: 8px; margin-bottom: 8px;
@@ -716,31 +735,26 @@ limitations under the License. -->
padding: 0 15px; padding: 0 15px;
border-radius: 3px; border-radius: 3px;
color: $disabled-color; color: $disabled-color;
border: 1px solid #eee; border: 1px solid $border-color-primary;
background-color: $theme-background; background-color: var(--sw-topology-setting-bg);
box-shadow: #eee 1px 2px 10px; box-shadow: var(--sw-topology-box-shadow);
transition: all 0.5ms linear; transition: all 0.5ms linear;
&.dark {
background-color: #2b3037;
}
} }
.label { .label {
color: #666; color: var(--sw-topology-color);
display: inline-block; display: inline-block;
margin-right: 5px; margin-right: 5px;
} }
.operations-list { .operations-list {
position: absolute; position: absolute;
color: #333; color: $font-color;
cursor: pointer; cursor: pointer;
border: var(--sw-topology-border);
border-radius: 3px;
background-color: $theme-background; background-color: $theme-background;
border-radius: 5px;
padding: 10px 0; padding: 10px 0;
border: 1px solid #999;
box-shadow: #ddd 1px 2px 10px;
span { span {
display: block; display: block;
@@ -752,7 +766,7 @@ limitations under the License. -->
span:hover { span:hover {
color: $active-color; color: $active-color;
background-color: #eee; background-color: $popper-hover-bg-color;
} }
} }
@@ -765,7 +779,7 @@ limitations under the License. -->
.switch-icon { .switch-icon {
cursor: pointer; cursor: pointer;
transition: all 0.5ms linear; transition: all 0.5ms linear;
background: rgb(0 0 0 / 30%); background: var(--sw-topology-switch-icon);
color: $text-color; color: $text-color;
display: inline-block; display: inline-block;
padding: 2px 4px; padding: 2px 4px;
@@ -784,13 +798,6 @@ limitations under the License. -->
.topo-node { .topo-node {
cursor: pointer; cursor: pointer;
} }
.topo-text {
font-family: Lato, "Source Han Sans CN", "Microsoft YaHei", sans-serif;
fill: #ddd;
font-size: 11px;
opacity: 0.8;
}
} }
@keyframes topo-dash { @keyframes topo-dash {
from { from {
@@ -810,7 +817,7 @@ limitations under the License. -->
position: absolute; position: absolute;
visibility: hidden; visibility: hidden;
padding: 5px; padding: 5px;
border: 1px solid #000; border: var(--sw-topology-border);
border-radius: 3px; border-radius: 3px;
background-color: $theme-background; background-color: $theme-background;
} }

View File

@@ -54,7 +54,6 @@ limitations under the License. -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { CalculationOpts, MetricModes } from "../../../data"; import { CalculationOpts, MetricModes } from "../../../data";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
@@ -63,15 +62,40 @@ limitations under the License. -->
/*global defineEmits, defineProps */ /*global defineEmits, defineProps */
const props = defineProps({ const props = defineProps({
type: { type: String, default: "" }, type: { type: String, default: "" },
metrics: { type: Array as PropType<string[]>, default: () => [] }, isExpression: { type: Boolean, default: true },
}); });
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(["update"]); const emit = defineEmits(["update"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const m = props.metrics.map((d: string) => { const getMetrics = computed(() => {
return { label: d, value: d }; let metrics = [];
const {
linkServerExpressions,
linkServerMetrics,
linkClientExpressions,
linkClientMetrics,
nodeExpressions,
nodeMetrics,
} = dashboardStore.selectedGrid;
switch (props.type) {
case "linkServerMetricConfig":
metrics = props.isExpression ? linkServerExpressions : linkServerMetrics;
break;
case "linkClientMetricConfig":
metrics = props.isExpression ? linkClientExpressions : linkClientMetrics;
break;
case "nodeMetricConfig":
metrics = props.isExpression ? nodeExpressions : nodeMetrics;
break;
}
return metrics || [];
});
const metricList = computed(() => {
const m = getMetrics.value.map((d: string) => {
return { label: d, value: d };
});
return m.length ? m : [{ label: "", value: "" }];
}); });
const metricList = ref<Option[]>(m.length ? m : [{ label: "", value: "" }]);
const currentMetric = ref<string>(metricList.value[0].value); const currentMetric = ref<string>(metricList.value[0].value);
const currentConfig = ref<{ unit: string; calculation: string; label: string }>({ const currentConfig = ref<{ unit: string; calculation: string; label: string }>({
unit: "", unit: "",
@@ -81,6 +105,7 @@ limitations under the License. -->
const currentIndex = ref<number>(0); const currentIndex = ref<number>(0);
const getMetricConfig = computed(() => { const getMetricConfig = computed(() => {
let config = []; let config = [];
switch (props.type) { switch (props.type) {
case "linkServerMetricConfig": case "linkServerMetricConfig":
config = dashboardStore.selectedGrid.linkServerMetricConfig; config = dashboardStore.selectedGrid.linkServerMetricConfig;
@@ -120,10 +145,6 @@ limitations under the License. -->
watch( watch(
() => props.type, () => props.type,
() => { () => {
const m = props.metrics.map((d: string) => {
return { label: d, value: d };
});
metricList.value = m.length ? m : [{ label: "", value: "" }];
currentMetric.value = metricList.value[0].value; currentMetric.value = metricList.value[0].value;
const config = getMetricConfig.value || []; const config = getMetricConfig.value || [];
currentIndex.value = 0; currentIndex.value = 0;

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