This is an automated email from the ASF dual-hosted git repository. juzhiyuan pushed a commit to branch next in repository https://gitbox.apache.org/repos/asf/incubator-apisix-dashboard.git
The following commit(s) were added to refs/heads/next by this push: new d4dbc30 add: redirect (#238) d4dbc30 is described below commit d4dbc30edc9202d53e29029cbb1edc5a9ffef0f6 Author: litesun <31329157+lite...@users.noreply.github.com> AuthorDate: Thu Jun 4 08:45:33 2020 +0800 add: redirect (#238) * feat: limit upload file * feat: intercept default upload api request * feat: limit upload file type * fix: show file when parse SSL file fail * feat: add search feature * feat: format code * fix: remove list item not work * feat: remove relatedRouting * feat: add routes step1 page * feat: update route * feat: format code * feat: update * feat: update * feat: add checkbox rule * feat: handle Modal close event * feat: format code * feat: add page skip * feat: format code * merge * feat: clean code * fix: step4 error * feat: add edit modal * feat: add form validation * fix: step4 lose data * fix: step4 edit * add: WebSocket switch * feat: https methods list Validation * fix: timeout * clean code * add: redirect * fix: force https * add: redirect * fix: wrong redirectURI typing * Update RequestConfigView.tsx * Update RequestConfigView.tsx Co-authored-by: 琚致远 <juzhiy...@apache.org> --- src/pages/Routes/Create.tsx | 6 ++- .../Routes/components/Step1/RequestConfigView.tsx | 46 ++++++++++++++++++---- src/pages/Routes/components/Step1/index.tsx | 10 ++++- src/pages/Routes/constants.ts | 3 ++ src/pages/Routes/transform.ts | 21 ++++++++-- src/pages/Routes/typing.d.ts | 24 +++++++---- 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/pages/Routes/Create.tsx b/src/pages/Routes/Create.tsx index 6584cf4..3196fc3 100644 --- a/src/pages/Routes/Create.tsx +++ b/src/pages/Routes/Create.tsx @@ -54,8 +54,10 @@ const Create: React.FC = (props) => { <Step1 data={routeData} form={form1} - onChange={(_data: RouteModule.Step1Data) => { - setStep1Data(_data); + onChange={(params: RouteModule.Step1Data) => { + requestAnimationFrame(() => { + setStep1Data(params); + }); }} /> ); diff --git a/src/pages/Routes/components/Step1/RequestConfigView.tsx b/src/pages/Routes/components/Step1/RequestConfigView.tsx index e3670eb..3dbcacb 100644 --- a/src/pages/Routes/components/Step1/RequestConfigView.tsx +++ b/src/pages/Routes/components/Step1/RequestConfigView.tsx @@ -1,7 +1,6 @@ import React from 'react'; import Form from 'antd/es/form'; -import { Checkbox, Button, Input, Switch } from 'antd'; -import { CheckboxValueType } from 'antd/lib/checkbox/Group'; +import { Checkbox, Button, Input, Switch, Select, Row, Col } from 'antd'; import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons'; import { @@ -14,14 +13,15 @@ import PanelSection from '../PanelSection'; interface Props extends RouteModule.Data {} -const RequestConfigView: React.FC<Props> = ({ data, disabled, onChange }) => { - const { protocols } = data.step1Data; +const { Option } = Select; +const RequestConfigView: React.FC<Props> = ({ data, disabled, onChange }) => { + const { step1Data } = data; + const { protocols } = step1Data; const onProtocolChange = (e: CheckboxValueType[]) => { if (!e.includes('http') && !e.includes('https')) return; onChange({ ...data.step1Data, protocols: e }); }; - const renderHosts = () => ( <Form.List name="hosts"> {(fields, { add, remove }) => { @@ -119,7 +119,7 @@ const RequestConfigView: React.FC<Props> = ({ data, disabled, onChange }) => { return ( <PanelSection title="请求基础定义"> - <Form.Item label="协议" name="protocols" rules={[{ required: true, message: '请勾选协议' }]}> + <Form.Item label="协议" name="protocols" rules={[{ required: true, message: '请选择协议' }]}> <Checkbox.Group disabled={disabled} options={['http', 'https']} @@ -135,10 +135,42 @@ const RequestConfigView: React.FC<Props> = ({ data, disabled, onChange }) => { <Form.Item label="HTTP 方法" name="methods" - rules={[{ required: true, message: '请勾选 HTTP 方法' }]} + rules={[{ required: true, message: '请选择 HTTP 方法' }]} > <Checkbox.Group options={HTTP_METHOD_OPTION_LIST} disabled={disabled} /> </Form.Item> + <Form.Item label="redirect" name="redirect" valuePropName="checked"> + <Switch disabled={disabled} /> + </Form.Item> + {step1Data.redirect && ( + <> + <Form.Item label="强制 HTTPS" valuePropName="checked" name="forceHttps"> + <Switch disabled={disabled || step1Data.protocols.includes('HTTPS')} /> + </Form.Item> + {!step1Data.forceHttps && ( + <Form.Item label="自定义参数" required> + <Row gutter={10}> + <Col> + <Form.Item name="redirectURI" rules={[{ required: true, message: '请输入 URI' }]}> + <Input placeholder="请输入 URI" disabled={disabled} /> + </Form.Item> + </Col> + <Col span={6}> + <Form.Item + name="redirectCode" + rules={[{ required: true, message: '请选择状态码' }]} + > + <Select disabled={disabled}> + <Option value="301">301</Option> + <Option value="302">302</Option> + </Select> + </Form.Item> + </Col> + </Row> + </Form.Item> + )} + </> + )} </PanelSection> ); }; diff --git a/src/pages/Routes/components/Step1/index.tsx b/src/pages/Routes/components/Step1/index.tsx index 60aaad8..150708f 100644 --- a/src/pages/Routes/components/Step1/index.tsx +++ b/src/pages/Routes/components/Step1/index.tsx @@ -14,7 +14,7 @@ interface Props extends RouteModule.Data { } const Step1: React.FC<Props> = (props) => { - const { data, form } = props; + const { data, form, onChange } = props; return ( <> @@ -23,6 +23,14 @@ const Step1: React.FC<Props> = (props) => { form={form} layout="horizontal" className={styles.stepForm} + onValuesChange={(field, value) => { + if (field.protocols?.includes('HTTPS')) { + form.setFieldsValue({ forceHttps: false }); + onChange({ ...data.step1Data, ...value, forceHttps: false }); + return; + } + onChange({ ...data.step1Data, ...value }); + }} initialValues={data.step1Data} > <MetaView {...props} /> diff --git a/src/pages/Routes/constants.ts b/src/pages/Routes/constants.ts index 0f87b3d..fade6a1 100644 --- a/src/pages/Routes/constants.ts +++ b/src/pages/Routes/constants.ts @@ -26,10 +26,13 @@ export const FORM_ITEM_WITHOUT_LABEL = { export const DEFAULT_STEP_1_DATA: RouteModule.Step1Data = { name: '', + desc: '', protocols: ['http', 'https'], websocket: false, hosts: [''], paths: [], + redirect: false, + forceHttps: false, methods: HTTP_METHOD_OPTION_LIST, advancedMatchingRules: [], }; diff --git a/src/pages/Routes/transform.ts b/src/pages/Routes/transform.ts index 7d36f22..0842978 100644 --- a/src/pages/Routes/transform.ts +++ b/src/pages/Routes/transform.ts @@ -13,6 +13,18 @@ export const transformStepData = ({ upstream_header[header.header_name] = header.header_value; }); + let redirect: RouteModule.Redirect = {}; + if (step1Data.redirect) { + if (step1Data.forceHttps) { + redirect = { redirect_to_https: true }; + } else { + redirect = { + code: step1Data.redirectCode, + uri: step1Data.redirectURI, + }; + } + } + let { protocols } = step1Data; if (step1Data.websocket) { protocols = protocols.concat('websocket'); @@ -25,9 +37,7 @@ export const transformStepData = ({ priority: 0, protocols, uris: step1Data.paths, - redirect: { - redirect_to_https: true, - }, + redirect, vars: step1Data.advancedMatchingRules.map((rule) => { const { operator, position, name, value } = rule; let key = ''; @@ -62,7 +72,10 @@ export const transformStepData = ({ 'upstreamHeaderList', 'websocket', 'timeout', - ]); + 'redirect', + 'redirectURI', + 'redirectCode', + ]) as RouteModule.Body; }; const transformVarsToRules = ( diff --git a/src/pages/Routes/typing.d.ts b/src/pages/Routes/typing.d.ts index fcbcb25..5024e20 100644 --- a/src/pages/Routes/typing.d.ts +++ b/src/pages/Routes/typing.d.ts @@ -22,6 +22,10 @@ declare namespace RouteModule { hosts: string[]; paths: string[]; methods: HttpMethod[]; + redirect: boolean; + forceHttps: boolean; + redirectURI?: string; + redirectCode?: boolean; advancedMatchingRules: MatchingRule[]; }; @@ -70,6 +74,17 @@ declare namespace RouteModule { type ModalType = 'CREATE' | 'EDIT'; + type Redirect = + | { + redirect_to_https: boolean; + code: 301 | 302; + uri: string; + } + | { + redirect_to_https: boolean; + } + | {}; + // Request Body or Response Data for API type Body = { id?: number; @@ -80,14 +95,7 @@ declare namespace RouteModule { uris: string[]; hosts: string[]; protocols: RequestProtocol[]; - redirect: - | { - code: 301 | 302; - uri: string; - } - | { - redirect_to_https?: boolean; - }; + redirect: Redirect; vars: [string, Operator, string][]; upstream: { type: 'roundrobin' | 'chash';