This is an automated email from the ASF dual-hosted git repository.

wusheng 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 61f82c5  feat:  Add menus in side bar (#30)
61f82c5 is described below

commit 61f82c54dfc868f92186f93d954f4868d2e863c9
Author: Fine0830 <[email protected]>
AuthorDate: Mon Mar 21 15:36:56 2022 +0800

    feat:  Add menus in side bar (#30)
---
 src/assets/icons/cloud_queue.svg                   |  17 ++++
 src/assets/icons/language.svg                      |  17 ++++
 src/assets/icons/linear_scale.svg                  |  17 ++++
 src/components/Selector.vue                        |  13 ++-
 src/hooks/useProcessor.ts                          |   2 +-
 src/layout/components/SideBar.vue                  |  39 ++++++--
 src/locales/lang/en.ts                             |   6 ++
 src/locales/lang/zh.ts                             |   6 ++
 src/router/{database.ts => browser.ts}             |  18 ++--
 src/router/database.ts                             |   2 +-
 src/router/{database.ts => functions.ts}           |  18 ++--
 src/router/index.ts                                |   8 +-
 src/router/infrastructure.ts                       |  34 ++++---
 .../{serviceMesh.ts => selfObservability.ts}       |  31 +++---
 src/router/serviceMesh.ts                          |   2 +-
 src/views/Layer.vue                                |  20 ++++
 src/views/dashboard/List.vue                       |   2 +-
 .../configuration/widget/MetricOptions.vue         |  28 ++----
 .../related/topology/components/Graph.vue          |  18 +++-
 .../related/topology/components/PodTopology.vue    |   4 +-
 .../related/topology/components/Settings.vue       | 106 ++++++++++++++-------
 21 files changed, 276 insertions(+), 132 deletions(-)

diff --git a/src/assets/icons/cloud_queue.svg b/src/assets/icons/cloud_queue.svg
new file mode 100644
index 0000000..4b1da73
--- /dev/null
+++ b/src/assets/icons/cloud_queue.svg
@@ -0,0 +1,17 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"; width="24" height="24" 
viewBox="0 0 24 24">
+<path d="M18.984 18q1.219 0 
2.109-0.891t0.891-2.109-0.891-2.109-2.109-0.891h-1.5v-0.516q0-2.297-1.594-3.891t-3.891-1.594q-1.875
 0-3.328 1.125t-1.969 2.859h-0.703q-1.641 0-2.813 1.195t-1.172 2.836 1.172 
2.813 2.813 1.172h12.984zM19.359 10.031q1.922 0.141 3.281 1.57t1.359 3.398q0 
2.063-1.477 3.539t-3.539 1.477h-12.984q-2.484 
0-4.242-1.758t-1.758-4.242q0-2.203 1.57-3.961t3.773-1.992q0.984-1.828 
2.766-2.953t3.891-1.125q2.531 0 4.711 1.781t2.648 4.266z"></path>
+</svg>
diff --git a/src/assets/icons/language.svg b/src/assets/icons/language.svg
new file mode 100644
index 0000000..eab0146
--- /dev/null
+++ b/src/assets/icons/language.svg
@@ -0,0 +1,17 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"; width="24" height="24" 
viewBox="0 0 24 24">
+<path d="M16.359 14.016h3.375q0.281-1.313 
0.281-2.016t-0.281-2.016h-3.375q0.141 0.984 0.141 2.016t-0.141 2.016zM14.578 
19.547q1.172-0.375 2.438-1.43t1.922-2.133h-2.953q-0.469 1.875-1.406 
3.563zM14.344 14.016q0.141-0.984 0.141-2.016t-0.141-2.016h-4.688q-0.141 
0.984-0.141 2.016t0.141 2.016h4.688zM12 19.969q1.313-1.922 
1.922-3.984h-3.844q0.609 2.063 1.922 3.984zM8.016 8.016q0.563-2.016 
1.406-3.563-1.172 0.375-2.461 1.43t-1.898 2.133h2.953zM5.063 15.984q0.609 1.078 
1.898 2.133t2.461 1.43q-0. [...]
+</svg>
diff --git a/src/assets/icons/linear_scale.svg 
b/src/assets/icons/linear_scale.svg
new file mode 100644
index 0000000..6b73974
--- /dev/null
+++ b/src/assets/icons/linear_scale.svg
@@ -0,0 +1,17 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"; width="24" height="24" 
viewBox="0 0 24 24">
+<path d="M19.5 9.516q1.031 0 1.758 0.727t0.727 1.758-0.727 1.758-1.758 
0.727q-1.688 0-2.297-1.5h-2.906q-0.609 1.5-2.297 1.5t-2.297-1.5h-2.906q-0.609 
1.5-2.297 1.5-1.031 0-1.758-0.727t-0.727-1.758 0.727-1.758 1.758-0.727q1.688 0 
2.297 1.5h2.906q0.609-1.5 2.297-1.5t2.297 1.5h2.906q0.609-1.5 
2.297-1.5z"></path>
+</svg>
diff --git a/src/components/Selector.vue b/src/components/Selector.vue
index c40867e..b6dd34c 100644
--- a/src/components/Selector.vue
+++ b/src/components/Selector.vue
@@ -37,8 +37,8 @@ import { ref, watch } from "vue";
 import type { PropType } from "vue";
 
 interface Option {
-  label: string;
-  value: string;
+  label: string | number;
+  value: string | number;
 }
 
 /*global  defineProps, defineEmits*/
@@ -49,11 +49,14 @@ const props = defineProps({
     default: () => [],
   },
   value: {
-    type: [Array, String, Number] as PropType<any>,
+    type: [Array, String, Number, undefined] as PropType<any>,
     default: () => [],
   },
   size: { type: null, default: "default" },
-  placeholder: { type: String, default: "Select a option" },
+  placeholder: {
+    type: [String, Number] as PropType<string | number>,
+    default: "Select a option",
+  },
   borderRadius: { type: Number, default: 3 },
   multiple: { type: Boolean, default: false },
   disabled: { type: Boolean, default: false },
@@ -61,7 +64,7 @@ const props = defineProps({
 
 const selected = ref<string[] | string>(props.value);
 function changeSelected() {
-  const options = props.options.filter((d: Option) =>
+  const options = props.options.filter((d: any) =>
     props.multiple
       ? selected.value.includes(d.value)
       : selected.value === d.value
diff --git a/src/hooks/useProcessor.ts b/src/hooks/useProcessor.ts
index 6d5560d..bd6632c 100644
--- a/src/hooks/useProcessor.ts
+++ b/src/hooks/useProcessor.ts
@@ -57,7 +57,7 @@ export function useQueryProcessor(config: any) {
       variables.push(`$condition${index}: TopNCondition!`);
       conditions[`condition${index}`] = {
         name,
-        parentService: ["Service", "All"].includes(dashboardStore.entity)
+        parentService: ["All"].includes(dashboardStore.entity)
           ? null
           : selectorStore.currentService.value,
         normal: selectorStore.currentService.normal,
diff --git a/src/layout/components/SideBar.vue 
b/src/layout/components/SideBar.vue
index f5b49b0..31da52c 100644
--- a/src/layout/components/SideBar.vue
+++ b/src/layout/components/SideBar.vue
@@ -33,13 +33,17 @@ limitations under the License. -->
       <template v-for="(menu, index) in routes" :key="index">
         <el-sub-menu :index="String(menu.name)" v-if="menu.meta.hasGroup">
           <template #title>
-            <router-link :to="menu.path" :exact="menu.meta.exact || false">
+            <router-link
+              class="items"
+              :to="menu.path"
+              :exact="menu.meta.exact || false"
+            >
               <el-icon class="menu-icons" :style="{ marginRight: '12px' }">
                 <Icon size="lg" :iconName="menu.meta.icon" />
               </el-icon>
-              <span :class="isCollapse ? 'collapse' : ''">{{
-                t(menu.meta.title)
-              }}</span>
+              <span :class="isCollapse ? 'collapse' : ''">
+                {{ t(menu.meta.title) }}
+              </span>
             </router-link>
           </template>
           <el-menu-item-group>
@@ -48,7 +52,11 @@ limitations under the License. -->
               :index="m.name"
               :key="idx"
             >
-              <router-link :to="m.path" :exact="m.meta.exact || false">
+              <router-link
+                class="items"
+                :to="m.path"
+                :exact="m.meta.exact || false"
+              >
                 <span>{{ t(m.meta.title) }}</span>
               </router-link>
             </el-menu-item>
@@ -59,13 +67,21 @@ limitations under the License. -->
           @click="changePage(menu)"
           v-else
         >
-          <el-icon class="menu-icons" :style="{ margin: '-10px 12px 0 0' }">
-            <router-link :to="menu.children[0].path" :exact="menu.meta.exact">
+          <el-icon class="menu-icons" :style="{ marginRight: '12px' }">
+            <router-link
+              class="items"
+              :to="menu.children[0].path"
+              :exact="menu.meta.exact"
+            >
               <Icon size="lg" :iconName="menu.meta.icon" />
             </router-link>
           </el-icon>
           <template #title>
-            <router-link :to="menu.children[0].path" :exact="menu.meta.exact">
+            <router-link
+              class="items"
+              :to="menu.children[0].path"
+              :exact="menu.meta.exact"
+            >
               <span>{{ t(menu.meta.title) }}</span>
             </router-link>
           </template>
@@ -99,7 +115,7 @@ const theme = ["VirtualMachine", 
"Kubernetes"].includes(name.value || "")
   ? ref("light")
   : ref("black");
 const routes = ref<any>(useRouter().options.routes);
-const isCollapse = ref(true);
+const isCollapse = ref(false);
 const controlMenu = () => {
   isCollapse.value = !isCollapse.value;
 };
@@ -172,4 +188,9 @@ span.collapse {
 .el-icon.el-sub-menu__icon-arrow {
   height: 12px;
 }
+
+.items {
+  display: inline-block;
+  width: 100%;
+}
 </style>
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 56a8dc2..a955a01 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -113,6 +113,12 @@ const msg = {
   noRoot: "Please set a root dashboard for",
   noWidget: "Please add widgets.",
   rename: "Rename",
+  selfObservability: "Self Observability",
+  satellite: "Satellite",
+  skyWalkingServer: "Sky Walking Server",
+  functions: "Functions",
+  browser: "Browser",
+  linux: "Linux",
   hourTip: "Select Hour",
   minuteTip: "Select Minute",
   secondTip: "Select Second",
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 3cec3c1..62bc7bf 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -113,6 +113,12 @@ const msg = {
   showGroup: "显示分组",
   noWidget: "请添加组件",
   rename: "重命名",
+  selfObservability: "自观性",
+  satellite: "Satellite",
+  skyWalkingServer: "Sky Walking服务",
+  functions: "Functions",
+  linux: "Linux",
+  browser: "浏览器",
   hourTip: "选择小时",
   minuteTip: "选择分钟",
   secondTip: "选择秒数",
diff --git a/src/router/database.ts b/src/router/browser.ts
similarity index 80%
copy from src/router/database.ts
copy to src/router/browser.ts
index 199cbc1..1906813 100644
--- a/src/router/database.ts
+++ b/src/router/browser.ts
@@ -17,23 +17,23 @@
 import { RouteRecordRaw } from "vue-router";
 import Layout from "@/layout/Index.vue";
 
-export const routesDatabase: Array<RouteRecordRaw> = [
+export const routesBrowser: Array<RouteRecordRaw> = [
   {
     path: "",
-    name: "Database",
+    name: "Browser",
     meta: {
-      title: "database",
-      icon: "epic",
+      title: "browser",
+      icon: "language",
     },
-    redirect: "/database",
+    redirect: "/browser",
     component: Layout,
     children: [
       {
-        path: "/database",
-        name: "Database",
+        path: "/browser",
+        name: "Browser",
         meta: {
-          title: "database",
-          headPath: "/database",
+          title: "browser",
+          headPath: "/browser",
           exact: true,
         },
         component: () => import("@/views/Layer.vue"),
diff --git a/src/router/database.ts b/src/router/database.ts
index 199cbc1..ce56697 100644
--- a/src/router/database.ts
+++ b/src/router/database.ts
@@ -23,7 +23,7 @@ export const routesDatabase: Array<RouteRecordRaw> = [
     name: "Database",
     meta: {
       title: "database",
-      icon: "epic",
+      icon: "bar_chart",
     },
     redirect: "/database",
     component: Layout,
diff --git a/src/router/database.ts b/src/router/functions.ts
similarity index 79%
copy from src/router/database.ts
copy to src/router/functions.ts
index 199cbc1..7ae9bed 100644
--- a/src/router/database.ts
+++ b/src/router/functions.ts
@@ -17,23 +17,23 @@
 import { RouteRecordRaw } from "vue-router";
 import Layout from "@/layout/Index.vue";
 
-export const routesDatabase: Array<RouteRecordRaw> = [
+export const routesFunctions: Array<RouteRecordRaw> = [
   {
     path: "",
-    name: "Database",
+    name: "Functions",
     meta: {
-      title: "database",
-      icon: "epic",
+      title: "functions",
+      icon: "cloud_queue",
     },
-    redirect: "/database",
+    redirect: "/functions",
     component: Layout,
     children: [
       {
-        path: "/database",
-        name: "Database",
+        path: "/functions",
+        name: "Functions",
         meta: {
-          title: "database",
-          headPath: "/database",
+          title: "functions",
+          headPath: "/functions",
           exact: true,
         },
         component: () => import("@/views/Layer.vue"),
diff --git a/src/router/index.ts b/src/router/index.ts
index 4d4c2fc..2102c00 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -23,12 +23,18 @@ import { routesDashboard } from "./dashboard";
 import { routesEvent } from "./event";
 import { routesSetting } from "./setting";
 import { routesAlarm } from "./alarm";
+import { routesSelf } from "./selfObservability";
+import { routesFunctions } from "./functions";
+import { routesBrowser } from "./browser";
 
 const routes: Array<RouteRecordRaw> = [
   ...routesGen,
   ...routesMesh,
-  ...routesDatabase,
+  ...routesFunctions,
   ...routesInfra,
+  ...routesBrowser,
+  ...routesDatabase,
+  ...routesSelf,
   ...routesDashboard,
   ...routesAlarm,
   ...routesEvent,
diff --git a/src/router/infrastructure.ts b/src/router/infrastructure.ts
index 6ec33f2..2450e82 100644
--- a/src/router/infrastructure.ts
+++ b/src/router/infrastructure.ts
@@ -27,24 +27,34 @@ export const routesInfra: Array<RouteRecordRaw> = [
       exact: true,
       hasGroup: true,
     },
+    redirect: "/infrastructure",
     component: Layout,
     children: [
       {
-        path: "/infrastructure/vm",
-        name: "VirtualMachine",
+        path: "/infrastructure",
+        name: "Linux",
         meta: {
-          title: "virtualMachine",
+          title: "linux",
         },
-        component: () => import("@/views/infrastructure/Infrastructure.vue"),
-      },
-      {
-        path: "/infrastructure/k8s",
-        name: "Kubernetes",
-        meta: {
-          title: "kubernetes",
-        },
-        component: () => import("@/views/infrastructure/Infrastructure.vue"),
+        component: () => import("@/views/Layer.vue"),
+        // component: () => 
import("@/views/infrastructure/Infrastructure.vue"),
       },
+      // {
+      //   path: "/infrastructure/vm",
+      //   name: "VirtualMachine",
+      //   meta: {
+      //     title: "virtualMachine",
+      //   },
+      //   component: () => 
import("@/views/infrastructure/Infrastructure.vue"),
+      // },
+      // {
+      //   path: "/infrastructure/k8s",
+      //   name: "Kubernetes",
+      //   meta: {
+      //     title: "kubernetes",
+      //   },
+      //   component: () => 
import("@/views/infrastructure/Infrastructure.vue"),
+      // },
     ],
   },
 ];
diff --git a/src/router/serviceMesh.ts b/src/router/selfObservability.ts
similarity index 68%
copy from src/router/serviceMesh.ts
copy to src/router/selfObservability.ts
index d0f1480..1cf3936 100644
--- a/src/router/serviceMesh.ts
+++ b/src/router/selfObservability.ts
@@ -17,45 +17,36 @@
 import { RouteRecordRaw } from "vue-router";
 import Layout from "@/layout/Index.vue";
 
-export const routesMesh: Array<RouteRecordRaw> = [
+export const routesSelf: Array<RouteRecordRaw> = [
   {
     path: "",
-    name: "ServiceMesh",
-    redirect: "/mesh/services",
+    name: "SelfObservability",
+    redirect: "/self/skyWalkingServer",
     meta: {
-      title: "serviceMesh",
-      icon: "bar_chart",
+      title: "selfObservability",
+      icon: "logo",
       hasGroup: true,
     },
     component: Layout,
     children: [
       {
-        path: "/mesh/services",
-        name: "MeshServices",
+        path: "/self/skyWalkingServer",
+        name: "SkyWalkingServer",
         meta: {
-          title: "services",
+          title: "skyWalkingServer",
           headPath: "/mesh/services",
         },
         component: () => import("@/views/Layer.vue"),
       },
       {
-        path: "/mesh/controlPanel",
-        name: "ControlPanel",
+        path: "/self/satellite",
+        name: "Satellite",
         meta: {
-          title: "controlPanel",
+          title: "satellite",
           headPath: "/mesh/controlPanel",
         },
         component: () => import("@/views/Layer.vue"),
       },
-      {
-        path: "/mesh/dataPanel",
-        name: "DataPanel",
-        meta: {
-          title: "dataPanel",
-          headPath: "/mesh/dataPanel",
-        },
-        component: () => import("@/views/Layer.vue"),
-      },
     ],
   },
 ];
diff --git a/src/router/serviceMesh.ts b/src/router/serviceMesh.ts
index d0f1480..946f1d1 100644
--- a/src/router/serviceMesh.ts
+++ b/src/router/serviceMesh.ts
@@ -24,7 +24,7 @@ export const routesMesh: Array<RouteRecordRaw> = [
     redirect: "/mesh/services",
     meta: {
       title: "serviceMesh",
-      icon: "bar_chart",
+      icon: "epic",
       hasGroup: true,
     },
     component: Layout,
diff --git a/src/views/Layer.vue b/src/views/Layer.vue
index 7e43f14..ed1f418 100644
--- a/src/views/Layer.vue
+++ b/src/views/Layer.vue
@@ -34,6 +34,11 @@ const routeNames = [
   "MeshServices",
   "ControlPanel",
   "DataPanel",
+  "Linux",
+  "SkyWalkingServer",
+  "Satellite",
+  "Functions",
+  "Browser",
 ];
 const layer = ref<string>("GENERAL");
 getDashboard();
@@ -69,6 +74,21 @@ function setLayer(n: string) {
     case routeNames[4]:
       layer.value = "MESH_DP";
       break;
+    case routeNames[5]:
+      layer.value = "OS_LINUX";
+      break;
+    case routeNames[6]:
+      layer.value = "SO11Y_OAP";
+      break;
+    case routeNames[7]:
+      layer.value = "SO11Y_SATELLITE";
+      break;
+    case routeNames[8]:
+      layer.value = "FAAS";
+      break;
+    case routeNames[9]:
+      layer.value = "BROWSER";
+      break;
     default:
       layer.value = "GENERAL";
       break;
diff --git a/src/views/dashboard/List.vue b/src/views/dashboard/List.vue
index 8760849..df462af 100644
--- a/src/views/dashboard/List.vue
+++ b/src/views/dashboard/List.vue
@@ -57,7 +57,7 @@ limitations under the License. -->
         <el-table-column label="Operations">
           <template #default="scope">
             <el-button size="small" @click="handleView(scope.row)">
-              {{ t("view") }}
+              {{ t("edit") }}
             </el-button>
             <el-button size="small" @click="handleEdit(scope.row)">
               {{ t("rename") }}
diff --git a/src/views/dashboard/configuration/widget/MetricOptions.vue 
b/src/views/dashboard/configuration/widget/MetricOptions.vue
index 8682dae..d41a402 100644
--- a/src/views/dashboard/configuration/widget/MetricOptions.vue
+++ b/src/views/dashboard/configuration/widget/MetricOptions.vue
@@ -90,12 +90,11 @@ import { useDashboardStore } from 
"@/store/modules/dashboard";
 import {
   MetricTypes,
   ListChartTypes,
-  MetricCatalog,
   DefaultGraphConfig,
   EntityType,
   ChartTypes,
   PodsChartTypes,
-  ListEntity,
+  MetricsType,
 } from "../../data";
 import { ElMessage } from "element-plus";
 import Icon from "@/components/Icon.vue";
@@ -134,13 +133,8 @@ states.visTypes = setVisTypes();
 setDashboards();
 setMetricType();
 
-async function setMetricType(catalog?: string) {
+async function setMetricType() {
   const { graph } = dashboardStore.selectedGrid;
-  if (states.isList) {
-    catalog = catalog || ListEntity[graph.type];
-  } else {
-    catalog = catalog || dashboardStore.entity;
-  }
   const json = await dashboardStore.fetchMetricList();
   if (json.errors) {
     ElMessage.error(json.errors);
@@ -149,16 +143,11 @@ async function setMetricType(catalog?: string) {
   states.metricList = (json.data.metrics || []).filter(
     (d: { catalog: string; type: string }) => {
       if (states.isList || graph.type === "Table") {
-        if (
-          d.type === "REGULAR_VALUE" &&
-          catalog === (MetricCatalog as any)[d.catalog]
-        ) {
+        if (d.type === MetricsType.REGULAR_VALUE) {
           return d;
         }
       } else {
-        if (catalog === (MetricCatalog as any)[d.catalog]) {
-          return d;
-        }
+        return d;
       }
     }
   );
@@ -253,12 +242,7 @@ function changeChartType(item: Option) {
     states.metrics = [""];
     states.metricTypes = [""];
   }
-  const catalog: { [key: string]: string } = {
-    InstanceList: EntityType[3].value,
-    EndpointList: EntityType[2].value,
-    ServiceList: EntityType[0].value,
-  };
-  setMetricType(catalog[graph.type]);
+  setMetricType();
   setDashboards();
   states.dashboardName = "";
 }
@@ -367,7 +351,7 @@ function deleteMetric(index: number) {
   states.metricTypes.splice(index, 1);
 }
 function setMetricTypeList(type: string) {
-  if (type !== "REGULAR_VALUE") {
+  if (type !== MetricsType.REGULAR_VALUE) {
     return MetricTypes[type];
   }
   if (states.isList || dashboardStore.selectedGrid.graph.type === "Table") {
diff --git a/src/views/dashboard/related/topology/components/Graph.vue 
b/src/views/dashboard/related/topology/components/Graph.vue
index 2058640..f67be5e 100644
--- a/src/views/dashboard/related/topology/components/Graph.vue
+++ b/src/views/dashboard/related/topology/components/Graph.vue
@@ -213,7 +213,7 @@ function handleNodeClick(d: Node & { x: number; y: number 
}) {
   topologyStore.setNode(d);
   topologyStore.setLink(null);
   operationsPos.x = d.x;
-  operationsPos.y = d.y + 30;
+  operationsPos.y = d.y - 70;
   if (d.layer === String(dashboardStore.layerId)) {
     return;
   }
@@ -239,7 +239,9 @@ function handleLinkClick(event: any, d: Call) {
     dashboardStore.entity === EntityType[1].value
       ? EntityType[0].value
       : dashboardStore.entity;
-  const path = 
`/dashboard/${dashboardStore.layerId}/${e}Relation/${d.source.id}/${d.target.id}/${settings.value.linkDashboard}`;
+  const path = `/dashboard/${dashboardStore.layerId}/${e}Relation/${
+    d.source.id
+  }/${d.target.id}/${settings.value.linkDashboard.split(" ").join("-")}`;
   const routeUrl = router.resolve({ path });
   window.open(routeUrl.href, "_blank");
 }
@@ -371,19 +373,25 @@ async function handleInspect() {
   update();
 }
 function handleGoEndpoint(name: string) {
-  const path = 
`/dashboard/${dashboardStore.layerId}/Endpoint/${topologyStore.node.id}/${name}`;
+  const path = `/dashboard/${dashboardStore.layerId}/Endpoint/${
+    topologyStore.node.id
+  }/${name.split(" ").join("-")}`;
   const routeUrl = router.resolve({ path });
 
   window.open(routeUrl.href, "_blank");
 }
 function handleGoInstance(name: string) {
-  const path = 
`/dashboard/${dashboardStore.layerId}/ServiceInstance/${topologyStore.node.id}/${name}`;
+  const path = `/dashboard/${dashboardStore.layerId}/ServiceInstance/${
+    topologyStore.node.id
+  }/${name.split(" ").join("-")}`;
   const routeUrl = router.resolve({ path });
 
   window.open(routeUrl.href, "_blank");
 }
 function handleGoDashboard(name: string) {
-  const path = 
`/dashboard/${dashboardStore.layerId}/Service/${topologyStore.node.id}/${name}`;
+  const path = `/dashboard/${dashboardStore.layerId}/Service/${
+    topologyStore.node.id
+  }/${name.split(" ").join("-")}`;
   const routeUrl = router.resolve({ path });
 
   window.open(routeUrl.href, "_blank");
diff --git a/src/views/dashboard/related/topology/components/PodTopology.vue 
b/src/views/dashboard/related/topology/components/PodTopology.vue
index e9a36bc..045f17f 100644
--- a/src/views/dashboard/related/topology/components/PodTopology.vue
+++ b/src/views/dashboard/related/topology/components/PodTopology.vue
@@ -189,8 +189,8 @@ function selectNodeLink(d: any) {
   }
   topologyStore.setNode(d.data);
   topologyStore.setLink(null);
-  operationsPos.x = d.event.event.clientX;
-  operationsPos.y = d.event.event.clientY;
+  operationsPos.x = d.event.event.clientX - 200;
+  operationsPos.y = d.event.event.clientY - 150;
 }
 
 async function changeDepth(opt: Option[] | any) {
diff --git a/src/views/dashboard/related/topology/components/Settings.vue 
b/src/views/dashboard/related/topology/components/Settings.vue
index c99eeb5..3d5e658 100644
--- a/src/views/dashboard/related/topology/components/Settings.vue
+++ b/src/views/dashboard/related/topology/components/Settings.vue
@@ -16,11 +16,12 @@ limitations under the License. -->
   <div class="link-settings">
     <h5 class="title">{{ t("callSettings") }}</h5>
     <div class="label">{{ t("linkDashboard") }}</div>
-    <el-input
-      v-model="states.linkDashboard"
-      placeholder="Please input a dashboard name for calls"
-      @change="updateSettings"
+    <Selector
+      :value="states.linkDashboard"
+      :options="states.linkDashboards"
       size="small"
+      placeholder="Please input a dashboard name for calls"
+      @change="changeLinkDashboard"
       class="inputs"
     />
     <div class="label">{{ t("linkServerMetrics") }}</div>
@@ -51,16 +52,17 @@ limitations under the License. -->
   <div class="node-settings">
     <h5 class="title">{{ t("nodeSettings") }}</h5>
     <div class="label">{{ t("nodeDashboard") }}</div>
-    <el-input
-      v-show="!isServer"
-      v-model="states.nodeDashboard"
-      placeholder="Please input a dashboard name for nodes"
-      @change="updateSettings"
+    <Selector
+      v-show="!isService"
+      :value="states.nodeDashboard"
+      :options="states.nodeDashboards"
       size="small"
+      placeholder="Please input a dashboard name for nodes"
+      @change="changeNodeDashboard"
       class="inputs"
     />
     <div
-      v-show="isServer"
+      v-show="isService"
       v-for="(item, index) in items"
       :key="index"
       class="metric-item"
@@ -73,11 +75,12 @@ limitations under the License. -->
         @change="changeScope(index, $event)"
         class="item mr-5"
       />
-      <el-input
-        v-model="item.dashboard"
+      <Selector
+        :value="item.dashboard"
+        :options="states.nodeDashboards"
+        size="small"
         placeholder="Please input a dashboard name for nodes"
         @change="updateNodeDashboards(index, $event)"
-        size="small"
         class="item mr-5"
       />
       <span>
@@ -108,7 +111,7 @@ limitations under the License. -->
       @change="changeNodeMetrics"
     />
   </div>
-  <div class="legend-settings" v-show="isServer">
+  <div class="legend-settings" v-show="isService">
     <h5 class="title">{{ t("legendSettings") }}</h5>
     <div class="label">{{ t("conditions") }}</div>
     <div v-for="(metric, index) of legend.metric" :key="metric.name + index">
@@ -184,7 +187,8 @@ import { MetricCatalog, ScopeType, MetricConditions } from 
"../../../data";
 import { Option } from "@/types/app";
 import { useQueryTopologyMetrics } from "@/hooks/useProcessor";
 import { Node, Call } from "@/types/topology";
-import { EntityType, LegendOpt } from "../../../data";
+import { DashboardItem } from "@/types/dashboard";
+import { EntityType, LegendOpt, MetricsType } from "../../../data";
 
 /*global defineEmits */
 const emit = defineEmits(["update", "updateNodes"]);
@@ -208,6 +212,8 @@ const states = reactive<{
   nodeMetrics: string[];
   nodeMetricList: Option[];
   linkMetricList: Option[];
+  linkDashboards: (DashboardItem & { label: string; value: string })[];
+  nodeDashboards: (DashboardItem & { label: string; value: string })[];
 }>({
   linkDashboard: "",
   nodeDashboard: [],
@@ -216,8 +222,10 @@ const states = reactive<{
   nodeMetrics: [],
   nodeMetricList: [],
   linkMetricList: [],
+  linkDashboards: [],
+  nodeDashboards: [],
 });
-const isServer = [EntityType[0].value, EntityType[1].value].includes(
+const isService = [EntityType[0].value, EntityType[1].value].includes(
   dashboardStore.entity
 );
 const legend = reactive<{
@@ -226,6 +234,7 @@ const legend = reactive<{
 
 getMetricList();
 async function getMetricList() {
+  const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
   const json = await dashboardStore.fetchMetricList();
   if (json.errors) {
     ElMessage.error(json.errors);
@@ -237,18 +246,28 @@ async function getMetricList() {
       : dashboardStore.entity === EntityType[4].value
       ? EntityType[3].value
       : dashboardStore.entity;
+  states.linkDashboards = list.reduce(
+    (
+      prev: (DashboardItem & { label: string; value: string })[],
+      d: DashboardItem
+    ) => {
+      if (
+        d.layer === dashboardStore.layerId &&
+        d.entity === entity + "Relation"
+      ) {
+        prev.push({ ...d, label: d.name, value: d.name });
+      }
+      return prev;
+    },
+    []
+  );
   states.nodeMetricList = (json.data.metrics || []).filter(
-    (d: { catalog: string }) => entity === (MetricCatalog as any)[d.catalog]
+    (d: { type: string }) => d.type === MetricsType.REGULAR_VALUE
   );
-  const e =
-    dashboardStore.entity === EntityType[1].value
-      ? EntityType[0].value
-      : dashboardStore.entity === EntityType[4].value
-      ? EntityType[3].value
-      : dashboardStore.entity;
   states.linkMetricList = (json.data.metrics || []).filter(
-    (d: { catalog: string }) =>
-      e + "Relation" === (MetricCatalog as any)[d.catalog]
+    (d: { catalog: string; type: string }) =>
+      entity + "Relation" === (MetricCatalog as any)[d.catalog] &&
+      d.type === MetricsType.REGULAR_VALUE
   );
 }
 async function setLegend() {
@@ -259,7 +278,7 @@ async function setLegend() {
 
   emit("update", {
     linkDashboard: states.linkDashboard,
-    nodeDashboard: isServer
+    nodeDashboard: isService
       ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
       : states.nodeDashboard,
     linkServerMetrics: states.linkServerMetrics,
@@ -276,15 +295,34 @@ async function setLegend() {
   }
   emit("updateNodes");
 }
+function changeNodeDashboard(opt: any) {
+  states.nodeDashboard = opt[0].value;
+}
+function changeLinkDashboard(opt: any) {
+  states.linkDashboard = opt[0].value;
+}
 function changeLegend(type: string, opt: any, index: number) {
   (legend.metric[index] as any)[type] = opt[0].value || opt;
 }
-function changeScope(index: number, opt: Option[]) {
+function changeScope(index: number, opt: Option[] | any) {
   items[index].scope = opt[0].value;
-  items[index].dashboard = "";
+  const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
+  states.nodeDashboards = list.reduce(
+    (
+      prev: (DashboardItem & { label: string; value: string })[],
+      d: DashboardItem
+    ) => {
+      if (d.layer === dashboardStore.layerId && d.entity === opt[0].value) {
+        prev.push({ ...d, label: d.name, value: d.name });
+      }
+      return prev;
+    },
+    []
+  );
+  items[index].dashboard = states.nodeDashboards[0].value;
 }
-function updateNodeDashboards(index: number, content: string) {
-  items[index].dashboard = content;
+function updateNodeDashboards(index: number, content: Option[] | any) {
+  items[index].dashboard = content[0].value;
   updateSettings();
 }
 function addItem() {
@@ -297,7 +335,7 @@ function deleteItem(index: number) {
 function updateSettings() {
   emit("update", {
     linkDashboard: states.linkDashboard,
-    nodeDashboard: isServer
+    nodeDashboard: isService
       ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
       : states.nodeDashboard,
     linkServerMetrics: states.linkServerMetrics,
@@ -306,7 +344,7 @@ function updateSettings() {
     legend: legend.metric,
   });
 }
-async function changeLinkServerMetrics(options: Option[]) {
+async function changeLinkServerMetrics(options: Option[] | any) {
   states.linkServerMetrics = options.map((d: Option) => d.value);
   updateSettings();
   if (!states.linkServerMetrics.length) {
@@ -323,7 +361,7 @@ async function changeLinkServerMetrics(options: Option[]) {
     ElMessage.error(res.errors);
   }
 }
-async function changeLinkClientMetrics(options: Option[]) {
+async function changeLinkClientMetrics(options: Option[] | any) {
   states.linkClientMetrics = options.map((d: Option) => d.value);
   updateSettings();
   if (!states.linkClientMetrics.length) {
@@ -340,7 +378,7 @@ async function changeLinkClientMetrics(options: Option[]) {
     ElMessage.error(res.errors);
   }
 }
-async function changeNodeMetrics(options: Option[]) {
+async function changeNodeMetrics(options: Option[] | any) {
   states.nodeMetrics = options.map((d: Option) => d.value);
   updateSettings();
   if (!states.nodeMetrics.length) {

Reply via email to