Skip to content

Commit

Permalink
chore: use the correct API version (apache#1215)
Browse files Browse the repository at this point in the history
Co-authored-by: litesun <[email protected]>

fix: online debug body params support content-type x-www-form-urlencoded (apache#1201)

* fix: online debug body params support content-type x-www-form-urlencoded

* fix: body code mirror support different mode

* fix: use enum instead of real string

* fix: lint error

Co-authored-by: 琚致远 <[email protected]>

feat: add tips when plugin type is auth and schemaType is not consumer (apache#1219)

Co-authored-by: 琚致远 <[email protected]>
  • Loading branch information
juzhiyuan authored and Jaycean committed Jan 6, 2021
1 parent 6ec1338 commit 24eb08c
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 32 deletions.
2 changes: 1 addition & 1 deletion api/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.3
master
17 changes: 11 additions & 6 deletions web/src/components/Plugin/PluginDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/
import React, { useEffect, useRef } from 'react';
import { Button, notification, PageHeader, Switch, Form, Select, Divider, Drawer } from 'antd';
import { Button, notification, PageHeader, Switch, Form, Select, Divider, Drawer, Alert } from 'antd';
import { useIntl } from 'umi';
import CodeMirror from '@uiw/react-codemirror';
import { js_beautify } from 'js-beautify';
Expand All @@ -29,6 +29,7 @@ type Props = {
type?: 'global' | 'scoped';
schemaType: PluginComponent.Schema;
initialData: object;
pluginList: PluginComponent.Meta[],
readonly?: boolean;
visible: boolean;
onClose?: () => void;
Expand Down Expand Up @@ -65,15 +66,17 @@ const PluginDetail: React.FC<Props> = ({
type = 'scoped',
schemaType = 'route',
visible,
pluginList = [],
readonly = false,
initialData = {},
onClose = () => {},
onChange = () => {},
onClose = () => { },
onChange = () => { },
}) => {
const { formatMessage } = useIntl();
const [form] = Form.useForm();
const ref = useRef<any>(null);
const data = initialData[name];
const data = initialData[name] || {};
const pluginType = pluginList.find(item => item.name === name)?.type

useEffect(() => {
form.setFieldsValue({ disable: initialData[name] && !initialData[name].disable });
Expand Down Expand Up @@ -149,7 +152,7 @@ const PluginDetail: React.FC<Props> = ({
placement="right"
closable={false}
onClose={onClose}
width={600}
width={700}
footer={
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
{' '}
Expand Down Expand Up @@ -204,7 +207,9 @@ const PluginDetail: React.FC<Props> = ({
<Divider orientation="left">Data Editor</Divider>
<PageHeader
title=""
subTitle={`Current Plugin: ${name}`}
subTitle={
(pluginType === 'auth' && schemaType !== 'consumer') ? <Alert message={`${name} does not require configuration`} type="warning" />
: <>Current plugin: {name}</>}
ghost={false}
extra={[
<Button
Expand Down
1 change: 1 addition & 0 deletions web/src/components/Plugin/PluginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ const PluginPage: React.FC<Props> = ({
visible={name !== NEVER_EXIST_PLUGIN_FLAG}
schemaType={schemaType}
initialData={initialData}
pluginList={pluginList}
onClose={() => {
setName(NEVER_EXIST_PLUGIN_FLAG);
}}
Expand Down
108 changes: 93 additions & 15 deletions web/src/pages/Route/components/DebugViews/DebugDrawView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import { Input, Select, Card, Tabs, Form, Drawer, Spin, notification } from 'antd';
import React, { useEffect, useState, useRef } from 'react';
import { Input, Select, Card, Tabs, Form, Drawer, Spin, notification, Radio } from 'antd';
import { useIntl } from 'umi';
import CodeMirror from '@uiw/react-codemirror';
import { PanelSection } from '@api7-dashboard/ui';
Expand All @@ -27,6 +27,8 @@ import {
DEFAULT_DEBUG_PARAM_FORM_DATA,
DEFAULT_DEBUG_AUTH_FORM_DATA,
PROTOCOL_SUPPORTED,
DEBUG_BODY_TYPE_SUPPORTED,
DEBUG_BODY_CODEMIRROR_MODE_SUPPORTED,
} from '../../constants';
import { DebugParamsView, AuthenticationView } from '.';
import { debugRoute } from '../../service';
Expand All @@ -48,32 +50,62 @@ const DebugDrawView: React.FC<RouteModule.DebugDrawProps> = (props) => {
const [responseCode, setResponseCode] = useState<string>();
const [loading, setLoading] = useState(false);
const [codeMirrorHeight, setCodeMirrorHeight] = useState<number | string>(50);
const bodyCodeMirrorRef = useRef<any>(null);
const [bodyType, setBodyType] = useState('none');
const methodWithoutBody = ['GET', 'HEAD'];
const [bodyCodeMirrorMode, setBodyCodeMirrorMode] = useState(DEBUG_BODY_CODEMIRROR_MODE_SUPPORTED[0].mode)

enum DebugBodyType {
None = 0,
FormUrlencoded,
Json,
RawInput,
}

const resetForms = () => {
queryForm.setFieldsValue(DEFAULT_DEBUG_PARAM_FORM_DATA);
bodyForm.setFieldsValue(DEFAULT_DEBUG_PARAM_FORM_DATA);
headerForm.setFieldsValue(DEFAULT_DEBUG_PARAM_FORM_DATA);
authForm.setFieldsValue(DEFAULT_DEBUG_AUTH_FORM_DATA);
setResponseCode(`${formatMessage({ id: 'page.route.debug.showResultAfterSendRequest' })}`);
setBodyType(DEBUG_BODY_TYPE_SUPPORTED[DebugBodyType.None]);
};

useEffect(() => {
resetForms();
}, []);

const transformBodyParamsFormData = (formData: RouteModule.debugRequestParamsFormData[]) => {
let transformData = {};
(formData || [])
.filter((data) => data.check)
.forEach((data) => {
transformData = {
...transformData,
[data.key]: data.value,
};
});
const transformBodyParamsFormData = () => {
let transformDataForm: string[];
let transformDataJson: object;
const formData: RouteModule.debugRequestParamsFormData[] = bodyForm.getFieldsValue().params;
switch (bodyType) {
case 'x-www-form-urlencoded':
transformDataForm = (formData || [])
.filter((data) => data.check)
.map((data) => {
return `${data.key}=${data.value}`
});

return transformData;
return transformDataForm.join('&');
case 'json':
transformDataJson = {};
(formData || [])
.filter((data) => data.check)
.forEach((data) => {
transformDataJson = {
...transformDataJson,
[data.key]: data.value,
};
});

return JSON.stringify(transformDataJson);
case 'raw input':
return bodyCodeMirrorRef.current.editor.getValue();
case 'none':
default:
return undefined;
}
};

const transformHeaderAndQueryParamsFormData = (
Expand Down Expand Up @@ -128,7 +160,7 @@ const DebugDrawView: React.FC<RouteModule.DebugDrawProps> = (props) => {
return;
}
const queryFormData = transformHeaderAndQueryParamsFormData(queryForm.getFieldsValue().params);
const bodyFormData = transformBodyParamsFormData(bodyForm.getFieldsValue().params);
const bodyFormData = transformBodyParamsFormData();
const pureHeaderFormData = transformHeaderAndQueryParamsFormData(
headerForm.getFieldsValue().params,
);
Expand Down Expand Up @@ -233,7 +265,53 @@ const DebugDrawView: React.FC<RouteModule.DebugDrawProps> = (props) => {
</TabPane>
{showBodyTab && (
<TabPane tab={formatMessage({ id: 'page.route.TabPane.bodyParams' })} key="body">
<DebugParamsView form={bodyForm} />
<Radio.Group onChange={(e) => {setBodyType(e.target.value)}} value={bodyType}>
{
DEBUG_BODY_TYPE_SUPPORTED.map((type) => (
<Radio value={type} key={type}>{type}</Radio>
))
}
</Radio.Group>
{bodyType === DEBUG_BODY_TYPE_SUPPORTED[DebugBodyType.RawInput] && <Select
size="small"
onChange={(value) => {
setBodyCodeMirrorMode(value)
}}
style={{ width: 100 }}
defaultValue={bodyCodeMirrorMode}>
{
DEBUG_BODY_CODEMIRROR_MODE_SUPPORTED.map((modeObj) =>(
<Select.Option key={modeObj.name} value={modeObj.mode}>{modeObj.name}</Select.Option>
))
}
</Select>}
<div style={{marginTop: 16}}>
{
(bodyType === DEBUG_BODY_TYPE_SUPPORTED[DebugBodyType.FormUrlencoded] || bodyType === DEBUG_BODY_TYPE_SUPPORTED[DebugBodyType.Json]) &&
<DebugParamsView form={bodyForm} />
}

{
(bodyType === DEBUG_BODY_TYPE_SUPPORTED[DebugBodyType.RawInput]) &&
<Form>
<Form.Item>
<CodeMirror
ref={bodyCodeMirrorRef}
height={250}
options={{
mode: bodyCodeMirrorMode,
readOnly: '',
lineWrapping: true,
lineNumbers: true,
showCursorWhenSelecting: true,
autofocus: true,
scrollbarStyle: null,
}}
/>
</Form.Item>
</Form>
}
</div>
</TabPane>
)}
</Tabs>
Expand Down
20 changes: 11 additions & 9 deletions web/src/pages/Route/components/DebugViews/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,23 @@
.ant-drawer-body {
padding: 16px;
}
.ant-radio-wrapper {
display: block;
height: 30px;
line-height: 30px;
}
.ant-form-item {
margin-bottom: 8px;
}
.ant-radio-group {
margin-right: 16px;
border-right: 1px solid #e0e0e0;
}
}
.authForm {
display: flex;
margin: 16px;
:global {
.ant-radio-wrapper {
display: block;
height: 30px;
line-height: 30px;
}
.ant-radio-group {
margin-right: 16px;
border-right: 1px solid #e0e0e0;
}
}
}
}
6 changes: 6 additions & 0 deletions web/src/pages/Route/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,14 @@ export const DEFAULT_DEBUG_PARAM_FORM_DATA = {
value: '',
},
],
type: 'json',
};

export const DEFAULT_DEBUG_AUTH_FORM_DATA = {
authType: 'none',
};

export const DEBUG_BODY_TYPE_SUPPORTED: RouteModule.DebugBodyType[]= ['none', 'x-www-form-urlencoded','json','raw input'];

// Note: codemirror mode: apl for text; javascript for json(need to format); xml for xml;
export const DEBUG_BODY_CODEMIRROR_MODE_SUPPORTED = [{name: 'Json', mode: 'javascript'}, {name: 'Text', mode: 'apl'}, {name: 'XML', mode:'xml'}]
8 changes: 7 additions & 1 deletion web/src/pages/Route/typing.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ declare namespace RouteModule {
// TODO: grpc and websocket
type debugRequest = {
url: string;
request_protocol: 'http' | 'https' | 'grpc' | 'websocket';
request_protocol: RequestProtocol | 'grpc';
method: string;
body_params?: any;
header_params?: any;
Expand All @@ -271,6 +271,12 @@ declare namespace RouteModule {
type DebugViewProps = {
form: FormInstance;
};
type DebugBodyType = 'none' | 'x-www-form-urlencoded' | 'json' | 'raw input';
type DebugDodyViewProps = {
form: FormInstance;
changeBodyParamsType:(type: DebugBodyType) => void;
codeMirrorRef: any;
};
type DebugDrawProps = {
visible: boolean;
onClose(): void;
Expand Down

0 comments on commit 24eb08c

Please sign in to comment.