This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new eb33046 feat: autocomplete when people input http header (#1679)
eb33046 is described below
commit eb3304606a28586c64b4358e2bfadbc627b83e75
Author: qian0817 <[email protected]>
AuthorDate: Mon Apr 12 23:36:54 2021 +0800
feat: autocomplete when people input http header (#1679)
---
web/cypress/integration/route/online-debug.spec.js | 21 ++++++
.../Route/components/DebugViews/DebugDrawView.tsx | 2 +-
.../components/DebugViews/DebugParamsView.tsx | 38 +++++++++--
web/src/pages/Route/constants.ts | 76 +++++++++++++++++-----
web/src/pages/Route/typing.d.ts | 1 +
5 files changed, 115 insertions(+), 23 deletions(-)
diff --git a/web/cypress/integration/route/online-debug.spec.js
b/web/cypress/integration/route/online-debug.spec.js
index 5f80575..f5de8a4 100644
--- a/web/cypress/integration/route/online-debug.spec.js
+++ b/web/cypress/integration/route/online-debug.spec.js
@@ -124,6 +124,27 @@ context('Online debug', () => {
});
});
+ it('should autocomplete header',function () {
+ cy.visit('/');
+ cy.contains(menuLocaleUS['menu.routes']).click();
+ const currentToken = localStorage.getItem('token');
+
+ // show online debug draw
+ cy.contains(routeLocaleUS['page.route.onlineDebug']).click();
+ cy.get(domSelector.debugDraw).should('be.visible');
+ cy.get(domSelector.headerTab).should('be.visible').click();
+
+ // show autocomplete
+ cy.get(domSelector.headerDataKey0).click({ force: true });
+ cy.get('.ant-select-item-option-content').contains('Accept').click();
+ cy.get('.anticon-minus-circle').click()
+
+ // autocomplete should ingore case
+ cy.get(domSelector.headerDataKey0).type('auth').click({ force: true });
+
cy.get('.ant-select-item-option-content').contains('Authorization').click();
+ cy.get(domSelector.headerDataValue0).type(currentToken);
+ })
+
it('should debug POST request with file successfully', function () {
cy.visit('/');
cy.contains(menuLocaleUS['menu.routes']).click();
diff --git a/web/src/pages/Route/components/DebugViews/DebugDrawView.tsx
b/web/src/pages/Route/components/DebugViews/DebugDrawView.tsx
index 09300b6..60dd5de 100644
--- a/web/src/pages/Route/components/DebugViews/DebugDrawView.tsx
+++ b/web/src/pages/Route/components/DebugViews/DebugDrawView.tsx
@@ -317,7 +317,7 @@ const DebugDrawView: React.FC<RouteModule.DebugDrawProps> =
(props) => {
<AuthenticationView form={authForm} />
</TabPane>
<TabPane data-cy='header' tab={formatMessage({ id:
'page.route.TabPane.headerParams' })} key="header">
- <DebugParamsView form={headerForm} name='headerForm'/>
+ <DebugParamsView form={headerForm} name='headerForm'
inputType="header"/>
</TabPane>
{showBodyTab && (
<TabPane data-cy='body' tab={formatMessage({ id:
'page.route.TabPane.bodyParams' })} key="body">
diff --git a/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx
b/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx
index 64b04a6..85fc924 100644
--- a/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx
+++ b/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx
@@ -14,16 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React from 'react';
-import { Form, Input, Row, Col, Checkbox } from 'antd';
+import React, { useState } from 'react';
+import { Form, Input, Row, Col, Checkbox, AutoComplete } from 'antd';
import { useIntl } from 'umi';
import { MinusCircleOutlined } from '@ant-design/icons';
+import { HEADER_LIST } from '@/pages/Route/constants';
import styles from './index.less';
+const { Option } = AutoComplete;
+
const DebugParamsView: React.FC<RouteModule.DebugViewProps> = (props) => {
const { formatMessage } = useIntl();
+ const allSelectOptions = props.inputType === "header" ? HEADER_LIST : []
+ const [result, setResult] = useState<string[]>(allSelectOptions);
+
+ const onSearch = (value: string) => {
+ setResult(allSelectOptions.filter((option) =>
option.toLowerCase().startsWith(value.toLowerCase())))
+ }
+
return (
<Form name={props.name} className={styles.routeDebugDraw}
form={props.form}>
<Form.List name="params">
@@ -34,7 +44,9 @@ const DebugParamsView: React.FC<RouteModule.DebugViewProps> =
(props) => {
<Row gutter={16} key={field.name}>
<Col span={1}>
<Form.Item
+ {...field}
name={[field.name, 'check']}
+ fieldKey={[field.fieldKey, 'check']}
style={{ textAlign: 'right' }}
valuePropName="checked"
>
@@ -42,8 +54,12 @@ const DebugParamsView: React.FC<RouteModule.DebugViewProps>
= (props) => {
</Form.Item>
</Col>
<Col span={8}>
- <Form.Item name={[field.name, 'key']}>
- <Input
+ <Form.Item
+ {...field}
+ name={[field.name, 'key']}
+ fieldKey={[field.fieldKey, 'key']}>
+ <AutoComplete
+ onSearch={onSearch}
placeholder={formatMessage({ id:
'page.route.input.placeholder.paramKey' })}
onChange={() => {
// only last line key field input can trigger add
new line event
@@ -54,12 +70,20 @@ const DebugParamsView: React.FC<RouteModule.DebugViewProps>
= (props) => {
prevData.params[index].check = true;
props.form.setFieldsValue(prevData);
}
- }}
- />
+ }}>
+ {result.map((value) => (
+ <Option key={value} value={value}>
+ {value}
+ </Option>
+ ))}
+ </AutoComplete>
</Form.Item>
</Col>
<Col span={8}>
- <Form.Item name={[field.name, 'value']}>
+ <Form.Item
+ {...field}
+ name={[field.name, 'value']}
+ fieldKey={[field.fieldKey, 'value']}>
<Input
placeholder={formatMessage({
id: 'page.route.input.placeholder.paramValue',
diff --git a/web/src/pages/Route/constants.ts b/web/src/pages/Route/constants.ts
index a343067..ecad67e 100644
--- a/web/src/pages/Route/constants.ts
+++ b/web/src/pages/Route/constants.ts
@@ -90,23 +90,69 @@ export const INIT_CHART = {
hovered: {},
};
-export const HASH_KEY_LIST = [
- 'remote_addr',
- 'host',
- 'uri',
- 'server_name',
- 'server_addr',
- 'request_uri',
- 'query_string',
- 'remote_port',
- 'hostname',
- 'arg_id',
-];
-
-export const HASH_ON_LIST = ['vars', 'header', 'cookie', 'consumer'];
-
export const AUTH_LIST = ['basic-auth', 'jwt-auth', 'key-auth'];
+export const HEADER_LIST = [
+ "A-IM",
+ "Accept",
+ "Accept-Charset",
+ "Accept-Datetime",
+ "Accept-Encoding",
+ "Accept-Language",
+ "Access-Control-Request-Method",
+ "Access-Control-Request-Headers",
+ "Allow",
+ "Authorization",
+ "Cache-Control",
+ "Connection",
+ "Content-Encoding",
+ "Content-Length",
+ "Content-MD5",
+ "Content-Type",
+ "Cookie",
+ "DNT",
+ "Date",
+ "Expect",
+ "Forwarded",
+ "From",
+ "Front-End-Https",
+ "Host",
+ "HTTP2-Settings",
+ "If-Match",
+ "If-Modified-Since",
+ "If-None-Match",
+ "If-Range",
+ "If-Unmodified-Since",
+ "Max-Forwards",
+ "Origin",
+ "Pragma",
+ "Prefer",
+ "Proxy-Authorization",
+ "Proxy-Connection",
+ "Range",
+ "Referer",
+ "Save-Data",
+ "TE",
+ "Trailer",
+ "Transfer-Encoding",
+ "Upgrade",
+ "Upgrade-Insecure-Requests",
+ "User-Agent",
+ "Via",
+ "Warning",
+ "X-ATT-DeviceId",
+ "X-Correlation-ID",
+ "X-Csrf-Token",
+ "X-Forwarded-For",
+ "X-Forwarded-Host",
+ "X-Forwarded-Proto",
+ "X-Http-Method-Override",
+ "X-Request-ID",
+ "X-Requested-With",
+ "X-UIDH",
+ "X-Wap-Profile",
+];
+
export const PROTOCOL_SUPPORTED:
RouteModule.debugRequest['request_protocol'][] = ['http', 'https'];
export const DEFAULT_DEBUG_PARAM_FORM_DATA = {
diff --git a/web/src/pages/Route/typing.d.ts b/web/src/pages/Route/typing.d.ts
index 5fed522..2961a7a 100644
--- a/web/src/pages/Route/typing.d.ts
+++ b/web/src/pages/Route/typing.d.ts
@@ -257,6 +257,7 @@ declare namespace RouteModule {
type DebugViewProps = {
form: FormInstance;
name?: string;
+ inputType?: 'param' | 'header';
};
type DebugBodyType = 'none' | 'x-www-form-urlencoded' | 'raw input' |
'form-data';
type DebugDrawProps = {