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;
}