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

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-fence.git


The following commit(s) were added to refs/heads/master by this push:
     new abb4f57  add rest api testing (#90)
abb4f57 is described below

commit abb4f57d0a932e74c9243c39866f56f4b41034c5
Author: liubao68 <[email protected]>
AuthorDate: Sun Nov 3 11:42:16 2024 +0800

    add rest api testing (#90)
---
 .../src/main/web/config/vite.config.dev.ts         |  30 +--
 .../src/main/web/config/vite.config.prod.ts        |   5 +-
 .../src/main/web/src/components/menu/index.vue     |   6 +
 admin-website/src/main/web/src/locale/en-US.ts     |   3 +
 admin-website/src/main/web/src/locale/zh-CN.ts     |   3 +
 .../web/src/router/routes/modules/maintenance.ts   |  12 +
 .../views/maintenance/restApi/components/main.vue  | 247 +++++++++++++++++++++
 .../web/src/views/maintenance/restApi/index.vue    |  31 +++
 .../src/views/maintenance/restApi/locale/en-US.ts  |   6 +
 .../src/views/maintenance/restApi/locale/zh-CN.ts  |   6 +
 10 files changed, 333 insertions(+), 16 deletions(-)

diff --git a/admin-website/src/main/web/config/vite.config.dev.ts 
b/admin-website/src/main/web/config/vite.config.dev.ts
index dfb583a..9698f4a 100644
--- a/admin-website/src/main/web/config/vite.config.dev.ts
+++ b/admin-website/src/main/web/config/vite.config.dev.ts
@@ -1,22 +1,26 @@
-import { mergeConfig, loadEnv } from 'vite';
-import eslint from 'vite-plugin-eslint';
+import { mergeConfig } from 'vite';
 import baseConfig from './vite.config.base';
+import configCompressPlugin from './plugin/compress';
+import configVisualizerPlugin from './plugin/visualizer';
 
 export default mergeConfig(
   {
-    mode: 'development',
-    server: {
-      open: true,
-      fs: {
-        strict: true,
+    mode: 'production',
+    plugins: [configCompressPlugin('gzip'), configVisualizerPlugin()],
+    build: {
+      rollupOptions: {
+        output: {
+          manualChunks: {
+            vue: ['vue', 'vue-router', 'pinia', '@vueuse/core', 'vue-i18n'],
+          },
+          entryFileNames: 'assets/[name].js',
+          chunkFileNames: 'assets/[name].js',
+          assetFileNames: 'assets/[name].[ext]'
+        },
       },
+      chunkSizeWarningLimit: 2000,
+      minify: false,
     },
-    plugins: [
-      eslint({
-        include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
-        exclude: ['node_modules'],
-      }),
-    ],
   },
   baseConfig
 );
diff --git a/admin-website/src/main/web/config/vite.config.prod.ts 
b/admin-website/src/main/web/config/vite.config.prod.ts
index 9446a32..9698f4a 100644
--- a/admin-website/src/main/web/config/vite.config.prod.ts
+++ b/admin-website/src/main/web/config/vite.config.prod.ts
@@ -1,12 +1,11 @@
 import { mergeConfig } from 'vite';
-import baseConig from './vite.config.base';
+import baseConfig from './vite.config.base';
 import configCompressPlugin from './plugin/compress';
 import configVisualizerPlugin from './plugin/visualizer';
 
 export default mergeConfig(
   {
     mode: 'production',
-    mock: true,
     plugins: [configCompressPlugin('gzip'), configVisualizerPlugin()],
     build: {
       rollupOptions: {
@@ -23,5 +22,5 @@ export default mergeConfig(
       minify: false,
     },
   },
-  baseConig
+  baseConfig
 );
diff --git a/admin-website/src/main/web/src/components/menu/index.vue 
b/admin-website/src/main/web/src/components/menu/index.vue
index f478e12..953d4fb 100644
--- a/admin-website/src/main/web/src/components/menu/index.vue
+++ b/admin-website/src/main/web/src/components/menu/index.vue
@@ -74,6 +74,12 @@
       icon: null,
       bold: 'title',
     },
+   {
+      value: 'RestApi',
+      name: 'menu.maintenance.restapi',
+      icon: null,
+      bold: 'title',
+    },
    {
       value: 'Examples',
       name: 'menu.examples',
diff --git a/admin-website/src/main/web/src/locale/en-US.ts 
b/admin-website/src/main/web/src/locale/en-US.ts
index 465d5ef..48f6378 100644
--- a/admin-website/src/main/web/src/locale/en-US.ts
+++ b/admin-website/src/main/web/src/locale/en-US.ts
@@ -8,6 +8,8 @@ import localeManagement from '@/views/management/locale/en-US';
 
 import localeProblems from '@/views/maintenance/problems/locale/en-US';
 
+import localeRestApi from '@/views/maintenance/restapi/locale/en-US';
+
 import localeExamples from '@/views/examples/locale/en-US';
 
 import localeSettings from './en-US/settings';
@@ -34,5 +36,6 @@ export default {
   ...localeManagement,
   ...localeExamples,
   ...localeProblems,
+  ...localeRestApi,
   ...localeHttpError,
 };
diff --git a/admin-website/src/main/web/src/locale/zh-CN.ts 
b/admin-website/src/main/web/src/locale/zh-CN.ts
index 904221c..800d260 100644
--- a/admin-website/src/main/web/src/locale/zh-CN.ts
+++ b/admin-website/src/main/web/src/locale/zh-CN.ts
@@ -8,6 +8,8 @@ import localeManagement from '@/views/management/locale/zh-CN';
 
 import localeProblems from '@/views/maintenance/problems/locale/zh-CN';
 
+import localeRestApi from '@/views/maintenance/restapi/locale/zh-CN';
+
 import localeExamples from '@/views/examples/locale/zh-CN';
 
 import localeSettings from './zh-CN/settings';
@@ -34,5 +36,6 @@ export default {
   ...localeManagement,
   ...localeExamples,
   ...localeProblems,
+  ...localeRestApi,
   ...localeHttpError,
 };
diff --git 
a/admin-website/src/main/web/src/router/routes/modules/maintenance.ts 
b/admin-website/src/main/web/src/router/routes/modules/maintenance.ts
index 8293a3c..ff1e01b 100644
--- a/admin-website/src/main/web/src/router/routes/modules/maintenance.ts
+++ b/admin-website/src/main/web/src/router/routes/modules/maintenance.ts
@@ -25,5 +25,17 @@ export default {
         roles: [],
       },
     },
+    {
+      path: 'restApi',
+      name: 'RestApi',
+      id: 'RestApi',
+      label: 'RestApi',
+      component: () => import('@/views/maintenance/restApi/index.vue'),
+      meta: {
+        locale: 'menu.maintenance.restapi',
+        requiresAuth: true,
+        roles: [],
+      },
+    },
   ],
 };
diff --git 
a/admin-website/src/main/web/src/views/maintenance/restApi/components/main.vue 
b/admin-website/src/main/web/src/views/maintenance/restApi/components/main.vue
new file mode 100644
index 0000000..d4580aa
--- /dev/null
+++ 
b/admin-website/src/main/web/src/views/maintenance/restApi/components/main.vue
@@ -0,0 +1,247 @@
+<template>
+  <div class="main">
+    <div class="main-title">
+      <span></span>
+      <p>{{ $t('maintenance.restapi.main.title') }}</p>
+    </div>
+    <div class="main-content">
+      <div class="main-content-method-and-url">
+        <tiny-select v-model="state.method" class="url-select"
+           :options="state.methodList"></tiny-select>
+        <tiny-input v-model="state.url" class="url-input"></tiny-input>
+        <tiny-button class="url-button" type="primary" @click="sendRequest">{{ 
$t('maintenance.restapi.main.send') }}</tiny-button>
+      </div>
+
+      <tiny-tabs v-model="state.activeTab">
+      <tiny-tab-item title="Query Params" name="query">
+      <div class="main-content-params">
+      <div class="main-content-params-table">
+        <tiny-grid :data="state.params">
+          <tiny-grid-column field="" title="">
+              <template #default="data">
+                <tiny-checkbox v-model="data.row.checked"></tiny-checkbox>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="Key" title="Key">
+              <template #default="data">
+                <tiny-input v-model="data.row.key" 
@input="onQueryInputChange(data.row.id)"></tiny-input>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="Value" title="Value">
+              <template #default="data">
+                <tiny-input v-model="data.row.value"></tiny-input>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="" title="">
+              <template #default="data">
+                <tiny-button @click="deleteQueryRow(data.row.id)">{{ 
$t('maintenance.restapi.main.deleteRow') }}</tiny-button>
+              </template>
+          </tiny-grid-column>
+        </tiny-grid>
+      </div>
+      </div>
+      </tiny-tab-item>
+
+      <tiny-tab-item title="Header Params" name="header">
+      <div class="main-content-params">
+      <div class="main-content-params-table">
+        <tiny-grid :data="state.headers">
+          <tiny-grid-column field="" title="">
+              <template #default="data">
+                <tiny-checkbox v-model="data.row.checked"></tiny-checkbox>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="Key" title="Key">
+              <template #default="data">
+                <tiny-input v-model="data.row.key" 
@input="onHeaderInputChange(data.row.id)"></tiny-input>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="Value" title="Value">
+              <template #default="data">
+                <tiny-input v-model="data.row.value"></tiny-input>
+              </template>
+          </tiny-grid-column>
+          <tiny-grid-column field="" title="">
+              <template #default="data">
+                <tiny-button @click="deleteHeaderRow(data.row.id)">{{ 
$t('maintenance.restapi.main.deleteRow') }}</tiny-button>
+              </template>
+          </tiny-grid-column>
+        </tiny-grid>
+      </div>
+      </div>
+      </tiny-tab-item>
+
+      <tiny-tab-item title="Body" name="body">
+      <div class="main-content-params">
+        <div class="main-content-params-text">
+          <div class="main-textarea">
+          <tiny-input type="textarea" v-model="state.body" placeholder=""
+            :autosize="{ minRows: 20, maxRows: 100 }" ></tiny-input>
+          </div>
+        </div>
+      </div>
+      </tiny-tab-item>
+      </tiny-tabs>
+
+      <tiny-divider></tiny-divider>
+      <div class="main-content-response">
+        <tiny-input v-model="state.response.status" disabled label="Status 
Code: "></tiny-input>
+        <div class="main-textarea">
+        <tiny-input type="textarea" v-model="state.response.data" disabled 
placeholder=""
+           :autosize="{ minRows: 20, maxRows: 100 }"></tiny-input>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import axios from 'axios';
+import { reactive, ref } from 'vue';
+import {
+  Form as TinyForm,
+  FormItem as TinyFormItem,
+  Input as TinyInput,
+  Button as TinyButton,
+  Row as TinyRow,
+  Col as TinyCol,
+  DatePicker as TinyDatePicker,
+  Grid as TinyGrid, GridColumn as TinyGridColumn, GridToolbar as 
TinyGridToolbar,
+  Select as TinySelect, Option as TinyOption,
+  Checkbox as TinyCheckbox, Divider as TinyDivider,
+  Tabs as TinyTabs, TabItem as TinyTabItem,
+} from '@opentiny/vue';
+
+const state = reactive({
+  method: "GET",
+  methodList: [{value: "GET", label: "GET"},{value: "POST", label: "POST"},
+                 {value: "PUT", label: "PUT"},{value: "DELETE", label: 
"DELETE"}],
+  url: "",
+  params: [{id: 0, key: "", value: "", checked: false}],
+  headers: [{id: 0, key: "", value: "", checked: false}],
+  body: "",
+  activeTab: "query",
+  response: {},
+});
+
+const onQueryInputChange = (id)  => {
+  state.params.forEach((element, index) => {
+    if (element.id === id) {
+      element.checked = true
+    }
+  });
+
+  if (state.params[state.params.length - 1].key !== '') {
+    state.params.push({id: state.params.length, key: "", value: "", checked: 
false});
+  }
+};
+
+const onHeaderInputChange = (id)  => {
+  state.headers.forEach((element, index) => {
+    if (element.id === id) {
+      element.checked = true
+    }
+  });
+
+  if (state.headers[state.headers.length - 1].key !== '') {
+    state.headers.push({id: state.headers.length, key: "", value: "", checked: 
false});
+  }
+};
+
+const deleteQueryRow = (id)  => {
+  state.params.splice(id, 1);
+};
+
+const deleteHeaderRow = (id)  => {
+  state.headers.splice(id, 1);
+};
+
+const sendRequest = () => {
+  const params = {};
+  state.params.forEach((element, index) => {
+    if (element.key !== "" && element.checked === true) {
+      params[element.key] = element.value;
+    }
+  });
+  const headers = {};
+  state.headers.forEach((element, index) => {
+    if (element.key !== "" && element.checked === true) {
+      headers[element.key] = element.value;
+    }
+  });
+
+  axios({
+    url: state.url,
+    method: state.method,
+    headers: headers,
+    params: params,
+    data: state.body
+  })
+  .then(function(data) {
+    state.response.status = "Response Success";
+    state.response.data = JSON.stringify(data);
+  });
+}
+</script>
+
+<style scoped lang="less"></style>
+
+<style lang="less" scoped>
+.main {
+  &-title {
+    span {
+      display: inline-block;
+      position: relative;
+      border-width: 0px;
+      left: 0px;
+      top: 4px;
+      width: 6px;
+      height: 20px;
+      background: inherit;
+      background-color: rgba(37, 97, 239, 1);
+      border: none;
+      border-radius: 8px;
+      -moz-box-shadow: none;
+      -webkit-box-shadow: none;
+      box-shadow: none;
+    }
+
+    p {
+      margin-left: 10px;
+      display: inline-block;
+      font-weight: 500;
+      font-style: normal;
+      font-size: 18px;
+      color: rgba(51, 51, 51, 0.898039215686275);
+    }
+  }
+
+  &-content {
+    .main-content-method-and-url {
+      display: flex;
+      gap: 10px;
+
+      .url-select {
+        width: 10%
+      }
+      .url-input {
+        width: 80%
+      }
+      .url-button {
+        width: 10%
+      }
+    }
+
+    .main-content-params {
+      &-table {
+          width: 95%;
+          background-color: saddlebrown;
+      }
+    }
+  }
+}
+
+.tiny-textarea {
+  height: 200px;
+}
+</style>
diff --git a/admin-website/src/main/web/src/views/maintenance/restApi/index.vue 
b/admin-website/src/main/web/src/views/maintenance/restApi/index.vue
new file mode 100644
index 0000000..caffea3
--- /dev/null
+++ b/admin-website/src/main/web/src/views/maintenance/restApi/index.vue
@@ -0,0 +1,31 @@
+<template>
+  <div class="container">
+    <div class="contain">
+      <Breadcrumb :items="['menu.maintenance', 'menu.maintenance.restapi']" />
+      <Main></Main>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import Main from './components/main.vue';
+</script>
+
+<style scoped lang="less">
+  .container {
+    width: 98%;
+    height: inherit;
+    margin: 0 auto;
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+</style>
+
+<style lang="less" scoped>
+  // responsive
+  @media (max-width: @screen-xs) {
+    .container {
+      overflow-x: auto;
+    }
+  }
+</style>
diff --git 
a/admin-website/src/main/web/src/views/maintenance/restApi/locale/en-US.ts 
b/admin-website/src/main/web/src/views/maintenance/restApi/locale/en-US.ts
new file mode 100644
index 0000000..54a1022
--- /dev/null
+++ b/admin-website/src/main/web/src/views/maintenance/restApi/locale/en-US.ts
@@ -0,0 +1,6 @@
+export default {
+  'menu.maintenance.restapi': 'API Testing',
+    'maintenance.restapi.main.title': 'API Testing',
+    'maintenance.restapi.main.send': 'Send',
+    'maintenance.restapi.main.deleteRow': 'Delete',
+};
diff --git 
a/admin-website/src/main/web/src/views/maintenance/restApi/locale/zh-CN.ts 
b/admin-website/src/main/web/src/views/maintenance/restApi/locale/zh-CN.ts
new file mode 100644
index 0000000..489ab33
--- /dev/null
+++ b/admin-website/src/main/web/src/views/maintenance/restApi/locale/zh-CN.ts
@@ -0,0 +1,6 @@
+export default {
+    'menu.maintenance.restapi': '接口测试',
+    'maintenance.restapi.main.title': '接口测试',
+    'maintenance.restapi.main.send': '发送',
+    'maintenance.restapi.main.deleteRow': '删除',
+};

Reply via email to