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': '删除',
+};