This is an automated email from the ASF dual-hosted git repository.

liuxiran 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 cbcac5f  feat: support post args advanced match (#2231)
cbcac5f is described below

commit cbcac5f74b1da44540603493f0f4bfe417de414b
Author: Zeping Bai <bzp2...@apache.org>
AuthorDate: Thu Dec 2 10:21:23 2021 +0800

    feat: support post args advanced match (#2231)
---
 ...route-with-advanced-matching-conditions.spec.js | 10 ++++-----
 .../Route/components/Step1/MatchingRulesView.tsx   | 26 +++++++++++++++++++---
 web/src/pages/Route/locales/en-US.ts               |  9 +++++++-
 web/src/pages/Route/locales/zh-CN.ts               |  8 ++++++-
 web/src/pages/Route/transform.ts                   | 11 +++++----
 web/src/pages/Route/typing.d.ts                    |  2 +-
 6 files changed, 50 insertions(+), 16 deletions(-)

diff --git 
a/web/cypress/integration/route/create-route-with-advanced-matching-conditions.spec.js
 
b/web/cypress/integration/route/create-route-with-advanced-matching-conditions.spec.js
index ae4a2fc..45cc98d 100644
--- 
a/web/cypress/integration/route/create-route-with-advanced-matching-conditions.spec.js
+++ 
b/web/cypress/integration/route/create-route-with-advanced-matching-conditions.spec.js
@@ -23,7 +23,6 @@ context('Create Route with advanced matching conditions', () 
=> {
     nodes_0_port: '#submitNodes_0_port',
     nodes_0_weight: '#submitNodes_0_weight',
     deleteAlert: '.ant-modal-body',
-    notificationCloseIcon: '.ant-notification-close-icon',
     notification: '.ant-notification-notice-message',
     parameterPosition: '#position',
     ruleCard: '.ant-modal',
@@ -79,7 +78,7 @@ context('Create Route with advanced matching conditions', () 
=> {
             .click()
             .then(() => {
               cy.get('.ant-select-dropdown').within(() => {
-                cy.contains('Build-in').should('be.visible').click();
+                cy.contains('Built-in').should('be.visible').click();
               });
             });
           cy.get(selector.ruleCard).within(() => {
@@ -94,7 +93,7 @@ context('Create Route with advanced matching conditions', () 
=> {
     cy.get(selector.advancedMatchingTable).should('exist');
     cy.wrap(opreatorList).each((operator, index) => {
       cy.get(selector.advancedMatchingTableCell).within(() => {
-        cy.contains('td', 'Build-in Parameter').should('be.visible');
+        cy.contains('td', 'Built-in Parameter').should('be.visible');
         cy.contains('td', data.matchingParamName).should('be.visible');
         cy.contains('td', matchingValueList1[index]).should('be.visible');
       });
@@ -128,14 +127,14 @@ context('Create Route with advanced matching conditions', 
() => {
           });
       });
       cy.get(selector.ruleCard).within(() => {
-        cy.get(`[title="Build-in Parameter"]`).should('have.class', 
'ant-select-selection-item');
+        cy.get(`[title="Built-in Parameter"]`).should('have.class', 
'ant-select-selection-item');
         cy.get(selector.name).clear().type(data.matchingParamName);
         cy.get(`[title="${opreator}"]`).should('have.class', 
'ant-select-selection-item');
         cy.get(selector.value).clear().type(matchingValueList2[index]);
         cy.contains('Confirm').click();
       });
       cy.get(selector.advancedMatchingTableCell).within(() => {
-        cy.contains('td', 'Build-in Parameter').should('be.visible');
+        cy.contains('td', 'Built-in Parameter').should('be.visible');
         cy.contains('td', data.matchingParamName).should('be.visible');
         cy.contains('td', matchingValueList2[index]).should('be.visible');
       });
@@ -183,6 +182,5 @@ context('Create Route with advanced matching conditions', 
() => {
         cy.contains('OK').click();
       });
     cy.get(selector.notification).should('contain', data.deleteRouteSuccess);
-    cy.get(selector.notificationCloseIcon).click();
   });
 });
diff --git a/web/src/pages/Route/components/Step1/MatchingRulesView.tsx 
b/web/src/pages/Route/components/Step1/MatchingRulesView.tsx
index ccbb97c..90760a3 100644
--- a/web/src/pages/Route/components/Step1/MatchingRulesView.tsx
+++ b/web/src/pages/Route/components/Step1/MatchingRulesView.tsx
@@ -15,11 +15,13 @@
  * limitations under the License.
  */
 import React, { useState } from 'react';
-import { Button, Table, Modal, Form, Select, Input, Space, notification } from 
'antd';
+import { Button, Table, Modal, Form, Select, Input, Space, notification, 
Typography } from 'antd';
 import { useIntl } from 'umi';
 
 import PanelSection from '@/components/PanelSection';
 
+const { Title, Text } = Typography;
+
 const MatchingRulesView: React.FC<RouteModule.Step1PassProps> = ({
   advancedMatchingRules,
   disabled,
@@ -113,11 +115,14 @@ const MatchingRulesView: 
React.FC<RouteModule.Step1PassProps> = ({
           case 'arg':
             renderText = formatMessage({ id: 'page.route.requestParameter' });
             break;
+          case 'post_arg':
+            renderText = formatMessage({ id: 'page.route.postRequestParameter' 
});
+            break;
           case 'cookie':
             renderText = 'Cookie';
             break;
           case 'buildin':
-            renderText = formatMessage({ id: 'page.route.buildinParameter' });
+            renderText = formatMessage({ id: 'page.route.builtinParameter' });
             break;
           default:
             renderText = '';
@@ -208,8 +213,13 @@ const MatchingRulesView: 
React.FC<RouteModule.Step1PassProps> = ({
             >
               <Option value="http">{formatMessage({ id: 
'page.route.httpRequestHeader' })}</Option>
               <Option value="arg">{formatMessage({ id: 
'page.route.requestParameter' })}</Option>
+              <Option value="post_arg">
+                {formatMessage({ id: 'page.route.postRequestParameter' })}
+              </Option>
               <Option value="cookie">Cookie</Option>
-              <Option value="buildin">{formatMessage({ id: 
'page.route.buildinParameter' })}</Option>
+              <Option value="buildin">
+                {formatMessage({ id: 'page.route.builtinParameter' })}
+              </Option>
             </Select>
           </Form.Item>
           <Form.Item
@@ -289,6 +299,16 @@ const MatchingRulesView: 
React.FC<RouteModule.Step1PassProps> = ({
           >
             <Input />
           </Form.Item>
+          <Typography>
+            <Title level={5}>{formatMessage({ id: 
'page.route.advanced-match.message' })}</Title>
+            <Text>
+              {formatMessage({ id: 
'page.route.advanced-match.tips.requestParameter' })}
+              <br />
+              {formatMessage({ id: 
'page.route.advanced-match.tips.postRequestParameter' })}
+              <br />
+              {formatMessage({ id: 
'page.route.advanced-match.tips.builtinParameter' })}
+            </Text>
+          </Typography>
         </Form>
       </Modal>
     );
diff --git a/web/src/pages/Route/locales/en-US.ts 
b/web/src/pages/Route/locales/en-US.ts
index 23c9184..db78212 100644
--- a/web/src/pages/Route/locales/en-US.ts
+++ b/web/src/pages/Route/locales/en-US.ts
@@ -23,7 +23,8 @@ export default {
   'page.route.parameterPosition': 'Parameter Position',
   'page.route.httpRequestHeader': 'HTTP Request Header',
   'page.route.requestParameter': 'Request Parameter',
-  'page.route.buildinParameter': 'Build-in Parameter',
+  'page.route.postRequestParameter': 'POST Request Parameter',
+  'page.route.builtinParameter': 'Built-in Parameter',
   'page.route.parameterName': 'Parameter Name',
   'page.route.operationalCharacter': 'Operational Character',
   'page.route.equal': 'Equal(==)',
@@ -182,6 +183,12 @@ export default {
     'If you do not bind the service, you must set the Upstream (Step 2)',
   'page.route.advanced-match.tooltip':
     'It supports route matching through request headers, request parameters 
and cookies, and can be applied to scenarios such as grayscale publishing and 
blue-green testing.',
+  'page.route.advanced-match.message': 'Tips',
+  'page.route.advanced-match.tips.requestParameter': 'Request Parameter:Query 
of the request URL',
+  'page.route.advanced-match.tips.postRequestParameter':
+    'POST Request Parameter:Only support x-www-form-urlencoded form',
+  'page.route.advanced-match.tips.builtinParameter':
+    'Build-in Parameter:Nginx internal parameters',
 
   'page.route.fields.custom.redirectOption.tooltip': 'This is related to 
redirect plugin',
   'page.route.fields.service_id.tooltip': 'Bind Service object to reuse their 
configuration.',
diff --git a/web/src/pages/Route/locales/zh-CN.ts 
b/web/src/pages/Route/locales/zh-CN.ts
index 30112ab..64adf5e 100644
--- a/web/src/pages/Route/locales/zh-CN.ts
+++ b/web/src/pages/Route/locales/zh-CN.ts
@@ -19,7 +19,8 @@ export default {
   'page.route.parameterPosition': '参数位置',
   'page.route.httpRequestHeader': 'HTTP 请求头',
   'page.route.requestParameter': '请求参数',
-  'page.route.buildinParameter': '内置参数',
+  'page.route.postRequestParameter': 'POST 请求参数',
+  'page.route.builtinParameter': '内置参数',
   'page.route.parameterName': '参数名称',
   'page.route.operationalCharacter': '运算符',
   'page.route.equal': '等于(==)',
@@ -178,6 +179,11 @@ export default {
   'page.route.fields.service_id.without-upstream': '如果不绑定服务,则必须设置上游服务(步骤 2)',
   'page.route.advanced-match.tooltip':
     '支持通过请求头,请求参数、Cookie 进行路由匹配,可应用于灰度发布,蓝绿测试等场景。',
+  'page.route.advanced-match.message': '提示',
+  'page.route.advanced-match.tips.requestParameter': '请求参数:请求 URL 中的 Query 部分',
+  'page.route.advanced-match.tips.postRequestParameter':
+    'POST 请求参数:仅支持 POST x-www-form-urlencoded 表单',
+  'page.route.advanced-match.tips.builtinParameter': '内置参数:Nginx 内部参数',
 
   'page.route.fields.custom.redirectOption.tooltip': '在此配置 redirect 插件',
   'page.route.fields.service_id.tooltip': '绑定服务(Service)对象,以便复用其中的配置。',
diff --git a/web/src/pages/Route/transform.ts b/web/src/pages/Route/transform.ts
index d1fbd30..a8a4f8a 100644
--- a/web/src/pages/Route/transform.ts
+++ b/web/src/pages/Route/transform.ts
@@ -160,6 +160,9 @@ export const transformStepData = ({
         case 'arg':
           key = `arg_${name}`;
           break;
+        case 'post_arg':
+          key = `post_arg_${name}`;
+          break;
         default:
           key = `${name}`;
       }
@@ -272,11 +275,11 @@ const transformVarsToRules = (
   data.map(([key, operator, value]) => {
     let position = '';
     let name = '';
-    const regex = new RegExp('^(cookie|http|arg)_.+');
+    const regex = new RegExp('^(cookie|http|arg|post_arg)_.+');
     if (regex.test(key)) {
-      [, position, name] = key.split(/^(cookie|http|arg)_/);
-    }else {
-      position = "buildin";
+      [, position, name] = key.split(/^(cookie|http|arg|post_arg)_/);
+    } else {
+      position = 'buildin';
       name = key;
     }
     return {
diff --git a/web/src/pages/Route/typing.d.ts b/web/src/pages/Route/typing.d.ts
index 4870e38..5d16958 100644
--- a/web/src/pages/Route/typing.d.ts
+++ b/web/src/pages/Route/typing.d.ts
@@ -17,7 +17,7 @@
 declare namespace RouteModule {
   type Operator = '==' | '~=' | '>' | '<' | '~~' | '~*' | 'IN' | 'HAS' | '!';
 
-  type VarPosition = 'arg' | 'http' | 'cookie' | 'buildin';
+  type VarPosition = 'arg' | 'post_arg' | 'http' | 'cookie' | 'buildin';
 
   type RequestProtocol = 'https' | 'http' | 'websocket';
 

Reply via email to