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 8fefd80  feat: update naming (#224)
8fefd80 is described below

commit 8fefd8023b04c15643e8c10c30201deeb34b7277
Author: 琚致远 <[email protected]>
AuthorDate: Mon Jun 1 00:14:45 2020 +0800

    feat: update naming (#224)
    
    * feat: update naming
    
    * feat: added Step3Data
    
    * feat: set active status
---
 src/pages/Routes/Create.tsx                        | 32 ++++++++-----
 .../Routes/components/CreateStep3/CreateStep3.tsx  | 54 ++++++++++++++++------
 .../Routes/components/CreateStep3/PluginDrawer.tsx | 32 ++++++++-----
 src/pages/Routes/components/Step1/index.tsx        | 10 ++--
 src/pages/Routes/typing.d.ts                       | 17 +++++--
 5 files changed, 97 insertions(+), 48 deletions(-)

diff --git a/src/pages/Routes/Create.tsx b/src/pages/Routes/Create.tsx
index 28e2b89..f007825 100644
--- a/src/pages/Routes/Create.tsx
+++ b/src/pages/Routes/Create.tsx
@@ -8,7 +8,7 @@ import CreateStep3 from './components/CreateStep3';
 const { Step } = Steps;
 
 const Create: React.FC = () => {
-  const [step1Data, setStep1Data] = useState<RoutesModule.Step1DataProps>({
+  const [step1Data, setStep1Data] = useState<RouteModule.Step1Data>({
     name: '',
     protocol: [],
     hosts: [''],
@@ -17,19 +17,22 @@ const Create: React.FC = () => {
     advancedMatchingRules: [],
   });
 
+  const [step3Data, setStep3Data] = useState<RouteModule.Step3Data>({
+    plugins: {
+      'limit-count': {
+        count: 2,
+        time_window: 60,
+        rejected_code: 503,
+        key: 'remote_addr',
+      },
+    },
+  });
+
   const [currentStep] = useState(2);
   const [stepHeader] = useState(['定义 API 请求', '定义 API 后端服务', '插件配置', '预览']);
   const data = {
     step1Data,
-  };
-
-  const handleChange = (step: number, params: RoutesModule.Step1DataProps) => {
-    switch (step) {
-      case 0:
-        setStep1Data({ ...step1Data, ...params });
-        break;
-      default:
-    }
+    step3Data,
   };
 
   const renderStep = () => {
@@ -38,11 +41,16 @@ const Create: React.FC = () => {
         return (
           <Step1
             data={data}
-            onChange={(params: RoutesModule.Step1DataProps) => 
handleChange(currentStep, params)}
+            onChange={(params: RouteModule.Step1Data) => setStep1Data({ 
...step1Data, ...params })}
           />
         );
       case 2:
-        return <CreateStep3 />;
+        return (
+          <CreateStep3
+            data={data}
+            onChange={(params: RouteModule.Step3Data) => setStep3Data({ 
...step3Data, ...params })}
+          />
+        );
       default:
         return null;
     }
diff --git a/src/pages/Routes/components/CreateStep3/CreateStep3.tsx 
b/src/pages/Routes/components/CreateStep3/CreateStep3.tsx
index 8526b34..199966b 100644
--- a/src/pages/Routes/components/CreateStep3/CreateStep3.tsx
+++ b/src/pages/Routes/components/CreateStep3/CreateStep3.tsx
@@ -1,5 +1,4 @@
-import React, { useState } from 'react';
-import { Card } from 'antd';
+import React, { useState, useEffect } from 'react';
 import { SettingOutlined, LinkOutlined } from '@ant-design/icons';
 
 import { pluginList } from '@/components/PluginForm';
@@ -7,6 +6,8 @@ import PanelSection from '../PanelSection';
 import PluginDrawer from './PluginDrawer';
 import PluginCard from './PluginCard';
 
+interface Props extends RouteModule.Data {}
+
 const sectionStyle = {
   display: 'grid',
   gridTemplateColumns: 'repeat(3, 33.333%)',
@@ -14,25 +15,44 @@ const sectionStyle = {
   gridColumnGap: 10,
 };
 
-const CreateStep3: React.FC = () => {
-  const [currentPlugin, setCurrentPlugin] = useState<string | undefined>();
+const CreateStep3: React.FC<Props> = ({ data }) => {
+  // NOTE: Plugin in blacklist WILL NOT be shown on Step3.
+  const pluginBlackList = ['redirect'];
+
+  const list = pluginList.filter(({ name }) => 
!pluginBlackList.includes(name));
+  const [activeList, setActiveList] = useState<PluginForm.PluginProps[]>([]);
+  const [inactiveList, setInactiveList] = 
useState<PluginForm.PluginProps[]>([]);
 
-  // TODO: 设置插件黑名单(不展示的插件)
-  // TODO: 获取 Route 已启用插件
-  // TODO: 拆分已启用、未启用插件
+  useEffect(() => {
+    const pluginKeys = Object.keys(data.step3Data.plugins || []);
+    setActiveList(list.filter((item) => pluginKeys.includes(item.name)));
+    setInactiveList(list.filter((item) => !pluginKeys.includes(item.name)));
+  }, [data.step3Data.plugins]);
+
+  const [currentPlugin, setCurrentPlugin] = useState<string | undefined>();
 
   return (
     <>
       <PanelSection title="已启用" style={sectionStyle}>
-        <Card
-          style={{ width: 300 }}
-          actions={[<SettingOutlined onClick={() => setCurrentPlugin('')} />]}
-        >
-          <Card.Meta title="插件名称" description="插件描述" />
-        </Card>
+        {activeList.map(({ name }) => (
+          <PluginCard
+            name={name}
+            actions={[
+              <SettingOutlined onClick={() => setCurrentPlugin(name)} />,
+              <LinkOutlined
+                onClick={() =>
+                  window.open(
+                    
`https://github.com/apache/incubator-apisix/blob/master/doc/plugins/${name}.md`,
+                  )
+                }
+              />,
+            ]}
+            key={name}
+          />
+        ))}
       </PanelSection>
       <PanelSection title="未启用" style={sectionStyle}>
-        {pluginList.map(({ name }) => (
+        {inactiveList.map(({ name }) => (
           <PluginCard
             name={name}
             actions={[
@@ -49,7 +69,11 @@ const CreateStep3: React.FC = () => {
           />
         ))}
       </PanelSection>
-      <PluginDrawer name={currentPlugin} onFinish={() => {}} />
+      <PluginDrawer
+        name={currentPlugin}
+        active={Boolean(activeList.find((item) => item.name === 
currentPlugin))}
+        onFinish={() => {}}
+      />
     </>
   );
 };
diff --git a/src/pages/Routes/components/CreateStep3/PluginDrawer.tsx 
b/src/pages/Routes/components/CreateStep3/PluginDrawer.tsx
index db00f5f..2656674 100644
--- a/src/pages/Routes/components/CreateStep3/PluginDrawer.tsx
+++ b/src/pages/Routes/components/CreateStep3/PluginDrawer.tsx
@@ -3,9 +3,11 @@ import { Drawer, Button } from 'antd';
 
 import PluginForm from '@/components/PluginForm';
 
-interface Props extends PluginForm.Props {}
+interface Props extends PluginForm.Props {
+  active?: boolean;
+}
 
-const PluginDrawer: React.FC<Props> = ({ name, ...rest }) => {
+const PluginDrawer: React.FC<Props> = ({ name, active, ...rest }) => {
   const [visiable, setVisiable] = useState(false);
 
   useEffect(() => {
@@ -23,15 +25,23 @@ const PluginDrawer: React.FC<Props> = ({ name, ...rest }) 
=> {
       visible={visiable}
       destroyOnClose
       footer={
-        <div
-          style={{
-            textAlign: 'right',
-          }}
-        >
-          <Button style={{ marginRight: 8 }} onClick={() => 
setVisiable(false)}>
-            取消
-          </Button>
-          <Button type="primary">提交</Button>
+        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
+          <div>
+            {Boolean(active) && (
+              <Button type="primary" danger>
+                禁用
+              </Button>
+            )}
+            {Boolean(!active) && <Button type="primary">启用</Button>}
+          </div>
+          {Boolean(active) && (
+            <div>
+              <Button onClick={() => setVisiable(false)}>取消</Button>
+              <Button type="primary" style={{ marginRight: 8, marginLeft: 8 }}>
+                提交
+              </Button>
+            </div>
+          )}
         </div>
       }
       onClose={() => setVisiable(false)}
diff --git a/src/pages/Routes/components/Step1/index.tsx 
b/src/pages/Routes/components/Step1/index.tsx
index 3b42dec..5b06b8f 100644
--- a/src/pages/Routes/components/Step1/index.tsx
+++ b/src/pages/Routes/components/Step1/index.tsx
@@ -16,12 +16,12 @@ const formItemLayout = {
   },
 };
 
-const Step1: React.FC<RoutesModule.StepProps> = ({ data, onChange }) => {
+const Step1: React.FC<RouteModule.Data> = ({ data, onChange }) => {
   const { step1Data } = data;
   const { hosts, paths, advancedMatchingRules } = step1Data;
   const [form] = Form.useForm();
   const [modalVisible, setModalVisible] = useState(false);
-  const [editModalData, setEditModalData] = 
useState<RoutesModule.MatchingRule>({
+  const [editModalData, setEditModalData] = 
useState<RouteModule.MatchingRule>({
     paramsLocation: 'query',
     paramsName: '',
     paramsExpresstion: '==',
@@ -33,7 +33,7 @@ const Step1: React.FC<RoutesModule.StepProps> = ({ data, 
onChange }) => {
     setModalVisible(true);
   };
 
-  const handleEdit = (record: RoutesModule.MatchingRule) => {
+  const handleEdit = (record: RouteModule.MatchingRule) => {
     setEditModalData(record);
     requestAnimationFrame(() => {
       setModalVisible(true);
@@ -69,7 +69,7 @@ const Step1: React.FC<RoutesModule.StepProps> = ({ data, 
onChange }) => {
     {
       title: '操作',
       key: 'action',
-      render: (_: any, record: RoutesModule.MatchingRule) => (
+      render: (_: any, record: RouteModule.MatchingRule) => (
         <Space size="middle">
           <a onClick={() => handleEdit(record)}>编辑</a>
           <a onClick={() => handleRemove(record.key)}>移除</a>
@@ -218,7 +218,7 @@ const Step1: React.FC<RoutesModule.StepProps> = ({ data, 
onChange }) => {
     modalForm.validateFields().then((value) => {
       onChange({
         advancedMatchingRules: advancedMatchingRules.concat({
-          ...(value as RoutesModule.MatchingRule),
+          ...(value as RouteModule.MatchingRule),
           key: Math.random().toString(36).slice(2),
         }),
       });
diff --git a/src/pages/Routes/typing.d.ts b/src/pages/Routes/typing.d.ts
index 0f26e6b..f51d0a6 100644
--- a/src/pages/Routes/typing.d.ts
+++ b/src/pages/Routes/typing.d.ts
@@ -1,4 +1,4 @@
-declare namespace RoutesModule {
+declare namespace RouteModule {
   interface MatchingRule {
     paramsLocation: 'query' | 'params' | 'header' | 'cookie';
     paramsName: string;
@@ -7,18 +7,25 @@ declare namespace RoutesModule {
     key: string;
   }
 
-  interface Step1DataProps {
+  type Step1Data = {
     name: string;
     protocol: [];
     hosts: string[];
     paths: string[];
     httpMethods: [];
     advancedMatchingRules: MatchingRule[];
-  }
+  };
+
+  type Step3Data = {
+    plugins: {
+      [name: string]: any;
+    };
+  };
 
-  interface StepProps {
+  interface Data {
     data: {
-      step1Data: Step1DataProps;
+      step1Data: Step1Data;
+      step3Data: Step3Data;
     };
     onChange(data: T): void;
   }

Reply via email to