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 a521e041 feat: Implement customize menus (#297)
a521e041 is described below

commit a521e041a7ae629a872d9ceaa54818ecd53626ce
Author: Fine0830 <[email protected]>
AuthorDate: Tue Jul 11 17:19:30 2023 +0800

    feat: Implement customize menus (#297)
---
 src/assets/icons/aws_cloud.svg            |  17 ++++
 src/assets/icons/browser.svg              |  17 ++++
 src/assets/icons/database.svg             |  17 ++++
 src/assets/icons/general_service.svg      |  16 ++++
 src/assets/icons/infrastructure.svg       |  18 +++++
 src/assets/icons/kubernetes.svg           |  17 ++++
 src/assets/icons/marketplace.svg          |  15 ++++
 src/assets/icons/self_observability.svg   |  29 +++++++
 src/assets/icons/service_mesh.svg         |  16 ++++
 src/graphql/fragments/app.ts              |  21 +++++
 src/graphql/query/app.ts                  |   4 +-
 src/layout/components/NavBar.vue          |   2 +-
 src/layout/components/SideBar.vue         |  17 ++--
 src/locales/lang/en.ts                    |   4 +
 src/locales/lang/es.ts                    |   4 +
 src/locales/lang/zh.ts                    |   4 +
 src/router/alarm.ts                       |   2 +-
 src/router/dashboard.ts                   |   6 +-
 src/router/data/aws.ts                    |  95 -----------------------
 src/router/data/browser.ts                |  46 -----------
 src/router/data/database.ts               | 111 --------------------------
 src/router/data/functions.ts              |  46 -----------
 src/router/data/gateway.ts                |  63 ---------------
 src/router/data/general.ts                |  94 ----------------------
 src/router/data/index.ts                  |  41 ----------
 src/router/data/infrastructure.ts         |  65 ----------------
 src/router/data/k8s.ts                    |  67 ----------------
 src/router/data/mq.ts                     |  47 -----------
 src/router/data/selfObservability.ts      |  63 ---------------
 src/router/data/serviceMesh.ts            |  83 --------------------
 src/router/index.ts                       |   9 ++-
 src/router/layer.ts                       |  66 +++++++++++++---
 src/router/{setting.ts => marketplace.ts} |  26 ++++---
 src/store/modules/app.ts                  |  40 ++++++++++
 src/types/app.d.ts                        |  18 +++++
 src/types/components.d.ts                 |   2 +
 src/utils/cancelToken.ts                  |   2 +-
 src/views/marketplace/Menus.vue           | 124 ++++++++++++++++++++++++++++++
 src/views/{ => marketplace}/Settings.vue  |   0
 vite.config.ts                            |   2 +-
 40 files changed, 477 insertions(+), 859 deletions(-)

diff --git a/src/assets/icons/aws_cloud.svg b/src/assets/icons/aws_cloud.svg
new file mode 100644
index 00000000..9ec18d56
--- /dev/null
+++ b/src/assets/icons/aws_cloud.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"; 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/browser.svg b/src/assets/icons/browser.svg
new file mode 100644
index 00000000..eab0146d
--- /dev/null
+++ b/src/assets/icons/browser.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/database.svg b/src/assets/icons/database.svg
new file mode 100644
index 00000000..73d66841
--- /dev/null
+++ b/src/assets/icons/database.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="M3.984 11.016v1.969h2.016v-1.969h-2.016zM2.016 
14.016v-4.031h19.969v4.031h-19.969zM6 6.984v-1.969h-2.016v1.969h2.016zM2.016 
3.984h19.969v4.031h-19.969v-4.031zM3.984 
17.016v1.969h2.016v-1.969h-2.016zM2.016 
20.016v-4.031h19.969v4.031h-19.969z"></path>
+</svg>
diff --git a/src/assets/icons/general_service.svg 
b/src/assets/icons/general_service.svg
new file mode 100755
index 00000000..f22dfca1
--- /dev/null
+++ b/src/assets/icons/general_service.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/chart</title><path 
d="M5.55 3.824L6.853 5.78a.3.3 0 0 0 .384.102l1.526-.764a.3.3 0 0 1 
.384.102l1.65 2.476a.3.3 0 0 0 .462.045l1.229-1.229a.3.3 0 0 1 
.512.212v4.243H5V3.99a.3.3 0 0 1 .55-.167zM13 12a1 1 0 0 1 0 2H3.833A1.833 
1.833 0 0 1 2 12.167V3a1 1 0 1 1 2 0v9h9z" id="a"/></svg>
\ No newline at end of file
diff --git a/src/assets/icons/infrastructure.svg 
b/src/assets/icons/infrastructure.svg
new file mode 100644
index 00000000..2ab919b7
--- /dev/null
+++ b/src/assets/icons/infrastructure.svg
@@ -0,0 +1,18 @@
+<!-- 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">
+<title>scatter_plot</title>
+<path d="M13.594 17.578q0-1.219 0.891-2.109t2.109-0.891 2.109 0.891 0.891 
2.109-0.891 2.109-2.109 0.891-2.109-0.891-0.891-2.109zM8.016 6q0-1.219 
0.891-2.109t2.109-0.891 2.109 0.891 0.891 2.109-0.891 2.109-2.109 
0.891-2.109-0.891-0.891-2.109zM3.984 14.016q0-1.219 0.891-2.109t2.109-0.891 
2.109 0.891 0.891 2.109-0.891 2.109-2.109 
0.891-2.109-0.891-0.891-2.109z"></path>
+</svg>
diff --git a/src/assets/icons/kubernetes.svg b/src/assets/icons/kubernetes.svg
new file mode 100644
index 00000000..1c4cad71
--- /dev/null
+++ b/src/assets/icons/kubernetes.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="M12.984 14.859q1.266-0.375 1.875-1.875h7.125q-0.375 3.609-2.836 
6.141t-6.164 2.859v-7.125zM14.859 11.016q-0.563-1.5-1.875-1.875v-7.125q3.703 
0.328 6.164 2.859t2.836 6.141h-7.125zM11.016 9.141q-0.797 0.328-1.406 
1.125t-0.609 1.734 0.609 1.734 1.406 
1.125v7.125q-3.797-0.375-6.398-3.234t-2.602-6.75 2.602-6.75 
6.398-3.234v7.125z"></path>
+</svg>
diff --git a/src/assets/icons/marketplace.svg b/src/assets/icons/marketplace.svg
new file mode 100644
index 00000000..4433709c
--- /dev/null
+++ b/src/assets/icons/marketplace.svg
@@ -0,0 +1,15 @@
+<!-- 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 t="1688979849484" class="icon" viewBox="0 0 1024 1024" version="1.1" 
xmlns="http://www.w3.org/2000/svg"; p-id="2698"><path d="M384 
469.333333H213.333333c-46.933333 
0-85.333333-38.4-85.333333-85.333333V213.333333c0-46.933333 38.4-85.333333 
85.333333-85.333333h170.666667c46.933333 0 85.333333 38.4 85.333333 
85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333zM213.333333 
213.333333v170.666667h170.666667V213.333333H213.333333z" 
p-id="2699"></path><path d="M170.666667 554. [...]
\ No newline at end of file
diff --git a/src/assets/icons/self_observability.svg 
b/src/assets/icons/self_observability.svg
new file mode 100644
index 00000000..65f0531d
--- /dev/null
+++ b/src/assets/icons/self_observability.svg
@@ -0,0 +1,29 @@
+<!-- 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. -->
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="3450px" height="1823px" viewBox="0 0 3450 1823" version="1.1" 
xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink";>
+    <!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch 
-->
+    <title>Group</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" 
fill-rule="evenodd">
+        <g id="Group" transform="translate(0.000000, -29.000000)">
+            <path d="M1050.01772,1394.31899 C1050.01772,1615.24051 
912.21519,1851.47342 474.746835,1851.47342 C310.696203,1851.47342 
192.579747,1836.16203 87.5873418,1812.10127 C65.7139241,1807.72658 
46.0278481,1792.41519 46.0278481,1768.35443 L46.0278481,1610.86582 
C46.0278481,1586.80506 65.7139241,1569.30633 87.5873418,1569.30633 
L91.9620253,1569.30633 C179.455696,1580.24304 398.189873,1591.17975 
479.121519,1591.17975 C673.794937,1591.17975 732.853165,1521.18481 
732.853165,1394.31899 C [...]
+            <g id="moon-o" transform="translate(2932.164557, 596.000000) 
rotate(-183.000000) translate(-2932.164557, -596.000000) translate(2415.708861, 
26.379747)" fill="#D8D8D8" fill-rule="nonzero">
+                <path d="M1025.31646,927.371333 C992.796119,932.841177 
959.292071,935.576099 925.845888,935.576099 C590.40035,935.576099 
318.259524,661.909325 318.259524,324.582876 C318.259524,209.134252 
351.705707,96.3623597 412.290747,0 C171.802278,71.8062511 0,293.684076 
0,557.342199 C0,878.317305 259.46831,1139.24051 578.65368,1139.24051 
C753.17563,1139.24051 916.818891,1059.22949 1025.31646,927.371333 Z" 
id="Shape"></path>
+            </g>
+        </g>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/src/assets/icons/service_mesh.svg 
b/src/assets/icons/service_mesh.svg
new file mode 100755
index 00000000..c48868a2
--- /dev/null
+++ b/src/assets/icons/service_mesh.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/epic</title><path 
d="M5.156 4l-.811 2h7.31l-.811-2H5.156zM4.55 2h6.9c.368 0 .702.235.85.6l1.622 
4c.205.505-.009 1.095-.478 1.316a.87.87 0 0 1-.371.084H2.927C2.415 8 2 7.552 2 
7c0-.138.026-.274.078-.4l1.622-4c.148-.365.481-.6.85-.6zM3 9h10a1 1 0 0 1 0 
2H3a1 1 0 0 1 0-2zm0 3h10a1 1 0 0 1 0 2H3a1 1 0 0 1 0-2z" id="a"/></svg>
\ No newline at end of file
diff --git a/src/graphql/fragments/app.ts b/src/graphql/fragments/app.ts
index 120b270a..8f87699f 100644
--- a/src/graphql/fragments/app.ts
+++ b/src/graphql/fragments/app.ts
@@ -26,3 +26,24 @@ export const OAPTimeInfo = {
 export const OAPVersion = {
   query: `version { version }`,
 };
+
+export const MenuItems = {
+  query: `
+    getMenuItems {
+        title
+        icon
+        layer
+        activate
+        description
+        documentLink
+        subItems {
+          title
+          icon
+          layer
+          activate
+          description
+          documentLink
+        }
+      }
+    `,
+};
diff --git a/src/graphql/query/app.ts b/src/graphql/query/app.ts
index d538c417..d74aeac4 100644
--- a/src/graphql/query/app.ts
+++ b/src/graphql/query/app.ts
@@ -14,8 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { OAPTimeInfo, OAPVersion } from "../fragments/app";
+import { OAPTimeInfo, OAPVersion, MenuItems } from "../fragments/app";
 
 export const queryOAPTimeInfo = `query queryOAPTimeInfo 
{${OAPTimeInfo.query}}`;
 
 export const queryOAPVersion = `query ${OAPVersion.query}`;
+
+export const queryMenuItems = `query menuItems {${MenuItems.query}}`;
diff --git a/src/layout/components/NavBar.vue b/src/layout/components/NavBar.vue
index f5576306..26a0285e 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">
-    <div class="title">{{ route.name === "ViewWidget" ? "" : 
appStore.pageTitle || t(pageName) }}</div>
+    <div class="title">{{ route.name === "ViewWidget" ? "" : 
appStore.pageTitle || pageName }}</div>
     <div class="app-config">
       <span class="red" v-show="timeRange">{{ t("timeTips") }}</span>
       <TimePicker
diff --git a/src/layout/components/SideBar.vue 
b/src/layout/components/SideBar.vue
index b88476ae..17e4344a 100644
--- a/src/layout/components/SideBar.vue
+++ b/src/layout/components/SideBar.vue
@@ -36,14 +36,14 @@ limitations under the License. -->
                   <Icon size="lg" :iconName="menu.meta.icon" />
                 </el-icon>
                 <span class="title" :class="isCollapse ? 'collapse' : ''">
-                  {{ t(menu.meta.title) }}
+                  {{ menu.meta.title }}
                 </span>
               </router-link>
             </template>
             <el-menu-item-group>
               <el-menu-item v-for="(m, idx) in filterMenus(menu.children)" 
:index="m.name" :key="idx">
                 <router-link class="items" :to="m.path">
-                  <span class="title">{{ m.meta && t(m.meta.title) }}</span>
+                  <span class="title">{{ m.meta && m.meta.title }}</span>
                 </router-link>
               </el-menu-item>
             </el-menu-item-group>
@@ -56,7 +56,7 @@ limitations under the License. -->
             </el-icon>
             <template #title>
               <router-link class="items menu-title" 
:to="menu.children[0].path">
-                <span class="title">{{ t(menu.meta.title) }}</span>
+                <span class="title">{{ menu.meta.title }}</span>
               </router-link>
             </template>
           </el-menu-item>
@@ -67,16 +67,14 @@ limitations under the License. -->
 </template>
 
 <script lang="ts" setup>
-  import { ref } from "vue";
+  import { ref, watch } from "vue";
   import type { RouteRecordRaw } from "vue-router";
   import { useRouter, useRoute } from "vue-router";
-  import { useI18n } from "vue-i18n";
   import Icon from "@/components/Icon.vue";
   import { useAppStoreWithOut } from "@/store/modules/app";
 
   /*global Recordable*/
   const appStore = useAppStoreWithOut();
-  const { t } = useI18n();
   const name = ref<string>(String(useRouter().currentRoute.value.name));
   const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "") ? 
ref("light") : ref("black");
   const routes = ref<RouteRecordRaw[] | any>(useRouter().options.routes);
@@ -112,6 +110,13 @@ limitations under the License. -->
     isCollapse.value = true;
     open.value = false;
   }
+
+  watch(
+    () => route.name,
+    () => {
+      name.value = String(route.name);
+    },
+  );
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 7dbf950c..906a88fc 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -405,5 +405,9 @@ const msg = {
   detailLabel: "Detail Label",
   summary: "Summary",
   detail: "Detail",
+  marketplace: "Marketplace",
+  menus: "Menus",
+  saveReload: "Save and reload the page",
+  document: "Documentation",
 };
 export default msg;
diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts
index 2f5637e9..f667740b 100644
--- a/src/locales/lang/es.ts
+++ b/src/locales/lang/es.ts
@@ -404,5 +404,9 @@ const msg = {
   detailLabel: "Detail Label",
   summary: "Summary",
   detail: "Detail",
+  marketplace: "Marketplace",
+  menus: "Menus",
+  saveReload: "Save and reload the page",
+  document: "Documentation",
 };
 export default msg;
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 4bf623b8..05eb3be8 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -402,5 +402,9 @@ const msg = {
   detailLabel: "详细标签",
   summary: "概括",
   detail: "详细",
+  marketplace: "市场",
+  menusManagement: "菜单",
+  saveReload: "保存并重新加载页面",
+  document: "文档",
 };
 export default msg;
diff --git a/src/router/alarm.ts b/src/router/alarm.ts
index 24101dd4..f9e6b92f 100644
--- a/src/router/alarm.ts
+++ b/src/router/alarm.ts
@@ -22,7 +22,7 @@ export const routesAlarm: Array<RouteRecordRaw> = [
     path: "",
     name: "Alarm",
     meta: {
-      title: "alarm",
+      title: "Alerting",
       icon: "spam",
       hasGroup: false,
     },
diff --git a/src/router/dashboard.ts b/src/router/dashboard.ts
index 32be6261..ab7ade75 100644
--- a/src/router/dashboard.ts
+++ b/src/router/dashboard.ts
@@ -23,7 +23,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
     component: Layout,
     name: "Dashboard",
     meta: {
-      title: "dashboards",
+      title: "Dashboards",
       icon: "dashboard_customize",
       hasGroup: true,
     },
@@ -33,7 +33,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
         component: () => import("@/views/dashboard/List.vue"),
         name: "List",
         meta: {
-          title: "dashboardList",
+          title: "Dashboard List",
         },
       },
       {
@@ -41,7 +41,7 @@ export const routesDashboard: Array<RouteRecordRaw> = [
         component: () => import("@/views/dashboard/New.vue"),
         name: "New",
         meta: {
-          title: "dashboardNew",
+          title: "New Dashboard",
         },
       },
       {
diff --git a/src/router/data/aws.ts b/src/router/data/aws.ts
deleted file mode 100644
index 47f782d7..00000000
--- a/src/router/data/aws.ts
+++ /dev/null
@@ -1,95 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "AWSCloud",
-    meta: {
-      title: "AWSCloud",
-      icon: "cloud_queue",
-      hasGroup: true,
-    },
-    redirect: "/aws-eks",
-    children: [
-      {
-        path: "/aws-eks",
-        name: "AWSCloudEKS",
-        meta: {
-          title: "AWSCloudEKS",
-          layer: "AWS_EKS",
-        },
-      },
-      {
-        path: "/aws-eks/tab/:activeTabIndex",
-        name: "EKSActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_EKS",
-        },
-      },
-      {
-        path: "/aws-s3",
-        name: "AWSCloudS3",
-        meta: {
-          title: "AWSCloudS3",
-          layer: "AWS_S3",
-        },
-      },
-      {
-        path: "/aws-s3/tab/:activeTabIndex",
-        name: "S3ActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_S3",
-        },
-      },
-      {
-        path: "/aws-dynamodb",
-        name: "AWSCloudDynamoDB",
-        meta: {
-          title: "AWSCloudDynamoDB",
-          layer: "AWS_DYNAMODB",
-        },
-      },
-      {
-        path: "/aws-dynamodb/tab/:activeTabIndex",
-        name: "DynamoDBActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_DYNAMODB",
-        },
-      },
-      {
-        path: "/aws-api-gateway",
-        name: "APIGateway",
-        meta: {
-          title: "APIGateway",
-          layer: "AWS_GATEWAY",
-        },
-      },
-      {
-        path: "/aws-api-gateway/tab/:activeTabIndex",
-        name: "APIGatewayActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_GATEWAY",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/browser.ts b/src/router/data/browser.ts
deleted file mode 100644
index d4cdf31e..00000000
--- a/src/router/data/browser.ts
+++ /dev/null
@@ -1,46 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Browser",
-    meta: {
-      title: "browser",
-      icon: "language",
-    },
-    redirect: "/browser",
-    children: [
-      {
-        path: "/browser",
-        name: "Browser",
-        meta: {
-          title: "browser",
-          layer: "BROWSER",
-        },
-      },
-      {
-        path: "/browser/tab/:activeTabIndex",
-        name: "BrowserActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "BROWSER",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/database.ts b/src/router/data/database.ts
deleted file mode 100644
index f95c500c..00000000
--- a/src/router/data/database.ts
+++ /dev/null
@@ -1,111 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Database",
-    meta: {
-      title: "database",
-      icon: "storage",
-      hasGroup: true,
-    },
-    redirect: "/mySQL",
-    children: [
-      {
-        path: "/mySQL",
-        name: "MySQL",
-        meta: {
-          title: "mySQL",
-          layer: "MYSQL",
-        },
-      },
-      {
-        path: "/mySQL/tab/:activeTabIndex",
-        name: "MySQLActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "MYSQL",
-        },
-      },
-      {
-        path: "/postgreSQL",
-        name: "PostgreSQL",
-        meta: {
-          title: "postgreSQL",
-          layer: "POSTGRESQL",
-        },
-      },
-      {
-        path: "/postgreSQL/tab/:activeTabIndex",
-        name: "PostgreSQLActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "POSTGRESQL",
-        },
-      },
-      {
-        path: "/aws-dynamodb",
-        name: "AWSCloudDynamoDB",
-        meta: {
-          title: "AWSCloudDynamoDB",
-          layer: "AWS_DYNAMODB",
-        },
-      },
-      {
-        path: "/aws-dynamodb/tab/:activeTabIndex",
-        name: "DynamoDBActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_DYNAMODB",
-        },
-      },
-      {
-        path: "/redis",
-        name: "Redis",
-        meta: {
-          title: "redis",
-          layer: "REDIS",
-        },
-      },
-      {
-        path: "/redis/tab/:activeTabIndex",
-        name: "RedisActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "REDIS",
-        },
-      },
-      {
-        path: "/elasticsearch",
-        name: "Elasticsearch",
-        meta: {
-          title: "elasticsearch",
-          layer: "ELASTICSEARCH",
-        },
-      },
-      {
-        path: "/elasticsearch/tab/:activeTabIndex",
-        name: "ElasticsearchActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "ELASTICSEARCH",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/functions.ts b/src/router/data/functions.ts
deleted file mode 100644
index 37e8469e..00000000
--- a/src/router/data/functions.ts
+++ /dev/null
@@ -1,46 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Functions",
-    meta: {
-      title: "functions",
-      icon: "functions",
-      hasGroup: true,
-    },
-    children: [
-      {
-        path: "/openFunction",
-        name: "OpenFunction",
-        meta: {
-          title: "openFunction",
-          layer: "FAAS",
-        },
-      },
-      {
-        path: "/openFunction/tab/:activeTabIndex",
-        name: "OpenFunctionActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "FAAS",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/gateway.ts b/src/router/data/gateway.ts
deleted file mode 100644
index 8c1f640a..00000000
--- a/src/router/data/gateway.ts
+++ /dev/null
@@ -1,63 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Gateway",
-    meta: {
-      title: "gateway",
-      icon: "gateway",
-      hasGroup: true,
-    },
-    redirect: "/apisix",
-    children: [
-      {
-        path: "/apisix",
-        name: "APISIX",
-        meta: {
-          title: "apisix",
-          layer: "APISIX",
-        },
-      },
-      {
-        path: "/apisix/tab/:activeTabIndex",
-        name: "APISIXActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "APISIX",
-        },
-      },
-      {
-        path: "/aws-gateway",
-        name: "AWSGateway",
-        meta: {
-          title: "AWSGateway",
-          layer: "AWS_GATEWAY",
-        },
-      },
-      {
-        path: "/aws-gateway/tab/:activeTabIndex",
-        name: "GatewayActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "AWS_GATEWAY",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/general.ts b/src/router/data/general.ts
deleted file mode 100644
index 75fb148d..00000000
--- a/src/router/data/general.ts
+++ /dev/null
@@ -1,94 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "General",
-    meta: {
-      title: "general",
-      icon: "chart",
-      hasGroup: true,
-    },
-    children: [
-      {
-        path: "/general",
-        name: "GeneralServices",
-        meta: {
-          title: "services",
-          layer: "GENERAL",
-        },
-      },
-      {
-        path: "/general/tab/:activeTabIndex",
-        name: "GeneralServicesActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "GENERAL",
-        },
-      },
-      {
-        path: "/database",
-        name: "VirtualDatabase",
-        meta: {
-          title: "virtualDatabase",
-          layer: "VIRTUAL_DATABASE",
-        },
-      },
-      {
-        path: "/database/tab/:activeTabIndex",
-        name: "VirtualDatabaseActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "VIRTUAL_DATABASE",
-        },
-      },
-      {
-        path: "/cache",
-        name: "VirtualCache",
-        meta: {
-          title: "virtualCache",
-          layer: "VIRTUAL_CACHE",
-        },
-      },
-      {
-        path: "/cache/tab/:activeTabIndex",
-        name: "VirtualCacheActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "VIRTUAL_CACHE",
-        },
-      },
-      {
-        path: "/mq",
-        name: "VirtualMQ",
-        meta: {
-          title: "virtualMQ",
-          layer: "VIRTUAL_MQ",
-        },
-      },
-      {
-        path: "/mq/tab/:activeTabIndex",
-        name: "VirtualMQActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "VIRTUAL_MQ",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/index.ts b/src/router/data/index.ts
deleted file mode 100644
index 94a8de71..00000000
--- a/src/router/data/index.ts
+++ /dev/null
@@ -1,41 +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.
- */
-import general from "./general";
-import serviceMesh from "./serviceMesh";
-import database from "./database";
-import infrastructure from "./infrastructure";
-import selfObservability from "./selfObservability";
-import functions from "./functions";
-import browser from "./browser";
-import k8s from "./k8s";
-import gateway from "./gateway";
-import aws from "./aws";
-import mq from "./mq";
-
-export default [
-  ...general,
-  ...serviceMesh,
-  ...functions,
-  ...k8s,
-  ...infrastructure,
-  ...aws,
-  ...browser,
-  ...gateway,
-  ...database,
-  ...mq,
-  ...selfObservability,
-];
diff --git a/src/router/data/infrastructure.ts 
b/src/router/data/infrastructure.ts
deleted file mode 100644
index d2b59698..00000000
--- a/src/router/data/infrastructure.ts
+++ /dev/null
@@ -1,65 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Infrastructure",
-    meta: {
-      title: "infrastructure",
-      icon: "scatter_plot",
-      hasGroup: true,
-    },
-    redirect: "/linux",
-    children: [
-      {
-        path: "/linux",
-        name: "Linux",
-        meta: {
-          title: "linux",
-          layer: "OS_LINUX",
-        },
-      },
-      {
-        path: "/linux/tab/:activeTabIndex",
-        name: "LinuxActiveTabIndex",
-        meta: {
-          title: "linux",
-          notShow: true,
-          layer: "OS_LINUX",
-        },
-      },
-      {
-        path: "/windows",
-        name: "Windows",
-        meta: {
-          title: "windows",
-          layer: "OS_WINDOWS",
-        },
-      },
-      {
-        path: "/windows/tab/:activeTabIndex",
-        name: "WindowsActiveTabIndex",
-        meta: {
-          title: "windows",
-          notShow: true,
-          layer: "OS_WINDOWS",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/k8s.ts b/src/router/data/k8s.ts
deleted file mode 100644
index bc93aa7d..00000000
--- a/src/router/data/k8s.ts
+++ /dev/null
@@ -1,67 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "Kubernetes",
-    meta: {
-      title: "kubernetes",
-      icon: "donut_small",
-      hasGroup: true,
-    },
-    redirect: "/kubernetes/cluster",
-    children: [
-      {
-        path: "/kubernetes/cluster",
-        name: "KubernetesCluster",
-        meta: {
-          notShow: false,
-          title: "kubernetesCluster",
-          layer: "K8S",
-        },
-      },
-      {
-        path: "/kubernetes/cluster/tab/:activeTabIndex",
-        name: "KubernetesClusterActiveTabIndex",
-        meta: {
-          notShow: true,
-          title: "kubernetesClusterActiveTabIndex",
-          layer: "K8S",
-        },
-      },
-      {
-        path: "/kubernetes/service",
-        name: "KubernetesService",
-        meta: {
-          notShow: false,
-          title: "kubernetesService",
-          layer: "K8S_SERVICE",
-        },
-      },
-      {
-        path: "/kubernetes/service/tab/:activeTabIndex",
-        name: "KubernetesServiceActiveTabIndex",
-        meta: {
-          notShow: true,
-          title: "kubernetesServiceActiveTabIndex",
-          layer: "K8S_SERVICE",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/mq.ts b/src/router/data/mq.ts
deleted file mode 100644
index 1286a4fc..00000000
--- a/src/router/data/mq.ts
+++ /dev/null
@@ -1,47 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "MQ",
-    meta: {
-      title: "mq",
-      icon: "mq",
-      hasGroup: true,
-    },
-    redirect: "/rabbitMQ",
-    children: [
-      {
-        path: "/rabbitMQ",
-        name: "RabbitMQ",
-        meta: {
-          title: "rabbitMQ",
-          layer: "RABBITMQ",
-        },
-      },
-      {
-        path: "/rabbitMQ/tab/:activeTabIndex",
-        name: "RabbitMQActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "RABBITMQ",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/selfObservability.ts 
b/src/router/data/selfObservability.ts
deleted file mode 100644
index 9e283cce..00000000
--- a/src/router/data/selfObservability.ts
+++ /dev/null
@@ -1,63 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "SelfObservability",
-    redirect: "/self/skyWalkingServer",
-    meta: {
-      title: "selfObservability",
-      icon: "logo",
-      hasGroup: true,
-    },
-    children: [
-      {
-        path: "/self/skyWalkingServer",
-        name: "SkyWalkingServer",
-        meta: {
-          title: "skyWalkingServer",
-          layer: "SO11Y_OAP",
-        },
-      },
-      {
-        path: "/self/skyWalkingServer/tab/:activeTabIndex",
-        name: "SkyWalkingServerActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "SO11Y_OAP",
-        },
-      },
-      {
-        path: "/self/satellite",
-        name: "Satellite",
-        meta: {
-          title: "satellite",
-          layer: "SO11Y_SATELLITE",
-        },
-      },
-      {
-        path: "/self/satellite/tab/:activeTabIndex",
-        name: "SatelliteActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "SO11Y_SATELLITE",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/data/serviceMesh.ts b/src/router/data/serviceMesh.ts
deleted file mode 100644
index 89abbde9..00000000
--- a/src/router/data/serviceMesh.ts
+++ /dev/null
@@ -1,83 +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.
- */
-
-export default [
-  {
-    path: "",
-    name: "ServiceMesh",
-    redirect: "/mesh/services",
-    meta: {
-      title: "serviceMesh",
-      icon: "epic",
-      hasGroup: true,
-    },
-    children: [
-      {
-        path: "/mesh/services",
-        name: "MeshServices",
-        meta: {
-          notShow: false,
-          title: "services",
-          layer: "MESH",
-        },
-      },
-      {
-        path: "/mesh/services/tab/:activeTabIndex",
-        name: "MeshServicesActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "MESH",
-        },
-      },
-      {
-        path: "/mesh/controlPanel",
-        name: "ControlPanel",
-        meta: {
-          notShow: false,
-          title: "controlPanel",
-          layer: "MESH_CP",
-        },
-      },
-      {
-        path: "/mesh/controlPanel/tab/:activeTabIndex",
-        name: "ControlPanelActiveTabIndex",
-        meta: {
-          notShow: true,
-          layer: "MESH_CP",
-        },
-      },
-      {
-        path: "/mesh/dataPanel",
-        name: "DataPanel",
-        meta: {
-          notShow: false,
-          title: "dataPanel",
-          layer: "MESH_DP",
-        },
-      },
-      {
-        path: "/mesh/dataPanel/tab/:activeTabIndex",
-        name: "DataPanelActiveTabIndex",
-        meta: {
-          notShow: true,
-          title: "dataPanelActiveTabIndex",
-          layer: "MESH_DP",
-        },
-      },
-    ],
-  },
-];
diff --git a/src/router/index.ts b/src/router/index.ts
index f86f4aaf..4fb334a8 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -17,11 +17,11 @@
 import type { RouteRecordRaw } from "vue-router";
 import { createRouter, createWebHistory } from "vue-router";
 import { routesDashboard } from "./dashboard";
-import { routesSetting } from "./setting";
+import { routesMarketplace } from "./marketplace";
 import { routesAlarm } from "./alarm";
 import routesLayers from "./layer";
 
-const routes: Array<RouteRecordRaw> = [...routesLayers, ...routesDashboard, 
...routesAlarm, ...routesSetting];
+const routes: Array<RouteRecordRaw> = [...routesMarketplace, ...routesLayers, 
...routesDashboard, ...routesAlarm];
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
@@ -30,6 +30,8 @@ const router = createRouter({
 
 (window as any).axiosCancel = [];
 
+const defaultPath = (routesLayers[0] && routesLayers[0].children[0].path) || 
"";
+
 router.beforeEach((to, from, next) => {
   // const token = window.localStorage.getItem("skywalking-authority");
   if ((window as any).axiosCancel.length !== 0) {
@@ -38,8 +40,9 @@ router.beforeEach((to, from, next) => {
     }
     (window as any).axiosCancel = [];
   }
+
   if (to.path === "/") {
-    next({ path: "/general" });
+    next({ path: defaultPath });
   } else {
     next();
   }
diff --git a/src/router/layer.ts b/src/router/layer.ts
index dc0fdc06..02646d0b 100644
--- a/src/router/layer.ts
+++ b/src/router/layer.ts
@@ -14,21 +14,65 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import LayerJson from "./data";
 import Layout from "@/layout/Index.vue";
+import { useAppStoreWithOut } from "@/store/modules/app";
+import type { MenuOptions } from "@/types/app";
 
-function layerDashboards() {
-  const routes = LayerJson.map((item: any) => {
-    item.component = Layout;
-    if (item.children) {
-      item.children = item.children.map((d: any) => {
-        d.component = () => import("@/views/Layer.vue");
-        return d;
-      });
+async function layerDashboards() {
+  const appStore = useAppStoreWithOut();
+  await appStore.getActivateMenus();
+  const routes = appStore.activateMenus.map((item: MenuOptions) => {
+    const route: any = {
+      path: "",
+      name: item.name,
+      component: Layout,
+      meta: {
+        icon: item.icon || "cloud_queue",
+        title: item.title,
+        hasGroup: item.hasGroup,
+      },
+      children: item.subItems && item.subItems.length ? [] : undefined,
+    };
+    for (const child of item.subItems || []) {
+      const d = {
+        name: child.name,
+        path: child.path,
+        meta: {
+          title: child.title,
+          layer: child.layer,
+          icon: child.icon || "cloud_queue",
+        },
+        component: () => import("@/views/Layer.vue"),
+      };
+      route.children.push(d);
+      const tab = {
+        name: `${child.name}ActiveTabIndex`,
+        path: `/${child.name}/tab/:activeTabIndex`,
+        component: () => import("@/views/Layer.vue"),
+        meta: {
+          notShow: true,
+          layer: child.layer,
+        },
+      };
+      route.children.push(tab);
     }
-    return item;
+    if (!item.hasGroup) {
+      route.children = [
+        {
+          name: item.name,
+          path: item.path,
+          meta: {
+            title: item.title,
+            layer: item.layer,
+            icon: item.icon,
+          },
+          component: () => import("@/views/Layer.vue"),
+        },
+      ];
+    }
+    return route;
   });
   return routes;
 }
 
-export default layerDashboards();
+export default await layerDashboards();
diff --git a/src/router/setting.ts b/src/router/marketplace.ts
similarity index 67%
rename from src/router/setting.ts
rename to src/router/marketplace.ts
index 9ad4d455..32f7d745 100644
--- a/src/router/setting.ts
+++ b/src/router/marketplace.ts
@@ -17,26 +17,32 @@
 import type { RouteRecordRaw } from "vue-router";
 import Layout from "@/layout/Index.vue";
 
-export const routesSetting: Array<RouteRecordRaw> = [
+export const routesMarketplace: Array<RouteRecordRaw> = [
   {
     path: "",
-    name: "Settings",
+    name: "Marketplace",
     meta: {
-      title: "settings",
-      icon: "settings",
-      hasGroup: false,
+      title: "Marketplace",
+      icon: "marketplace",
+      hasGroup: true,
     },
     component: Layout,
     children: [
       {
-        path: "/settings",
+        path: "/marketplace/menus",
+        name: "MenusManagement",
+        meta: {
+          title: "Categories",
+        },
+        component: () => import("@/views/marketplace/Menus.vue"),
+      },
+      {
+        path: "/marketplace/settings",
         name: "Settings",
         meta: {
-          title: "settings",
-          icon: "settings",
-          hasGroup: false,
+          title: "Settings",
         },
-        component: () => import("@/views/Settings.vue"),
+        component: () => import("@/views/marketplace/Settings.vue"),
       },
     ],
   },
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index 2065a163..05761182 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -22,6 +22,7 @@ import getLocalTime from "@/utils/localtime";
 import type { AxiosResponse } from "axios";
 import dateFormatStep, { dateFormatTime } from "@/utils/dateFormat";
 import { TimeType } from "@/constants/data";
+import type { MenuOptions, SubItem } from "@/types/app";
 /*global Nullable*/
 interface AppState {
   durationRow: Recordable;
@@ -35,6 +36,7 @@ interface AppState {
   version: string;
   isMobile: boolean;
   reloadTimer: Nullable<IntervalHandle>;
+  activateMenus: MenuOptions[];
 }
 
 export const appStore = defineStore({
@@ -55,6 +57,7 @@ export const appStore = defineStore({
     version: "",
     isMobile: false,
     reloadTimer: null,
+    activateMenus: [],
   }),
   getters: {
     duration(): Duration {
@@ -158,6 +161,35 @@ export const appStore = defineStore({
         500,
       );
     },
+    async getActivateMenus() {
+      const resp = (await this.queryMenuItems()) || {};
+      const menus = (resp.getMenuItems || []).map((d: MenuOptions, index: 
number) => {
+        const t = `${d.title.replace(/\s+/g, "-")}`;
+        d.name = `${t}-${index}`;
+        d.path = `/${t}`;
+        if (d.subItems && d.subItems.length) {
+          d.hasGroup = true;
+          d.subItems = d.subItems.map((item: SubItem, sub: number) => {
+            const id = `${item.title.replace(/\s+/g, "-")}`;
+            item.name = `${id}-${index}${sub}`;
+            item.path = `/${t}/${id}`;
+            return item;
+          });
+        }
+
+        return d;
+      });
+      this.activateMenus = menus.filter((d: MenuOptions) => {
+        if (d.activate) {
+          d.subItems = d.subItems.filter((item: SubItem) => {
+            if (item.activate) {
+              return item;
+            }
+          });
+          return d;
+        }
+      });
+    },
     async queryOAPTimeInfo() {
       const res: AxiosResponse = await 
graphql.query("queryOAPTimeInfo").params({});
       if (res.data.errors) {
@@ -179,6 +211,14 @@ export const appStore = defineStore({
       this.version = res.data.data.version;
       return res.data;
     },
+    async queryMenuItems() {
+      const res: AxiosResponse = await 
graphql.query("queryMenuItems").params({});
+      if (res.data.errors) {
+        return res.data;
+      }
+
+      return res.data.data;
+    },
     setReloadTimer(timer: IntervalHandle) {
       this.reloadTimer = timer;
     },
diff --git a/src/types/app.d.ts b/src/types/app.d.ts
index 4cf123ce..540e9bc8 100644
--- a/src/types/app.d.ts
+++ b/src/types/app.d.ts
@@ -46,3 +46,21 @@ export type EventParams = {
   color: string;
   event: any;
 };
+
+export interface MenuOptions extends SubItem {
+  hasGroup?: boolean;
+  subItems: SubItem[];
+}
+
+export interface SubItem {
+  layer: string;
+  icon: string;
+  title: string;
+  activate: boolean;
+  name?: string;
+  path?: string;
+  notShow?: boolean;
+  id?: string;
+  description: string;
+  documentLink: string;
+}
diff --git a/src/types/components.d.ts b/src/types/components.d.ts
index 05ec63bd..cae7912a 100644
--- a/src/types/components.d.ts
+++ b/src/types/components.d.ts
@@ -7,6 +7,7 @@ declare module '@vue/runtime-core' {
   export interface GlobalComponents {
     DateCalendar: typeof import('./../components/DateCalendar.vue')['default']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElCard: typeof import('element-plus/es')['ElCard']
     ElCollapse: typeof import('element-plus/es')['ElCollapse']
     ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
     ElDialog: typeof import('element-plus/es')['ElDialog']
@@ -17,6 +18,7 @@ declare module '@vue/runtime-core' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
+    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
diff --git a/src/utils/cancelToken.ts b/src/utils/cancelToken.ts
index 44da32ea..a4466adf 100644
--- a/src/utils/cancelToken.ts
+++ b/src/utils/cancelToken.ts
@@ -21,5 +21,5 @@ const CancelToken = axios.CancelToken;
 export const cancelToken = (): any =>
   new CancelToken(function executor(c) {
     const w = window as any;
-    w.axiosCancel.push(c);
+    (w.axiosCancel || []).push(c);
   });
diff --git a/src/views/marketplace/Menus.vue b/src/views/marketplace/Menus.vue
new file mode 100644
index 00000000..941918c6
--- /dev/null
+++ b/src/views/marketplace/Menus.vue
@@ -0,0 +1,124 @@
+<!-- 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 class="menus flex-v">
+    <div class="category-body flex-h">
+      <div class="mr-20 mt-10 flex-h category">
+        <el-card
+          class="item"
+          v-for="(menu, index) in appStore.activateMenus"
+          :key="index"
+          @click="handleItems(menu)"
+          :class="currentItems.name === menu.name ? 'active' : ''"
+        >
+          <router-link :to="menu.hasGroup ? '' : menu.path || ''">
+            <div class="title" :class="menu.hasGroup ? '' : 'actived-font'"> 
{{ menu.title }}</div>
+          </router-link>
+          <div class="mt-10"> {{ menu.description }} </div>
+          <el-link :href="menu.documentLink" target="_blank" class="link" 
v-show="menu.documentLink">
+            <el-button class="mt-10" size="small" type="primary"> {{ 
t("document") }} </el-button>
+          </el-link>
+        </el-card>
+      </div>
+      <div class="mt-10 cards">
+        <el-card shadow="hover" v-for="(item, index) in currentItems.subItems 
|| []" :key="index" class="card">
+          <router-link :to="item.path || ''">
+            <div class="title actived-font"> {{ item.title }}</div>
+          </router-link>
+          <div class="mt-10"> {{ item.description }} </div>
+          <el-link :href="item.documentLink" target="_blank" class="link" 
v-show="item.documentLink">
+            <el-button class="mt-10" size="small" type="primary"> {{ 
t("document") }} </el-button>
+          </el-link>
+        </el-card>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { ref } from "vue";
+  import { useI18n } from "vue-i18n";
+  import { useAppStoreWithOut } from "@/store/modules/app";
+  import type { MenuOptions } from "@/types/app";
+
+  const { t } = useI18n();
+  const appStore = useAppStoreWithOut();
+  const currentItems = ref<MenuOptions>(appStore.activateMenus[0] || {});
+
+  function handleItems(item: MenuOptions) {
+    currentItems.value = item;
+  }
+
+  appStore.setPageTitle("Categories");
+</script>
+<style lang="scss" scoped>
+  .menus {
+    flex-grow: 1;
+    height: 100%;
+    font-size: $font-size-smaller;
+    padding: 10px;
+  }
+
+  .category-body {
+    padding-left: 20px 30px;
+    width: 100%;
+    height: 100%;
+    justify-content: space-between;
+  }
+
+  .title {
+    font-weight: bold;
+    font-size: 14px;
+  }
+
+  .actived-font {
+    color: $active-color;
+  }
+
+  .card {
+    margin-bottom: 30px;
+    cursor: pointer;
+    width: 380px;
+  }
+
+  .cards {
+    min-width: 400px;
+    height: 100%;
+    overflow: auto;
+  }
+
+  .item {
+    margin-bottom: 20px;
+    margin-right: 10px;
+    width: 300px;
+    cursor: pointer;
+  }
+
+  .category {
+    flex-wrap: wrap;
+    border-right: 1px solid #ddd;
+    align-content: flex-start;
+    height: 100%;
+    overflow: auto;
+  }
+
+  .link {
+    float: right;
+    margin-bottom: 20px;
+  }
+
+  .active {
+    border: 1px solid $active-color;
+  }
+</style>
diff --git a/src/views/Settings.vue b/src/views/marketplace/Settings.vue
similarity index 100%
rename from src/views/Settings.vue
rename to src/views/marketplace/Settings.vue
diff --git a/vite.config.ts b/vite.config.ts
index a705e818..f63e7d5e 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -79,7 +79,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
       },
     },
     build: {
-      target: "es2015",
+      target: "esnext",
       cssTarget: "chrome80",
       outDir: OUTPUT_DIR,
       manifest: false,

Reply via email to