Explorar el Código

feat: 部署实例详情页基本完成

zhaoxingrui hace 4 años
padre
commit
b7a177846c

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
     "element-ui": "^2.15.6",
     "jwt-decode": "^3.1.2",
     "vue": "^2.6.14",
+    "vue-json-viewer": "^2.2.22",
     "vue-router": "^3.5.1",
     "vuex": "^3.6.2"
   },

+ 0 - 1
src/App.vue

@@ -3,7 +3,6 @@
     <el-container style="height: 100%">
       <side-bar></side-bar>
       <el-container>
-        <!-- <el-header>Header</el-header> -->
         <el-main>
           <router-view/>
         </el-main>

+ 1 - 0
src/api/deployment.js

@@ -3,3 +3,4 @@ import axios from "@/util/request.js"
 export const getTotalDeployments = config => axios.get('/api/deployment/pages', config);
 export const getDeploymentsByCurrentAndSize = config => axios.get('/api/deployment/page', config);
 export const getOwnerInfo = config => axios.get('/api/deployment/owner/namespace', config);
+export const getPodInfo = config => axios.get('/api/pod', config);

+ 3 - 0
src/api/limitRange.js

@@ -0,0 +1,3 @@
+import axios from '@/util/request.js'
+
+export const getLimitRange = config => axios.get('/api/limit', config);

+ 72 - 14
src/components/DeploymentDetail.vue

@@ -3,31 +3,59 @@
     <div class="title">部署实例详情
       <el-button type="text" @click="$router.push({path: '/'})" style="vertical-align: middle">←返回上一页</el-button>
     </div>
-    <!-- {{namespace}}:{{deployName}} -->
     <div class="wrapper">
       <div class="common">
         <div class="inner-title">所属者信息</div>
+        <owner-card :namespace="namespace"></owner-card>
       </div>
-      <div class="common">
+      <div class="common" style="height: 100%">
         <div class="inner-title">容器信息</div>
-        {{namespace}}-----{{deployName}}
+        <div style="height: 90%; overflow-y: auto;">
+          <info-card :info="containerInfo" :depth="depth"></info-card>
+        </div>
       </div>
-      <div class="common">
+      <div class="common" style="height: 100%">
         <div class="inner-title">容器状态</div>
+        <div style="height: 90%; overflow-y: auto;">
+          <info-card :info="containerStatus" :depth="depth"></info-card>
+        </div>
       </div>
-      <div class="common">
+      <div class="common" style="height: 100%">
         <div class="inner-title">pod状态</div>
+        <div style="height: 90%; overflow-y: auto;">
+          <info-card :info="podStatus" :depth="depth"></info-card>
+        </div>
       </div>
-      <div class="common">
+      <div class="common" style="height: 100%">
         <div class="inner-title">限额配置</div>
+        <div style="height: 70%; overflow-y: auto;">
+          <limit-range-card :namespace="namespace"></limit-range-card>
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script>
+import { getPodInfo } from '@/api/deployment'
+import OwnerCard from '@/components/OwnerCard.vue'
+import InfoCard from '@/components/InfoCard.vue'
+import LimitRangeCard from '@/components/LimitRangeCard.vue'
 export default {
   name: 'DeploymentDetail',
+  data() {
+    return {
+      containerInfo: {},
+      containerStatus: {},
+      podStatus: {},
+      depth: 5,
+    }
+  },
+  components: {
+    OwnerCard,
+    InfoCard,
+    LimitRangeCard
+  },
   computed: {
     namespace() {
       return this.$route.query.namespace;
@@ -35,26 +63,56 @@ export default {
     deployName() {
       return this.$route.query.deployName;
     }
+  },
+  async mounted() {
+    const config = {
+      params: {
+        namespace: this.namespace
+      }
+    };
+    await getPodInfo(config).then(res => {
+      const data = res.data.data[0];
+      this.containerInfo = {
+        apiVersion: data.apiVersion,
+        kind: data.kind,
+        name: data.name,
+        namespace: data.namespace,
+        labels: data.labels,
+        annotations: data.annotations,
+        containers: data.containers
+      };
+      this.podStatus = data.podStatus.conditions;
+      this.containerStatus = data.podStatus;
+      delete this.containerStatus.conditions;
+      console.log(this.containerStatus);
+    }).catch(err => {
+      console.log(err);
+    })
   }
 }
 </script>
 
 <style lang="scss" scoped>
 .wrapper {
-  /* 声明一个容器 */
   display: grid;
-  grid-template-columns: 1fr 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
   grid-template-rows: 1fr 1fr 1fr 1fr;
-  grid-template-areas: 'a b c c'
-                       'a b c c'
-                       'd d c c'
-                       'd d e e';
+  grid-template-areas: 'a b b c c c'
+                       'a b b c c c'
+                       'd d d e e e'
+                       'd d d e e e';
   height: 85vh;
   grid-gap: 12px;
+  width: 95%;
+  margin: 0 auto;
 }
 .common {
-  border-radius: 5px;
-  background-color: #9fb2da;
+  border-radius: 8px;
+  border: 1px solid #f0f0f0;
+  background: #fff;
+}
+.common:hover {
+  box-shadow: 1px 1px 2px #9fa8da;
 }
 .wrapper div:nth-child(1) {
   grid-area: a;

+ 25 - 0
src/components/InfoCard.vue

@@ -0,0 +1,25 @@
+<template>
+  <div class="body">
+    <json-viewer :value="info" theme="jv-light" :expand-depth="depth" class="my-theme"></json-viewer>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'InfoCard',
+  props: {
+    depth: Number,
+    info: [Array, Object],
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 95%;
+  margin: 0 auto;
+}
+.my-theme {
+  background: transparent;
+}
+</style>

+ 43 - 0
src/components/LimitRangeCard.vue

@@ -0,0 +1,43 @@
+<template>
+  <div class="body">
+    <json-viewer :value="info" theme="jv-light" :expand-depth="depth" class="my-theme"></json-viewer>
+  </div>
+</template>
+
+<script>
+import { getLimitRange } from '@/api/limitRange'
+export default {
+  name: 'LimitRangeCard',
+  props: {
+    namespace: String
+  },
+  data() {
+    return {
+      info: {},
+      depth: 2
+    }
+  },
+  mounted() {
+    const config = {
+      params: {
+        namespace: this.namespace
+      }
+    };
+    getLimitRange(config).then(res => {
+      this.info = res.data.data
+    }).catch(err => {
+      console.log(err)
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 95%;
+  margin: 0 auto;
+}
+.my-theme {
+  background: transparent;
+}
+</style>

+ 81 - 0
src/components/OwnerCard.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="body">
+    <el-row class="item">
+      <el-col :span="3">
+        <span class="item-title">id:</span>
+      </el-col>
+      <el-col :span="21">
+        <el-tag size="small">{{ownerInfo.id}}</el-tag>
+      </el-col>
+    </el-row>
+    <el-row class="item">
+      <el-col :span="11">
+        <span class="item-title">username:</span>
+      </el-col>
+      <el-col :span="13">{{ownerInfo.username}}</el-col>
+    </el-row>
+    <el-row class="item">
+      <el-col :span="7">
+        <span class="item-title">phone:</span>
+      </el-col>
+      <el-col :span="17">{{ownerInfo.phone}}</el-col>
+    </el-row>
+    <el-row class="item">
+      <el-col :span="6">
+        <span class="item-title">email:</span>
+      </el-col>
+      <el-col :span="18">{{ownerInfo.email}}</el-col>
+    </el-row>
+    <el-row class="item">
+      <el-col :span="5">
+        <span class="item-title">role:</span>
+      </el-col>
+      <el-col :span="19">
+        <el-tag type="success" size="small">{{ownerInfo.role}}</el-tag>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { getOwnerInfo } from '@/api/deployment'
+export default {
+  name: 'OwnerCard',
+  props: {
+    namespace: String,
+  },
+  data() {
+    return {
+      ownerInfo: {},
+    }
+  },
+  async mounted() {
+    const config = {
+      params: {
+        namespace: this.namespace
+      }
+    }
+    await getOwnerInfo(config).then(res => {
+      this.ownerInfo = res.data.data;
+    }).catch(err => {
+      console.log(err);
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 80%;
+  margin: 0 auto;
+  .item {
+    margin-bottom: 15px;
+    &-title {
+      font-weight: bold;
+    }
+  }
+  .item:nth-child(1) {
+    margin-top: 10px;
+  }
+}
+</style>

+ 3 - 0
src/main.js

@@ -2,11 +2,14 @@ import Vue from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
+import JsonViewer from 'vue-json-viewer'
 import ElementUI from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css'
 import '@/assets/css/common.css'
+
 Vue.config.productionTip = false
 Vue.use(ElementUI)
+Vue.use(JsonViewer)
 
 new Vue({
   router,

+ 40 - 82
yarn.lock

@@ -2001,11 +2001,6 @@ browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4
     node-releases "^2.0.2"
     picocolors "^1.0.0"
 
-buffer-equal-constant-time@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
-  integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
-
 buffer-from@^1.0.0:
   version "1.1.2"
   resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
@@ -2173,6 +2168,15 @@ cli-spinners@^2.5.0:
   resolved "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d"
   integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
 
+clipboard@^2.0.4:
+  version "2.0.10"
+  resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.10.tgz#e61f6f7139ac5044c58c0484dcac9fb2a918bfd6"
+  integrity sha512-cz3m2YVwFz95qSEbCDi2fzLN/epEN9zXBvfgAoGkvGOJZATMl9gtTDVOtBYkx2ODUJl2kvmud7n32sV2BpYR4g==
+  dependencies:
+    good-listener "^1.2.2"
+    select "^1.1.2"
+    tiny-emitter "^2.0.0"
+
 clipboardy@^2.3.0:
   version "2.3.0"
   resolved "https://registry.npmmirror.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290"
@@ -2578,6 +2582,11 @@ define-properties@^1.1.3:
   dependencies:
     object-keys "^1.0.12"
 
+delegate@^3.1.2:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
+  integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
+
 depd@~1.1.2:
   version "1.1.2"
   resolved "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -2684,13 +2693,6 @@ easy-stack@1.0.1:
   resolved "https://registry.npmmirror.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
   integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==
 
-ecdsa-sig-formatter@1.0.11:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
-  integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
-  dependencies:
-    safe-buffer "^5.0.1"
-
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -3305,6 +3307,13 @@ globby@^11.0.2, globby@^11.0.3:
     merge2 "^1.4.1"
     slash "^3.0.0"
 
+good-listener@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
+  integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
+  dependencies:
+    delegate "^3.1.2"
+
 graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
   version "4.2.10"
   resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
@@ -3775,39 +3784,6 @@ jsonfile@^6.0.1:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
-jsonwebtoken@^8.5.1:
-  version "8.5.1"
-  resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
-  integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
-  dependencies:
-    jws "^3.2.2"
-    lodash.includes "^4.3.0"
-    lodash.isboolean "^3.0.3"
-    lodash.isinteger "^4.0.4"
-    lodash.isnumber "^3.0.3"
-    lodash.isplainobject "^4.0.6"
-    lodash.isstring "^4.0.1"
-    lodash.once "^4.0.0"
-    ms "^2.1.1"
-    semver "^5.6.0"
-
-jwa@^1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
-  integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
-  dependencies:
-    buffer-equal-constant-time "1.0.1"
-    ecdsa-sig-formatter "1.0.11"
-    safe-buffer "^5.0.1"
-
-jws@^3.2.2:
-  version "3.2.2"
-  resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
-  integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
-  dependencies:
-    jwa "^1.4.1"
-    safe-buffer "^5.0.1"
-
 jwt-decode@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
@@ -3896,36 +3872,6 @@ lodash.defaultsdeep@^4.6.1:
   resolved "https://registry.npmmirror.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
   integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==
 
-lodash.includes@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
-  integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
-
-lodash.isboolean@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
-  integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
-
-lodash.isinteger@^4.0.4:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
-  integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
-
-lodash.isnumber@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
-  integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
-
-lodash.isplainobject@^4.0.6:
-  version "4.0.6"
-  resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
-  integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
-
-lodash.isstring@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
-  integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
-
 lodash.kebabcase@^4.1.1:
   version "4.1.1"
   resolved "https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
@@ -3946,11 +3892,6 @@ lodash.merge@^4.6.2:
   resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
   integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
 
-lodash.once@^4.0.0:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
-  integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
-
 lodash.truncate@^4.4.2:
   version "4.4.2"
   resolved "https://registry.npmmirror.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
@@ -5093,7 +5034,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
   integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
 
-safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
+safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
   version "5.2.1"
   resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
   integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -5153,6 +5094,11 @@ select-hose@^2.0.0:
   resolved "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
   integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
 
+select@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
+  integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
+
 selfsigned@^2.0.1:
   version "2.0.1"
   resolved "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56"
@@ -5160,7 +5106,7 @@ selfsigned@^2.0.1:
   dependencies:
     node-forge "^1"
 
-"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", semver@^5.5.0:
   version "5.7.1"
   resolved "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
   integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -5612,6 +5558,11 @@ thunky@^1.0.2:
   resolved "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
   integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
 
+tiny-emitter@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
+  integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
+
 to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -5770,6 +5721,13 @@ vue-hot-reload-api@^2.3.0:
   resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
   integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
 
+vue-json-viewer@^2.2.22:
+  version "2.2.22"
+  resolved "https://registry.yarnpkg.com/vue-json-viewer/-/vue-json-viewer-2.2.22.tgz#7ea7454b8aac3701245b88acf39de876cc54221e"
+  integrity sha512-3oPH5BxoUWva/qp7wNJj+15FBXyi9Yu5VDW4mCWivjHR1pUpMv34fjqqxML7jh2uOqm1S/3Xks5nQ5JjC5+OWw==
+  dependencies:
+    clipboard "^2.0.4"
+
 vue-loader@^17.0.0:
   version "17.0.0"
   resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb"