This is an automated email from the ASF dual-hosted git repository.
qiuxiafan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git
The following commit(s) were added to refs/heads/main by this push:
new 7472d70 feat: create global actions for setting page title and auto
refresh pages (#13)
7472d70 is described below
commit 7472d70720153ceb12dc7eb1ff347f18f3bb45ce
Author: Fine0830 <[email protected]>
AuthorDate: Wed Jan 26 12:18:03 2022 +0800
feat: create global actions for setting page title and auto refresh pages
(#13)
* fix: update heat map
* feat: update servicelist
* fix: update list
* feat: update page with changing times
* feat: set auto fresh
* feat: set page titles
---
src/assets/icons/retry.svg | 16 ++++++
src/hooks/useProcessor.ts | 47 +++++++++--------
src/layout/components/NavBar.vue | 14 +++--
src/store/data.ts | 21 ++++++++
src/store/modules/app.ts | 10 ++++
src/store/modules/dashboard.ts | 9 +++-
src/styles/lib.scss | 11 ++++
src/views/Log.vue | 4 ++
src/views/Settings.vue | 14 +++--
src/views/dashboard/Edit.vue | 4 +-
src/views/dashboard/List.vue | 6 +++
src/views/dashboard/New.vue | 3 ++
.../configuration/graph-styles/HeatMap.vue | 59 ++++++++++++++++++++++
src/views/dashboard/controls/Widget.vue | 13 ++---
src/views/dashboard/data.ts | 17 +++----
src/views/dashboard/graphs/EndpointList.vue | 13 ++++-
src/views/dashboard/graphs/HeatMap.vue | 24 +++++----
src/views/dashboard/graphs/InstanceList.vue | 4 +-
src/views/dashboard/graphs/ServiceList.vue | 18 +++++--
src/views/dashboard/graphs/index.ts | 4 +-
src/views/dashboard/panel/Tool.vue | 35 ++++++++++---
src/views/service/Panel.vue | 9 ++++
22 files changed, 282 insertions(+), 73 deletions(-)
diff --git a/src/assets/icons/retry.svg b/src/assets/icons/retry.svg
new file mode 100755
index 0000000..dfff925
--- /dev/null
+++ b/src/assets/icons/retry.svg
@@ -0,0 +1,16 @@
+<!-- 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. -->
+
+<svg width="16" height="16" viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/retry</title><path
d="M4.074 6.957c-.578 2.136.7 4.331 2.856 4.904a4.05 4.05 0 0 0 2.479-.124
1.013 1.013 0 0 1 1.303.579.998.998 0 0 1-.585 1.291 6.086 6.086 0 0
1-3.72.187c-3.232-.858-5.15-4.151-4.284-7.355l-.749-.199a.498.498 0 0
1-.122-.917L3.47 4.056a.507.507 0 0 1 .69.183l1.28 2.198a.497.497 0 0 1
.05.38.505.505 0 0 1-.618.353l-.798-.212zm7.852 2. [...]
\ No newline at end of file
diff --git a/src/hooks/useProcessor.ts b/src/hooks/useProcessor.ts
index 888694f..e50e6fb 100644
--- a/src/hooks/useProcessor.ts
+++ b/src/hooks/useProcessor.ts
@@ -19,7 +19,7 @@ import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app";
-import { Instance, Endpoint } from "@/types/selector";
+import { Instance, Endpoint, Service } from "@/types/selector";
export function useQueryProcessor(config: any) {
if (!(config.metrics && config.metrics[0])) {
@@ -28,7 +28,7 @@ export function useQueryProcessor(config: any) {
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
- if (!selectorStore.currentService) {
+ if (!selectorStore.currentService && dashboardStore.entity !== "All") {
return;
}
const conditions: { [key: string]: unknown } = {
@@ -190,7 +190,7 @@ export function useSourceProcessor(
}
export function useQueryPodsMetrics(
- pods: Array<Instance | Endpoint>,
+ pods: Array<Instance | Endpoint | Service | any>,
config: { metrics: string[]; metricTypes: string[] },
scope: string
) {
@@ -202,25 +202,30 @@ export function useQueryPodsMetrics(
const variables: string[] = [`$duration: Duration!`];
const { currentService } = selectorStore;
- const fragmentList = pods.map((d: Instance | Endpoint, index: number) => {
- const param = {
- scope,
- serviceName: currentService.label,
- serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined,
- endpointName: scope === "Endpoint" ? d.label : undefined,
- normal: currentService.normal,
- };
- const f = config.metrics.map((name: string, idx: number) => {
- const metricType = config.metricTypes[idx] || "";
- conditions[`condition${index}${idx}`] = {
- name,
- entity: param,
+ const fragmentList = pods.map(
+ (
+ d: (Instance | Endpoint | Service) & { normal: boolean },
+ index: number
+ ) => {
+ const param = {
+ scope,
+ serviceName: scope === "Service" ? d.label : currentService.label,
+ serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined,
+ endpointName: scope === "Endpoint" ? d.label : undefined,
+ normal: scope === "Service" ? d.normal : currentService.normal,
};
- variables.push(`$condition${index}${idx}: MetricsCondition!`);
- return `${name}${index}${idx}: ${metricType}(condition:
$condition${index}${idx}, duration: $duration)${RespFields[metricType]}`;
- });
- return f;
- });
+ const f = config.metrics.map((name: string, idx: number) => {
+ const metricType = config.metricTypes[idx] || "";
+ conditions[`condition${index}${idx}`] = {
+ name,
+ entity: param,
+ };
+ variables.push(`$condition${index}${idx}: MetricsCondition!`);
+ return `${name}${index}${idx}: ${metricType}(condition:
$condition${index}${idx}, duration: $duration)${RespFields[metricType]}`;
+ });
+ return f;
+ }
+ );
const fragment = fragmentList.flat(1).join(" ");
const queryStr = `query queryData(${variables}) {${fragment}}`;
diff --git a/src/layout/components/NavBar.vue b/src/layout/components/NavBar.vue
index d518570..bec073a 100644
--- a/src/layout/components/NavBar.vue
+++ b/src/layout/components/NavBar.vue
@@ -14,7 +14,7 @@ See the License for the specific language governing
permissions and
limitations under the License. -->
<template>
<div class="nav-bar flex-h" :class="{ dark: theme === 'dark' }">
- <div class="title">{{ t(pageName) }}</div>
+ <div class="title">{{ appStore.pageTitle || t(pageName) }}</div>
<div class="app-config">
<span class="red" v-show="timeRange">{{ t("timeTips") }}</span>
<TimePicker
@@ -27,9 +27,9 @@ limitations under the License. -->
UTC{{ utcHour >= 0 ? "+" : ""
}}{{ `${appStore.utcHour}:${appStore.utcMin}` }}
</span>
- <!-- <span @click="handleReload" title="refresh">
- <Icon icon="retry" :loading="auto" class="middle" />
- </span> -->
+ <span title="refresh" class="ghost ml-5 cp" @click="handleReload">
+ <Icon iconName="retry" :loading="appStore.autoRefresh" class="middle"
/>
+ </span>
</div>
</div>
</template>
@@ -66,6 +66,12 @@ const time = computed(() => [
appStore.durationRow.start,
appStore.durationRow.end,
]);
+const handleReload = () => {
+ const gap =
+ appStore.duration.end.getTime() - appStore.duration.start.getTime();
+ const time: Date[] = [new Date(new Date().getTime() - gap), new Date()];
+ appStore.setDuration(timeFormat(time));
+};
function changeTimeRange(val: Date[]) {
timeRange.value =
val[1].getTime() - val[0].getTime() > 60 * 24 * 60 * 60 * 1000 ? 1 : 0;
diff --git a/src/store/data.ts b/src/store/data.ts
index 25caaec..5a26937 100644
--- a/src/store/data.ts
+++ b/src/store/data.ts
@@ -101,3 +101,24 @@ export const ConfigData2: any = {
},
children: [],
};
+export const ConfigData3: any = {
+ x: 0,
+ y: 0,
+ w: 8,
+ h: 12,
+ i: "0",
+ metrics: ["all_heatmap"],
+ metricTypes: ["readHeatMap"],
+ type: "Widget",
+ widget: {
+ title: "all_heatmap",
+ tips: "Tooltip",
+ },
+ graph: {
+ type: "HeatMap",
+ },
+ standard: {
+ unit: "min",
+ },
+ children: [],
+};
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index e89f1e3..bf55be2 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -28,6 +28,8 @@ interface AppState {
utcMin: number;
eventStack: (() => unknown)[];
timer: Nullable<any>;
+ autoRefresh: boolean;
+ pageTitle: string;
}
export const appStore = defineStore({
@@ -39,6 +41,8 @@ export const appStore = defineStore({
utcMin: 0,
eventStack: [],
timer: null,
+ autoRefresh: false,
+ pageTitle: "",
}),
getters: {
duration(): Duration {
@@ -117,6 +121,12 @@ export const appStore = defineStore({
setEventStack(funcs: (() => void)[]): void {
this.eventStack = funcs;
},
+ setAutoRefresh(auto: boolean) {
+ this.autoRefresh = auto;
+ },
+ setPageTitle(title: string) {
+ this.pageTitle = title;
+ },
runEventStack() {
if (this.timer) {
clearTimeout(this.timer);
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 47fc4a7..88264c2 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -18,7 +18,7 @@ import { defineStore } from "pinia";
import { store } from "@/store";
import { LayoutConfig } from "@/types/dashboard";
import graph from "@/graph";
-import { ConfigData, ConfigData1, ConfigData2 } from "../data";
+import { ConfigData, ConfigData1, ConfigData2, ConfigData3 } from "../data";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors";
import { NewControl } from "../data";
@@ -146,12 +146,19 @@ export const dashboardStore = defineStore({
},
setEntity(type: string) {
this.entity = type;
+ // todo
if (type === "ServiceInstance") {
this.layout = [ConfigData1];
}
if (type === "Endpoint") {
this.layout = [ConfigData2];
}
+ if (type == "All") {
+ this.layout = [ConfigData3];
+ }
+ if (type == "Service") {
+ this.layout = [ConfigData];
+ }
},
setConfigs(param: { [key: string]: unknown }) {
const actived = this.activedGridItem.split("-");
diff --git a/src/styles/lib.scss b/src/styles/lib.scss
index 43a06b8..e49087a 100644
--- a/src/styles/lib.scss
+++ b/src/styles/lib.scss
@@ -126,3 +126,14 @@
.mr-20 {
margin-right: 20px;
}
+@keyframes loading {
+ 0% {
+ transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(1turn);
+ transform: rotate(1turn);
+ }
+}
diff --git a/src/views/Log.vue b/src/views/Log.vue
index f70cb63..9b188c7 100644
--- a/src/views/Log.vue
+++ b/src/views/Log.vue
@@ -16,6 +16,10 @@ limitations under the License. -->
<div class="about">{{ props.msg }}</div>
</template>
<script lang="ts" setup>
+import { useAppStoreWithOut } from "@/store/modules/app";
+
+const appStore = useAppStoreWithOut();
+appStore.setPageTitle("Log");
/*global defineProps */
const props = defineProps({
msg: String,
diff --git a/src/views/Settings.vue b/src/views/Settings.vue
index a4d8c6f..03313f2 100644
--- a/src/views/Settings.vue
+++ b/src/views/Settings.vue
@@ -55,7 +55,7 @@ limitations under the License. -->
</div>
<div class="flex-h item">
<span class="label">{{ t("auto") }}</span>
- <el-switch :change="handleAuto" style="height: 25px" />
+ <el-switch v-model="auto" @change="handleAuto" style="height: 25px" />
<div class="auto-time ml-5">
<span class="auto-select">
<input
@@ -90,17 +90,18 @@ const utcArr = appStore.utc.split(":");
const utcHour = ref<number>(isNaN(Number(utcArr[0])) ? 0 : Number(utcArr[0]));
const utcMin = ref<number>(isNaN(Number(utcArr[1])) ? 0 : Number(utcArr[1]));
+appStore.setPageTitle("Setting");
const handleReload = () => {
const gap =
appStore.duration.end.getTime() - appStore.duration.start.getTime();
const time: Date[] = [new Date(new Date().getTime() - gap), new Date()];
appStore.setDuration(timeFormat(time));
};
-const handleAuto = (status: boolean) => {
+const handleAuto = () => {
if (autoTime.value < 1) {
return;
}
- auto.value = status;
+ appStore.setAutoRefresh(auto.value);
if (auto.value) {
handleReload();
state.timer = setInterval(handleReload, autoTime.value * 1000);
@@ -164,15 +165,16 @@ const setUTCMin = () => {
outline: none;
padding-bottom: 0;
}
+
.utc-min {
display: inline-block;
padding-top: 2px;
}
+
.auto-select {
border-radius: 3px;
background-color: #fff;
padding: 1px;
- border-radius: 3px;
input {
width: 38px;
@@ -180,14 +182,17 @@ const setUTCMin = () => {
outline: 0;
}
}
+
.settings {
color: #222;
font-family: inherit;
font-size: 14px;
padding: 20px;
+
.item {
margin-top: 10px;
}
+
input {
outline: 0;
width: 50px;
@@ -196,6 +201,7 @@ const setUTCMin = () => {
text-align: center;
height: 25px;
}
+
.label {
width: 100px;
display: inline-block;
diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue
index d073e14..a96732a 100644
--- a/src/views/dashboard/Edit.vue
+++ b/src/views/dashboard/Edit.vue
@@ -34,8 +34,10 @@ import GridLayout from "./panel/Layout.vue";
import Tool from "./panel/Tool.vue";
import ConfigEdit from "./configuration/ConfigEdit.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
+import { useAppStoreWithOut } from "@/store/modules/app";
const dashboardStore = useDashboardStore();
+const appStore = useAppStoreWithOut();
const { t } = useI18n();
// fetch layout data from serve side
// const layout: any[] = [
@@ -56,7 +58,7 @@ const { t } = useI18n();
// { x: 8, y: 27, w: 4, h: 15, i: "16" },
// ];
// dashboardStore.setLayout(layout);
-
+appStore.setPageTitle("Dashboard Name");
function handleClick(e: any) {
e.stopPropagation();
if (e.target.className === "ds-main") {
diff --git a/src/views/dashboard/List.vue b/src/views/dashboard/List.vue
index 6f936fb..50bb970 100644
--- a/src/views/dashboard/List.vue
+++ b/src/views/dashboard/List.vue
@@ -61,6 +61,10 @@ limitations under the License. -->
import { ref } from "vue";
import { useI18n } from "vue-i18n";
import { ElTable, ElTableColumn, ElButton, ElInput } from "element-plus";
+import { useAppStoreWithOut } from "@/store/modules/app";
+
+const appStore = useAppStoreWithOut();
+appStore.setPageTitle("Dashboard List");
// # - os-linux
// # - k8s
// # - general(agent-installed)
@@ -107,9 +111,11 @@ const handleDelete = (index: number, row: any) => {
.header {
flex-direction: row-reverse;
}
+
.dashboard-list {
padding: 20px;
}
+
.input-with-search {
width: 300px;
margin-left: 20px;
diff --git a/src/views/dashboard/New.vue b/src/views/dashboard/New.vue
index 6147dc4..542d5df 100644
--- a/src/views/dashboard/New.vue
+++ b/src/views/dashboard/New.vue
@@ -59,7 +59,10 @@ import router from "@/router";
import { useSelectorStore } from "@/store/modules/selectors";
import { EntityType } from "./data";
import { ElMessage } from "element-plus";
+import { useAppStoreWithOut } from "@/store/modules/app";
+const appStore = useAppStoreWithOut();
+appStore.setPageTitle("Dashboard New");
const { t } = useI18n();
const selectorStore = useSelectorStore();
const states = reactive({
diff --git a/src/views/dashboard/configuration/graph-styles/HeatMap.vue
b/src/views/dashboard/configuration/graph-styles/HeatMap.vue
new file mode 100644
index 0000000..de9a4da
--- /dev/null
+++ b/src/views/dashboard/configuration/graph-styles/HeatMap.vue
@@ -0,0 +1,59 @@
+<!-- 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. -->
+<template>
+ <div>
+ <span class="label">{{ t("fontSize") }}</span>
+ <el-slider
+ class="slider"
+ v-model="fontSize"
+ show-input
+ input-size="small"
+ :min="10"
+ :max="20"
+ :step="1"
+ @change="updateConfig({ fontSize })"
+ />
+ </div>
+</template>
+<script lang="ts" setup>
+import { ref } from "vue";
+import { useI18n } from "vue-i18n";
+import { useDashboardStore } from "@/store/modules/dashboard";
+
+const { t } = useI18n();
+const dashboardStore = useDashboardStore();
+const fontSize = ref(dashboardStore.selectedGrid.graph.fontSize);
+
+function updateConfig(param: { [key: string]: unknown }) {
+ const graph = {
+ ...dashboardStore.selectedGrid.graph,
+ ...param,
+ };
+ dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, graph });
+}
+</script>
+<style lang="scss" scoped>
+.slider {
+ width: 500px;
+ margin-top: -13px;
+}
+
+.label {
+ font-size: 13px;
+ font-weight: 500;
+ display: block;
+ margin-bottom: 5px;
+}
+</style>
diff --git a/src/views/dashboard/controls/Widget.vue
b/src/views/dashboard/controls/Widget.vue
index d78f94a..254e71f 100644
--- a/src/views/dashboard/controls/Widget.vue
+++ b/src/views/dashboard/controls/Widget.vue
@@ -93,6 +93,10 @@ export default defineComponent({
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
+ if (dashboardStore.entity === EntityType[1].value) {
+ queryMetrics();
+ }
+
async function queryMetrics() {
const params = await useQueryProcessor(props.data);
if (!params) {
@@ -133,7 +137,7 @@ export default defineComponent({
}
);
watch(
- () => [selectorStore.currentService],
+ () => selectorStore.currentService,
() => {
if (dashboardStore.entity === EntityType[0].value) {
queryMetrics();
@@ -141,12 +145,9 @@ export default defineComponent({
}
);
watch(
- () => [selectorStore.currentPod],
+ () => selectorStore.currentPod,
() => {
- if (
- dashboardStore.entity === EntityType[0].value ||
- dashboardStore.entity === EntityType[1].value
- ) {
+ if (dashboardStore.entity === EntityType[0].value) {
return;
}
queryMetrics();
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index bff6c57..50d0e3e 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -41,7 +41,7 @@ export const MetricChartType: any = {
],
sortMetrics: [{ label: "Top List", value: "TopList" }],
readLabeledMetricsValues: [{ label: "Line", value: "Line" }],
- readHeatMap: [{ label: "Heatmap", value: "Heatmap" }],
+ readHeatMap: [{ label: "Heat Map", value: "HeatMap" }],
readSampledRecords: [{ label: "Top List", value: "TopList" }],
};
export const DefaultGraphConfig: { [key: string]: any } = {
@@ -93,6 +93,9 @@ export const DefaultGraphConfig: { [key: string]: any } = {
dashboardName: "",
fontSize: 12,
},
+ HeatMap: {
+ type: "HeatMap",
+ },
};
export enum MetricsType {
@@ -141,16 +144,10 @@ export const EntityType = [
{ value: "All", label: "All", key: 10 },
{ value: "Endpoint", label: "Service Endpoint", key: 3 },
{ value: "ServiceInstance", label: "Service Instance", key: 3 },
- { value: "ServiceRelationClient", label: "Service Relation(client)", key: 2
},
- { value: "ServiceRelationServer", label: "Service Relation(server)", key: 2
},
- {
- value: "ServiceInstanceRelationClient",
- label: "Service Instance Relation(client)",
- key: 4,
- },
+ { value: "ServiceRelation", label: "Service Relation", key: 2 },
{
- value: "ServiceInstanceRelationServer",
- label: "Service Instance Relation(server)",
+ value: "ServiceInstanceRelation",
+ label: "Service Instance Relation",
key: 4,
},
{ value: "EndpointRelation", label: "Endpoint Relation", key: 4 },
diff --git a/src/views/dashboard/graphs/EndpointList.vue
b/src/views/dashboard/graphs/EndpointList.vue
index a895349..397548e 100644
--- a/src/views/dashboard/graphs/EndpointList.vue
+++ b/src/views/dashboard/graphs/EndpointList.vue
@@ -49,10 +49,16 @@ limitations under the License. -->
<template #default="scope">
<div class="chart">
<Line
- :data="{ metric: scope.row[metric] }"
+ v-if="config.metricTypes[index] === 'readMetricsValues'"
+ :data="{ [metric]: scope.row[metric] }"
:intervalTime="intervalTime"
:config="{ showXAxis: false, showYAxis: false }"
/>
+ <Card
+ v-else
+ :data="{ [metric]: scope.row[metric] }"
+ :config="{ textAlign: 'left' }"
+ />
</div>
</template>
</el-table-column>
@@ -79,6 +85,7 @@ import { Endpoint } from "@/types/selector";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useProcessor";
import Line from "./Line.vue";
+import Card from "./Card.vue";
import { EntityType } from "../data";
/*global defineProps */
@@ -158,7 +165,9 @@ function searchList() {
watch(
() => [props.config.metricTypes, props.config.metrics],
() => {
- queryEndpointMetrics(endpoints.value);
+ if (dashboardStore.showConfig) {
+ queryEndpointMetrics(endpoints.value);
+ }
}
);
</script>
diff --git a/src/views/dashboard/graphs/HeatMap.vue
b/src/views/dashboard/graphs/HeatMap.vue
index 952658e..76036c6 100644
--- a/src/views/dashboard/graphs/HeatMap.vue
+++ b/src/views/dashboard/graphs/HeatMap.vue
@@ -23,7 +23,9 @@ import { StandardConfig } from "@/types/dashboard";
/*global defineProps */
const props = defineProps({
data: {
- type: Object as PropType<{ nodes: number[][]; buckets: number[][] }>,
+ type: Object as PropType<{
+ [key: string]: { nodes: number[][]; buckets: number[][] };
+ }>,
default: () => ({}),
},
intervalTime: { type: Array as PropType<string[]>, default: () => [] },
@@ -37,8 +39,11 @@ const props = defineProps({
},
});
const option = computed(() => getOption());
+
function getOption() {
- const source = (props.data.nodes || []).map((d: number[]) => d[2]);
+ const metric = props.config.metrics[0];
+ const nodes = (props.data[metric] && props.data[metric].nodes) || [];
+ const source = (nodes || []).map((d: number[]) => d[2]);
const maxItem = Math.max(...source);
const minItem = Math.min(...source);
const colorBox = [
@@ -63,15 +68,16 @@ function getOption() {
"#761212",
"#671010",
];
+
return {
tooltip: {
position: "top",
- formatter: (a: any) =>
- `${a.data[1] * 100}${props.standard.unit} [ ${a.data[2]} ]`,
- textStyle: {
- fontSize: 13,
- color: "#ccc",
- },
+ // formatter: (a: any) =>
+ // `${a.data[1] * 100}${props.standard.unit} [ ${a.data[2]} ]`,
+ // textStyle: {
+ // fontSize: 13,
+ // color: "#ccc",
+ // },
},
grid: {
top: 15,
@@ -112,7 +118,7 @@ function getOption() {
series: [
{
type: "heatmap",
- data: props.data.nodes || [],
+ data: nodes || [],
emphasis: {
itemStyle: {
shadowBlur: 10,
diff --git a/src/views/dashboard/graphs/InstanceList.vue
b/src/views/dashboard/graphs/InstanceList.vue
index aadcb2b..1ec86a4 100644
--- a/src/views/dashboard/graphs/InstanceList.vue
+++ b/src/views/dashboard/graphs/InstanceList.vue
@@ -170,7 +170,9 @@ function searchList() {
watch(
() => [props.config.metricTypes, props.config.metrics],
() => {
- queryInstanceMetrics(instances.value);
+ if (dashboardStore.showConfig) {
+ queryInstanceMetrics(instances.value);
+ }
}
);
</script>
diff --git a/src/views/dashboard/graphs/ServiceList.vue
b/src/views/dashboard/graphs/ServiceList.vue
index b5f1430..71707a4 100644
--- a/src/views/dashboard/graphs/ServiceList.vue
+++ b/src/views/dashboard/graphs/ServiceList.vue
@@ -34,7 +34,7 @@ limitations under the License. -->
<template #default="scope">
<router-link
class="link"
-
:to="`/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${selectorStore.currentService.id}/${config.dashboardName}`"
+
:to="`/dashboard/${dashboardStore.layerId}/${EntityType[0].value}/${scope.row.id}/${config.dashboardName}`"
:key="1"
:style="{ fontSize: `${config.fontSize}px` }"
>
@@ -50,10 +50,16 @@ limitations under the License. -->
<template #default="scope">
<div class="chart">
<Line
- :data="{ metric: scope.row[metric] }"
+ v-if="config.metricTypes[index] === 'readMetricsValues'"
+ :data="{ [metric]: scope.row[metric] }"
:intervalTime="intervalTime"
:config="{ showXAxis: false, showYAxis: false }"
/>
+ <Card
+ v-else
+ :data="{ [metric]: scope.row[metric] }"
+ :config="{ textAlign: 'left' }"
+ />
</div>
</template>
</el-table-column>
@@ -76,6 +82,7 @@ import { ElMessage } from "element-plus";
import type { PropType } from "vue";
import { ServiceListConfig } from "@/types/dashboard";
import Line from "./Line.vue";
+import Card from "./Card.vue";
import { useSelectorStore } from "@/store/modules/selectors";
import { useDashboardStore } from "@/store/modules/dashboard";
import { Service } from "@/types/selector";
@@ -111,13 +118,14 @@ queryServices();
async function queryServices() {
chartLoading.value = true;
- const resp = await selectorStore.fetchServices();
+ const resp = await selectorStore.fetchServices(dashboardStore.layerId);
chartLoading.value = false;
if (resp.errors) {
ElMessage.error(resp.errors);
}
services.value = selectorStore.services.splice(0, pageSize);
+ queryServiceMetrics(services.value);
}
async function queryServiceMetrics(currentServices: Service[]) {
const { metrics } = props.config;
@@ -155,7 +163,9 @@ function searchList() {
watch(
() => [props.config.metricTypes, props.config.metrics],
() => {
- queryServiceMetrics(services.value);
+ if (dashboardStore.showConfig) {
+ queryServiceMetrics(services.value);
+ }
}
);
</script>
diff --git a/src/views/dashboard/graphs/index.ts
b/src/views/dashboard/graphs/index.ts
index dedb645..1118b59 100644
--- a/src/views/dashboard/graphs/index.ts
+++ b/src/views/dashboard/graphs/index.ts
@@ -18,7 +18,7 @@
import Area from "./Area.vue";
import Line from "./Line.vue";
import Bar from "./Bar.vue";
-import Heatmap from "./HeatMap.vue";
+import HeatMap from "./HeatMap.vue";
import TopList from "./TopList.vue";
import Table from "./Table.vue";
import Pie from "./Pie.vue";
@@ -30,7 +30,7 @@ import ServiceList from "./ServiceList.vue";
export default {
Line,
Bar,
- Heatmap,
+ HeatMap,
TopList,
Area,
Table,
diff --git a/src/views/dashboard/panel/Tool.vue
b/src/views/dashboard/panel/Tool.vue
index 9ba4f40..1f8584e 100644
--- a/src/views/dashboard/panel/Tool.vue
+++ b/src/views/dashboard/panel/Tool.vue
@@ -40,7 +40,7 @@ limitations under the License. -->
size="mini"
placeholder="Select a data"
@change="changePods"
- class="selectors"
+ class="selectorPod"
/>
</div>
<div class="selectors-item" v-if="states.key === 2">
@@ -84,9 +84,10 @@ limitations under the License. -->
</template>
<script lang="ts" setup>
-import { reactive } from "vue";
+import { reactive, watch } from "vue";
import { useRoute } from "vue-router";
import { useDashboardStore } from "@/store/modules/dashboard";
+import { useAppStoreWithOut } from "@/store/modules/app";
import { EntityType, ToolIcons } from "../data";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
@@ -95,6 +96,7 @@ import { Service } from "@/types/selector";
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
+const appStore = useAppStoreWithOut();
const params = useRoute().params;
const type = EntityType.filter((d: Option) => d.value === params.entity)[0];
const states = reactive<{
@@ -114,10 +116,14 @@ const states = reactive<{
dashboardStore.setLayer(String(params.layerId));
dashboardStore.setEntity(String(params.entity));
-if (params.serviceId) {
- setSelector();
-} else {
- getServices();
+initSelector();
+
+function initSelector() {
+ if (params.serviceId) {
+ setSelector();
+ } else {
+ getServices();
+ }
}
async function setSelector() {
@@ -149,6 +155,9 @@ async function getServices() {
if (!dashboardStore.layerId) {
return;
}
+ if (dashboardStore.entity === EntityType[1].value) {
+ return;
+ }
const json = await selectorStore.fetchServices(dashboardStore.layerId);
if (json.errors) {
ElMessage.error(json.errors);
@@ -173,7 +182,7 @@ async function changeService(service: Service[]) {
function changePods(pod: Option[]) {
if (pod[0]) {
- selectorStore.setCurrentPod(pod[0].value);
+ selectorStore.setCurrentPod(pod[0]);
} else {
selectorStore.setCurrentPod("");
}
@@ -227,6 +236,12 @@ async function fetchPods(type: string, setPod: boolean) {
return;
}
}
+watch(
+ () => appStore.durationTime,
+ () => {
+ initSelector();
+ }
+);
</script>
<style lang="scss" scoped>
.dashboard-tool {
@@ -260,10 +275,14 @@ async function fetchPods(type: string, setPod: boolean) {
}
.selectors {
- min-width: 180px;
+ min-width: 200px;
}
.selectors-item {
margin-right: 5px;
}
+
+.selectorPod {
+ width: 340px;
+}
</style>
diff --git a/src/views/service/Panel.vue b/src/views/service/Panel.vue
index 1febb4c..bb51cc4 100644
--- a/src/views/service/Panel.vue
+++ b/src/views/service/Panel.vue
@@ -50,7 +50,10 @@ import Endpoints from "./Endpoints.vue";
import Topology from "./Topology.vue";
import Traces from "./Traces.vue";
import Profiles from "./Profiles.vue";
+import { useAppStoreWithOut } from "@/store/modules/app";
+const appStore = useAppStoreWithOut();
+appStore.setPageTitle("General Service");
const route = useRoute();
const { t } = useI18n();
const tabs = ["metrics", "topologies", "endpoints", "traces", "profiles"];
@@ -69,30 +72,36 @@ function handleClick(tab: string) {
.service-detail {
text-align: left;
}
+
.tabs {
padding: 15px 15px 0 15px;
border-bottom: 1px solid var(--el-border-color-light);
}
+
.tab {
display: inline-block;
margin-right: 30px;
font-size: 13px;
font-weight: 400;
height: 30px;
+
&:hover {
color: var(--el-color-primary);
}
+
&.active {
color: var(--el-color-primary);
border-bottom: 1px solid var(--el-color-primary);
}
}
+
.title {
padding: 5px 0 5px 15px;
font-size: 14px;
font-weight: 400;
border-bottom: 1px solid #dfe4e8;
background-color: #c4c8e133;
+
span {
display: inline-block;
margin-right: 10px;