You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2020/06/04 00:45:41 UTC

[incubator-apisix-dashboard] branch next updated: add: redirect (#238)

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 <31...@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: 琚致远 <ju...@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';