Merge pull request #233 from sjmshsh/master

k8s mode
diff --git a/ui-vue3/index.html b/ui-vue3/index.html
index 51273a5..63002b3 100644
--- a/ui-vue3/index.html
+++ b/ui-vue3/index.html
@@ -20,7 +20,7 @@
     <meta charset="UTF-8">
     <link rel="icon" href="/dubbo.ico">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Vite App</title>
+    <title>Dubbo Admin</title>
 </head>
 <body>
 <div id="app"></div>
diff --git a/ui-vue3/package.json b/ui-vue3/package.json
index 89e7285..58cec06 100644
--- a/ui-vue3/package.json
+++ b/ui-vue3/package.json
@@ -8,7 +8,8 @@
     "check:i18n": "node --loader ts-node/esm src/base/i18n/sortI18n.ts",
     "preview": "vite preview",
     "test:unit": "vitest",
-    "build": "vite build",
+    "build": "prettier --write src/ && vite build",
+    "format": "prettier --write src/",
     "type-check": "vue-tsc --build --force",
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore",
     "lint:fix": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
diff --git a/ui-vue3/src/api/mock/mockApp.ts b/ui-vue3/src/api/mock/mockApp.ts
index a79658f..8528e82 100644
--- a/ui-vue3/src/api/mock/mockApp.ts
+++ b/ui-vue3/src/api/mock/mockApp.ts
@@ -18,6 +18,14 @@
 import Mock from 'mockjs'
 import devTool from '@/utils/DevToolUtil'
 
+Mock.mock('/mock/application/metrics', 'get', () => {
+  return {
+    code: 200,
+    message: 'success',
+    data: 'http://101.201.225.179:3000/d/a0b114ca-edf7-4dfe-ac2c-34a4fc545fed/application?orgId=1&refresh=1m&from=1710644821536&to=1710731221536&theme=light'
+  }
+})
+
 Mock.mock('/mock/application/search', 'get', () => {
   let total = Mock.mock('@integer(8, 1000)')
   let list = []
diff --git a/ui-vue3/src/api/service/app.ts b/ui-vue3/src/api/service/app.ts
index 15e99c2..44c32a7 100644
--- a/ui-vue3/src/api/service/app.ts
+++ b/ui-vue3/src/api/service/app.ts
@@ -47,3 +47,10 @@
     params
   })
 }
+export const getApplicationMetricsInfo = (params: any): Promise<any> => {
+  return request({
+    url: '/application/metrics',
+    method: 'get',
+    params
+  })
+}
diff --git a/ui-vue3/src/api/service/service.ts b/ui-vue3/src/api/service/service.ts
index 225f86e..8879d2b 100644
--- a/ui-vue3/src/api/service/service.ts
+++ b/ui-vue3/src/api/service/service.ts
@@ -24,3 +24,19 @@
     params
   })
 }
+
+export const getServiceDetail = (params: any): Promise<any> => {
+  return request({
+    url: '/service/detail',
+    method: 'get',
+    params
+  })
+}
+
+export const getServiceDistribution = (params: any): Promise<any> => {
+  return request({
+    url: '/service/distribution',
+    method: 'get',
+    params
+  })
+}
diff --git a/ui-vue3/src/api/service/serviceDetail.ts b/ui-vue3/src/api/service/serviceDetail.ts
deleted file mode 100644
index 3fe9a27..0000000
--- a/ui-vue3/src/api/service/serviceDetail.ts
+++ /dev/null
@@ -1,26 +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 request from '@/base/http/request'
-
-export const getServiceDetail = (params: any): Promise<any> => {
-  return request({
-    url: '/service/detail',
-    method: 'get',
-    params
-  })
-}
diff --git a/ui-vue3/src/api/service/serviceDistribution.ts b/ui-vue3/src/api/service/serviceDistribution.ts
deleted file mode 100644
index 61dbb52..0000000
--- a/ui-vue3/src/api/service/serviceDistribution.ts
+++ /dev/null
@@ -1,26 +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 request from '@/base/http/request'
-
-export const getServiceDistribution = (params: any): Promise<any> => {
-  return request({
-    url: '/service/distribution',
-    method: 'get',
-    params
-  })
-}
diff --git a/ui-vue3/src/layout/index.vue b/ui-vue3/src/layout/index.vue
index 4a43cd6..227c081 100644
--- a/ui-vue3/src/layout/index.vue
+++ b/ui-vue3/src/layout/index.vue
@@ -46,7 +46,9 @@
             </transition>
           </router-view>
         </a-layout-content>
-        <a-layout-footer class="layout-footer">todo</a-layout-footer>
+        <a-layout-footer class="layout-footer"
+          >© 2024 The Apache Software Foundation.
+        </a-layout-footer>
       </a-layout>
     </a-layout>
   </div>
@@ -103,11 +105,12 @@
     padding: 16px 16px 24px;
     background: #fff;
     overflow-y: auto;
-    max-height: 88vh;
+    height: calc(100vh - 140px);
   }
 
   .layout-footer {
-    height: 40px;
+    height: 30px;
+    text-align: center;
   }
 }
 </style>
diff --git a/ui-vue3/src/views/resources/applications/tabs/monitor.vue b/ui-vue3/src/views/resources/applications/tabs/monitor.vue
index 33615d6..09297b6 100644
--- a/ui-vue3/src/views/resources/applications/tabs/monitor.vue
+++ b/ui-vue3/src/views/resources/applications/tabs/monitor.vue
@@ -15,14 +15,66 @@
   ~ limitations under the License.
 -->
 <template>
-  <div class="__container_tabDemo3">tab3</div>
+  <div class="__container_tabDemo3">
+    <div class="option">
+      <a-button class="btn" @click="refresh"> refresh </a-button>
+      <a-button class="btn" @click="newPageForGrafana"> grafana </a-button>
+    </div>
+    <a-spin class="spin" :spinning="!showIframe">
+      <div class="__container_iframe_container">
+        <iframe v-if="showIframe" id="grafanaIframe" :src="grafanaUrl" frameborder="0"></iframe>
+      </div>
+    </a-spin>
+  </div>
 </template>
 
 <script setup lang="ts">
-import { onMounted } from 'vue'
+import { onMounted, ref } from 'vue'
+import { getApplicationMetricsInfo } from '@/api/service/app'
 
-onMounted(() => {
-  console.log(333)
+let grafanaUrl = ref('')
+let showIframe = ref(true)
+onMounted(async () => {
+  let res = await getApplicationMetricsInfo({})
+  grafanaUrl.value = res.data
 })
+
+function refresh() {
+  showIframe.value = false
+  setTimeout(() => {
+    showIframe.value = true
+  }, 200)
+}
+
+function newPageForGrafana() {
+  window.open(grafanaUrl.value, '_blank')
+}
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.__container_tabDemo3 {
+  .option {
+    padding-left: 16px;
+    .btn {
+      margin-right: 10px;
+    }
+  }
+  :deep(.spin) {
+    margin-top: 30px;
+  }
+  .__container_iframe_container {
+    z-index: 1;
+    position: relative;
+    width: calc(100vw - 332px);
+    height: calc(100vh - 200px);
+    clip-path: inset(20px 10px);
+
+    #grafanaIframe {
+      z-index: 0;
+      top: -112px;
+      position: absolute;
+      width: calc(100vw - 332px);
+      height: calc(100vh - 200px);
+    }
+  }
+}
+</style>
diff --git a/ui-vue3/src/views/resources/services/tabs/detail.vue b/ui-vue3/src/views/resources/services/tabs/detail.vue
index fe0751d..9420d9c 100644
--- a/ui-vue3/src/views/resources/services/tabs/detail.vue
+++ b/ui-vue3/src/views/resources/services/tabs/detail.vue
@@ -61,11 +61,11 @@
 
 <script setup lang="ts">
 import { ref } from 'vue'
-import { getServiceDetail } from '@/api/service/serviceDetail'
+import { getServiceDetail } from '@/api/service/service'
 
 const serviceDetail = ref({})
 const onSearch = async () => {
-  const { data } = await getServiceDetail()
+  const { data } = await getServiceDetail({})
   serviceDetail.value = data.data
 }
 
diff --git a/ui-vue3/src/views/resources/services/tabs/distribution.vue b/ui-vue3/src/views/resources/services/tabs/distribution.vue
index 796f77f..4b985a2 100644
--- a/ui-vue3/src/views/resources/services/tabs/distribution.vue
+++ b/ui-vue3/src/views/resources/services/tabs/distribution.vue
@@ -68,7 +68,7 @@
 <script setup lang="ts">
 import type { ComponentInternalInstance } from 'vue'
 import { ref, reactive, getCurrentInstance } from 'vue'
-import { getServiceDistribution } from '@/api/service/serviceDistribution'
+import { getServiceDistribution } from '@/api/service/service'
 import { debounce } from 'lodash'
 
 const {
diff --git a/ui-vue3/vite.config.ts b/ui-vue3/vite.config.ts
index 499c805..e9557fb 100644
--- a/ui-vue3/vite.config.ts
+++ b/ui-vue3/vite.config.ts
@@ -33,7 +33,8 @@
                 target: 'http://jsonplaceholder.typicode.com',
                 changeOrigin: true,
                 rewrite: (path) => path.replace(/^\/api/, ''),
-            }
+            },
+
         },
     },
     plugins: [