You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2022/06/14 09:01:16 UTC

[skywalking-booster-ui] branch main updated: feat: set a url parameter to activate tab index (#107)

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 b697fe4  feat: set a url parameter to activate tab index (#107)
b697fe4 is described below

commit b697fe471352b9dfa1703191705e32329d592cc8
Author: Fine0830 <fi...@outlook.com>
AuthorDate: Tue Jun 14 17:01:11 2022 +0800

    feat: set a url parameter to activate tab index (#107)
---
 src/constants/data.ts                              |  11 ++
 src/layout/components/SideBar.vue                  |   4 +-
 src/router/browser.ts                              |  10 +-
 src/router/dashboard.ts                            | 119 ++++++++++++++++++---
 src/router/database.ts                             |  10 +-
 src/router/functions.ts                            |   8 +-
 src/router/general.ts                              |  11 +-
 src/router/infrastructure.ts                       |   9 ++
 src/router/k8s.ts                                  |  22 ++++
 src/router/selfObservability.ts                    |  20 +++-
 src/router/serviceMesh.ts                          |  37 ++++++-
 src/views/dashboard/controls/Tab.vue               |  38 ++++++-
 .../related/topology/components/Graph.vue          |   3 +
 13 files changed, 270 insertions(+), 32 deletions(-)

diff --git a/src/constants/data.ts b/src/constants/data.ts
index 5a8bf13..33779df 100644
--- a/src/constants/data.ts
+++ b/src/constants/data.ts
@@ -28,15 +28,26 @@ export const Languages = [
 
 export const RoutesMap: { [key: string]: string } = {
   GeneralServices: "GENERAL",
+  GeneralServicesActiveTabIndex: "GENERAL",
   Database: "VIRTUAL_DATABASE",
+  DatabaseActiveTabIndex: "VIRTUAL_DATABASE",
   MeshServices: "MESH",
+  MeshServicesActiveTabIndex: "MESH",
   ControlPanel: "MESH_CP",
+  ControlPanelActiveTabIndex: "MESH_CP",
   DataPanel: "MESH_DP",
+  DataPanelActiveTabIndex: "MESH_DP",
   Linux: "OS_LINUX",
   SkyWalkingServer: "SO11Y_OAP",
+  SkyWalkingServerActiveTabIndex: "SO11Y_OAP",
+  SatelliteActiveTabIndex: "SO11Y_SATELLITE",
   Satellite: "SO11Y_SATELLITE",
   Functions: "FAAS",
+  FunctionsActiveTabIndex: "FAAS",
   Browser: "BROWSER",
+  BrowserActiveTabIndex: "BROWSER",
   KubernetesCluster: "K8S",
+  KubernetesClusterActiveTabIndex: "K8S",
   KubernetesService: "K8S_SERVICE",
+  KubernetesServiceActiveTabIndex: "K8S_SERVICE",
 };
diff --git a/src/layout/components/SideBar.vue b/src/layout/components/SideBar.vue
index 34ad685..44392bc 100644
--- a/src/layout/components/SideBar.vue
+++ b/src/layout/components/SideBar.vue
@@ -55,9 +55,9 @@ limitations under the License. -->
               <router-link
                 class="items"
                 :to="m.path"
-                :exact="m.meta.exact || false"
+                :exact="(m.meta && m.meta.exact) || false"
               >
-                <span class="title">{{ t(m.meta.title) }}</span>
+                <span class="title">{{ m.meta && t(m.meta.title) }}</span>
               </router-link>
             </el-menu-item>
           </el-menu-item-group>
diff --git a/src/router/browser.ts b/src/router/browser.ts
index e0633bb..a7a4eb2 100644
--- a/src/router/browser.ts
+++ b/src/router/browser.ts
@@ -33,12 +33,20 @@ export const routesBrowser: Array<RouteRecordRaw> = [
         name: "Browser",
         meta: {
           title: "browser",
-          headPath: "/browser",
           exact: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/browser/tab/:activeTabIndex",
+        name: "BrowserActiveTabIndex",
+        meta: {
+          notShow: true,
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
     ],
   },
 ];
diff --git a/src/router/dashboard.ts b/src/router/dashboard.ts
index 93fc53a..c985e2f 100644
--- a/src/router/dashboard.ts
+++ b/src/router/dashboard.ts
@@ -54,69 +54,156 @@ export const routesDashboard: Array<RouteRecordRaw> = [
         },
       },
       {
-        path: "/dashboard/:layerId/:entity/:name",
+        path: "",
+        redirect: "/dashboard/:layerId/:entity/:name",
+        name: "Create",
         component: () =>
           import(
             /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
           ),
-        name: "Create",
         meta: {
-          title: "dashboardEdit",
-          exact: false,
           notShow: true,
         },
+        children: [
+          {
+            path: "/dashboard/:layerId/:entity/:name",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "CreateChild",
+          },
+          {
+            path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "CreateActiveTabIndex",
+          },
+        ],
       },
       {
-        path: "/dashboard/:layerId/:entity/:serviceId/:name",
+        path: "",
         component: () =>
           import(
             /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
           ),
         name: "View",
+        redirect: "/dashboard/:layerId/:entity/:serviceId/:name",
         meta: {
-          title: "dashboardEdit",
-          exact: false,
           notShow: true,
         },
+        children: [
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:name",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewChild",
+          },
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewActiveTabIndex",
+          },
+        ],
       },
       {
-        path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
+        path: "",
+        redirect:
+          "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
         component: () =>
           import(
             /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
           ),
         name: "ViewServiceRelation",
         meta: {
-          title: "dashboardEdit",
-          exact: false,
           notShow: true,
         },
+        children: [
+          {
+            path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewServiceRelation",
+          },
+          {
+            path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewServiceRelationActiveTabIndex",
+          },
+        ],
       },
       {
-        path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
+        path: "",
+        redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
         component: () =>
           import(
             /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
           ),
         name: "ViewPod",
         meta: {
-          title: "dashboardEdit",
-          exact: false,
           notShow: true,
         },
+        children: [
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewPod",
+          },
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewPodActiveTabIndex",
+          },
+        ],
       },
       {
-        path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
+        path: "",
+        redirect:
+          "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
         component: () =>
           import(
             /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
           ),
         name: "ViewPodRelation",
         meta: {
-          title: "dashboardEdit",
-          exact: true,
           notShow: true,
         },
+        children: [
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewPodRelation",
+          },
+          {
+            path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex",
+            component: () =>
+              import(
+                /* webpackChunkName: "dashboards" */ "@/views/dashboard/Edit.vue"
+              ),
+            name: "ViewPodRelationActiveTabIndex",
+          },
+        ],
       },
     ],
   },
diff --git a/src/router/database.ts b/src/router/database.ts
index 7dc0653..70b82b3 100644
--- a/src/router/database.ts
+++ b/src/router/database.ts
@@ -34,12 +34,20 @@ export const routesDatabase: Array<RouteRecordRaw> = [
         name: "Database",
         meta: {
           title: "virtualDatabase",
-          headPath: "/database",
           exact: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/database/tab/:activeTabIndex",
+        name: "DatabaseActiveTabIndex",
+        meta: {
+          notShow: true,
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
     ],
   },
 ];
diff --git a/src/router/functions.ts b/src/router/functions.ts
index be1fa33..ddafec9 100644
--- a/src/router/functions.ts
+++ b/src/router/functions.ts
@@ -32,13 +32,17 @@ export const routesFunctions: Array<RouteRecordRaw> = [
         path: "/functions",
         name: "Functions",
         meta: {
-          title: "functions",
-          headPath: "/functions",
           exact: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/functions/tab/:activeTabIndex",
+        name: "FunctionsActiveTabIndex",
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
     ],
   },
 ];
diff --git a/src/router/general.ts b/src/router/general.ts
index 393b94f..e9bb7b8 100644
--- a/src/router/general.ts
+++ b/src/router/general.ts
@@ -33,8 +33,15 @@ export const routesGen: Array<RouteRecordRaw> = [
         path: "/general",
         name: "GeneralServices",
         meta: {
-          title: "services",
-          headPath: "/general/service",
+          exact: true,
+        },
+        component: () =>
+          import(/* webpackChunkName: "layers" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/general/tab/:activeTabIndex",
+        name: "GeneralServicesActiveTabIndex",
+        meta: {
           exact: true,
         },
         component: () =>
diff --git a/src/router/infrastructure.ts b/src/router/infrastructure.ts
index 86bb55e..555953f 100644
--- a/src/router/infrastructure.ts
+++ b/src/router/infrastructure.ts
@@ -39,6 +39,15 @@ export const routesInfra: Array<RouteRecordRaw> = [
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/linux/tab/:activeTabIndex",
+        name: "LinuxActiveTabIndex",
+        meta: {
+          title: "linux",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
       // {
       //   path: "/infrastructure/vm",
       //   name: "VirtualMachine",
diff --git a/src/router/k8s.ts b/src/router/k8s.ts
index 38adf3f..a9390bd 100644
--- a/src/router/k8s.ts
+++ b/src/router/k8s.ts
@@ -33,20 +33,42 @@ export const routesK8s: Array<RouteRecordRaw> = [
         path: "/kubernetes/cluster",
         name: "KubernetesCluster",
         meta: {
+          notShow: false,
           title: "kubernetesCluster",
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/kubernetes/cluster/tab/:activeTabIndex",
+        name: "KubernetesClusterActiveTabIndex",
+        meta: {
+          notShow: true,
+          title: "kubernetesClusterActiveTabIndex",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
       {
         path: "/kubernetes/service",
         name: "KubernetesService",
         meta: {
+          notShow: false,
           title: "kubernetesService",
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
+      {
+        path: "/kubernetes/service/tab/:activeTabIndex",
+        name: "KubernetesServiceActiveTabIndex",
+        meta: {
+          notShow: true,
+          title: "kubernetesServiceActiveTabIndex",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
     ],
   },
 ];
diff --git a/src/router/selfObservability.ts b/src/router/selfObservability.ts
index 4174e1b..b2e610b 100644
--- a/src/router/selfObservability.ts
+++ b/src/router/selfObservability.ts
@@ -34,7 +34,15 @@ export const routesSelf: Array<RouteRecordRaw> = [
         name: "SkyWalkingServer",
         meta: {
           title: "skyWalkingServer",
-          headPath: "/mesh/services",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/self/skyWalkingServer/tab/:activeTabIndex",
+        name: "SkyWalkingServerActiveTabIndex",
+        meta: {
+          notShow: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@@ -44,7 +52,15 @@ export const routesSelf: Array<RouteRecordRaw> = [
         name: "Satellite",
         meta: {
           title: "satellite",
-          headPath: "/mesh/controlPanel",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/self/satellite/tab/:activeTabIndex",
+        name: "SatelliteActiveTabIndex",
+        meta: {
+          notShow: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
diff --git a/src/router/serviceMesh.ts b/src/router/serviceMesh.ts
index 719fae4..04df1bb 100644
--- a/src/router/serviceMesh.ts
+++ b/src/router/serviceMesh.ts
@@ -33,8 +33,17 @@ export const routesMesh: Array<RouteRecordRaw> = [
         path: "/mesh/services",
         name: "MeshServices",
         meta: {
+          notShow: false,
           title: "services",
-          headPath: "/mesh/services",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/mesh/services/tab/:activeTabIndex",
+        name: "MeshServicesActiveTabIndex",
+        meta: {
+          notShow: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@@ -43,8 +52,17 @@ export const routesMesh: Array<RouteRecordRaw> = [
         path: "/mesh/controlPanel",
         name: "ControlPanel",
         meta: {
+          notShow: false,
           title: "controlPanel",
-          headPath: "/mesh/controlPanel",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/mesh/controlPanel/tab/:activeTabIndex",
+        name: "ControlPanelActiveTabIndex",
+        meta: {
+          notShow: true,
         },
         component: () =>
           import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
@@ -53,10 +71,21 @@ export const routesMesh: Array<RouteRecordRaw> = [
         path: "/mesh/dataPanel",
         name: "DataPanel",
         meta: {
+          notShow: false,
           title: "dataPanel",
-          headPath: "/mesh/dataPanel",
         },
-        component: () => import("@/views/Layer.vue"),
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
+      },
+      {
+        path: "/mesh/dataPanel/tab/:activeTabIndex",
+        name: "DataPanelActiveTabIndex",
+        meta: {
+          notShow: true,
+          title: "dataPanelActiveTabIndex",
+        },
+        component: () =>
+          import(/* webpackChunkName: "layer" */ "@/views/Layer.vue"),
       },
     ],
   },
diff --git a/src/views/dashboard/controls/Tab.vue b/src/views/dashboard/controls/Tab.vue
index 5064287..2efe341 100644
--- a/src/views/dashboard/controls/Tab.vue
+++ b/src/views/dashboard/controls/Tab.vue
@@ -40,7 +40,14 @@ limitations under the License. -->
       <span class="tab-icons" v-if="dashboardStore.editMode">
         <el-tooltip content="Add tab items" placement="bottom">
           <i @click="addTabItem">
-            <Icon size="middle" iconName="add" />
+            <Icon size="middle" iconName="add" class="tab-icon" />
+          </i>
+        </el-tooltip>
+      </span>
+      <span class="tab-icons">
+        <el-tooltip content="Copy Link" placement="bottom">
+          <i @click="copyLink">
+            <Icon size="middle" iconName="review-list" class="tab-icon" />
           </i>
         </el-tooltip>
       </span>
@@ -99,6 +106,7 @@ limitations under the License. -->
 <script lang="ts">
 import { ref, watch, defineComponent, toRefs } from "vue";
 import { useI18n } from "vue-i18n";
+import { useRoute } from "vue-router";
 import type { PropType } from "vue";
 import { LayoutConfig } from "@/types/dashboard";
 import { useDashboardStore } from "@/store/modules/dashboard";
@@ -111,6 +119,7 @@ import Text from "./Text.vue";
 import Ebpf from "./Ebpf.vue";
 import { dragIgnoreFrom } from "../data";
 import DemandLog from "./DemandLog.vue";
+import copy from "@/utils/copy";
 
 const props = {
   data: {
@@ -126,11 +135,16 @@ export default defineComponent({
   setup(props) {
     const { t } = useI18n();
     const dashboardStore = useDashboardStore();
-    const activeTabIndex = ref<number>(0);
+    const route = useRoute();
+    const activeTabIndex = ref<number>(
+      Number(route.params.activeTabIndex) || 0
+    );
     const activeTabWidget = ref<string>("");
     const editTabIndex = ref<number>(NaN); // edit tab item name
     const canEditTabName = ref<boolean>(false);
     const needQuery = ref<boolean>(false);
+
+    dashboardStore.setActiveTabIndex(activeTabIndex);
     const l = dashboardStore.layout.findIndex(
       (d: LayoutConfig) => d.i === props.data.i
     );
@@ -154,6 +168,11 @@ export default defineComponent({
         dashboardStore.layout[l].children[activeTabIndex.value].children
       );
       needQuery.value = true;
+      if (route.params.activeTabIndex) {
+        let p = location.href.split("/tab/")[0];
+        p = p + "/tab/" + activeTabIndex.value;
+        history.replaceState({}, "", p);
+      }
     }
     function removeTab(e: Event) {
       e.stopPropagation();
@@ -202,6 +221,16 @@ export default defineComponent({
         dashboardStore.layout[l].children[activeTabIndex.value].children
       );
     }
+    function copyLink() {
+      let path = "";
+      if (route.params.activeTabIndex === undefined) {
+        path = location.href + "/tab/" + activeTabIndex.value;
+      } else {
+        const p = location.href.split("/tab/")[0];
+        path = p + "/tab/" + activeTabIndex.value;
+      }
+      copy(path);
+    }
     document.body.addEventListener("click", handleClick, false);
     watch(
       () => dashboardStore.activedGridItem,
@@ -227,6 +256,7 @@ export default defineComponent({
       deleteTabItem,
       removeTab,
       clickTabs,
+      copyLink,
       ...toRefs(props),
       activeTabWidget,
       dashboardStore,
@@ -330,6 +360,10 @@ export default defineComponent({
   overflow: auto;
 }
 
+.tab-icon {
+  color: #666;
+}
+
 .vue-grid-item.active {
   border: 1px solid #409eff;
 }
diff --git a/src/views/dashboard/related/topology/components/Graph.vue b/src/views/dashboard/related/topology/components/Graph.vue
index c075a5d..4ebdbf1 100644
--- a/src/views/dashboard/related/topology/components/Graph.vue
+++ b/src/views/dashboard/related/topology/components/Graph.vue
@@ -538,6 +538,9 @@ function setNodeTools(nodeDashboard: any) {
   }
 }
 async function freshNodes() {
+  if (!svg.value) {
+    return;
+  }
   svg.value.selectAll(".topo-svg-graph").remove();
   await init();
   update();